From c59eb64dc45c0f69f52142f9c9b974511ea77aa6 Mon Sep 17 00:00:00 2001 From: jixiufeng Date: Fri, 16 Nov 2018 00:10:48 +0800 Subject: support set terminal title . --- elisp.c | 3 +++ elisp.h | 2 ++ vterm-module.c | 28 ++++++++++++++++++++++++++++ vterm-module.h | 2 ++ vterm.el | 22 ++++++++++++++++++++++ 5 files changed, 57 insertions(+) diff --git a/elisp.c b/elisp.c index 0cbfa5f..e132262 100644 --- a/elisp.c +++ b/elisp.c @@ -143,3 +143,6 @@ emacs_value get_hex_color_bg(emacs_env *env, emacs_value face) { return env->funcall(env, Fvterm_face_color_hex, 2, (emacs_value[]){face, Qbackground}); } +void set_title(emacs_env *env, emacs_value string) { + env->funcall(env, Fvterm_set_title, 1, (emacs_value[]){string}); +} diff --git a/elisp.h b/elisp.h index b505c40..c200754 100644 --- a/elisp.h +++ b/elisp.h @@ -39,6 +39,7 @@ emacs_value Fvterm_flush_output; emacs_value Fblink_cursor_mode; emacs_value Fget_buffer_window; emacs_value Fselected_window; +emacs_value Fvterm_set_title; // Utils void bind_function(emacs_env *env, const char *name, emacs_value Sfun); @@ -67,5 +68,6 @@ void recenter(emacs_env *env, emacs_value pos); void forward_char(emacs_env *env, emacs_value n); emacs_value get_buffer_window(emacs_env *env); emacs_value selected_window(emacs_env *env); +void set_title(emacs_env *env, emacs_value string) ; #endif /* ELISP_H */ diff --git a/vterm-module.c b/vterm-module.c index 24ac1e6..17cb14f 100644 --- a/vterm-module.c +++ b/vterm-module.c @@ -320,6 +320,10 @@ static void term_redraw(Term *term, emacs_env *env) { env->extract_integer(env, buffer_line_number(env)) - bufline_before; adjust_topline(term, env, line_added); } + if(term->is_title_changed){ + set_title(env,env->make_string(env, term->title,strlen(term->title))); + term->is_title_changed=false; + } term->is_invalidated = false; } @@ -353,6 +357,17 @@ static bool is_key(unsigned char *key, size_t len, char *key_description) { return (len == strlen(key_description) && memcmp(key, key_description, len) == 0); } +static void term_set_title(Term *term ,char* title) { + size_t len=strlen(title); + if (term->title){ + free(term->title); + } + term->title=malloc(sizeof(char) * (len+1)); + strncpy(term->title ,title,len); + term->title[len]=0; + term->is_title_changed=true; + return ; +} static int term_settermprop(VTermProp prop, VTermValue *val, void *user_data) { Term *term = (Term *)user_data; @@ -362,8 +377,12 @@ static int term_settermprop(VTermProp prop, VTermValue *val, void *user_data) { term->cursor.visible = val->boolean; break; + case VTERM_PROP_TITLE: + term_set_title(term,val->string); + break; case VTERM_PROP_CURSORBLINK: term->cursor.blinking = val->boolean; + break; default: return 0; } @@ -541,6 +560,11 @@ static void term_finalize(void *object) { for (int i = 0; i < term->sb_current; i++) { free(term->sb_buffer[i]); } + if (term->title){ + free(term->title); + term->title=NULL; + } + free(term->sb_buffer); vterm_free(term->vt); free(term); @@ -571,6 +595,8 @@ static emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs, term->invalid_end = rows; term->cursor.visible = true; term->cursor.blinking = false; + term->title = NULL; + term->is_title_changed=false; return env->make_user_ptr(env, term_finalize, term); } @@ -683,6 +709,8 @@ int emacs_module_init(struct emacs_runtime *ert) { Fselected_window = env->make_global_ref(env, env->intern(env, "selected-window")); + Fvterm_set_title = + env->make_global_ref(env, env->intern(env, "vterm--set-title")); // Faces Qterm = env->make_global_ref(env, env->intern(env, "vterm")); Qterm_color_black = diff --git a/vterm-module.h b/vterm-module.h index 0934087..9f809b3 100644 --- a/vterm-module.h +++ b/vterm-module.h @@ -48,6 +48,8 @@ typedef struct Term { bool is_invalidated; Cursor cursor; + char *title; + bool is_title_changed; } Term; // Faces diff --git a/vterm.el b/vterm.el index 5d5c21d..903ce01 100644 --- a/vterm.el +++ b/vterm.el @@ -61,6 +61,22 @@ value with `add-hook'." :type 'hook :group 'vterm) +(defcustom vterm-set-title-hook nil + "Shell set title hook. + +those functions are called one by one, with 1 arguments. +`vterm-set-title-hook' should be a symbol, a hook variable. +The value of HOOK may be nil, a function, or a list of functions. +for example +(defun vterm--rename-buffer-as-title (title) + (rename-buffer (format \"vterm %s\" title))) +(add-hook 'vterm-set-title-hook 'vterm--rename-buffer-as-title) + +see http://tldp.org/HOWTO/Xterm-Title-4.html about how to set terminal title +for different shell. " + :type 'hook + :group 'vterm) + (defface vterm '((t :inherit default)) "Default face to use in Term mode." @@ -267,5 +283,11 @@ Feeds the size change to the virtual terminal." "Return the maximum line number." (line-number-at-pos (point-max))) +(defun vterm--set-title (title) + (run-hook-with-args 'vterm-set-title-hook title)) + + + + (provide 'vterm) ;;; vterm.el ends here -- cgit v1.0 From df21bcb0e68b781ec13e97f929c9e3bcbc703540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20F=C3=BCrmetz?= Date: Thu, 15 Nov 2018 22:34:41 +0100 Subject: Minor cleanup --- vterm-module.c | 33 +++++++++++++++++---------------- vterm.el | 11 ++++++----- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/vterm-module.c b/vterm-module.c index 17cb14f..7c93fa7 100644 --- a/vterm-module.c +++ b/vterm-module.c @@ -203,7 +203,8 @@ static void refresh_screen(Term *term, emacs_env *env) { // Term height may have decreased before `invalid_end` reflects it. int line_start = row_to_linenr(term, term->invalid_start); goto_line(env, line_start); - delete_lines(env, line_start, term->invalid_end - term->invalid_start, true); + delete_lines(env, line_start, term->invalid_end - term->invalid_start, + true); refresh_lines(term, env, term->invalid_start, term->invalid_end, width); } @@ -320,9 +321,9 @@ static void term_redraw(Term *term, emacs_env *env) { env->extract_integer(env, buffer_line_number(env)) - bufline_before; adjust_topline(term, env, line_added); } - if(term->is_title_changed){ - set_title(env,env->make_string(env, term->title,strlen(term->title))); - term->is_title_changed=false; + if (term->is_title_changed) { + set_title(env, env->make_string(env, term->title, strlen(term->title))); + term->is_title_changed = false; } term->is_invalidated = false; } @@ -357,16 +358,16 @@ static bool is_key(unsigned char *key, size_t len, char *key_description) { return (len == strlen(key_description) && memcmp(key, key_description, len) == 0); } -static void term_set_title(Term *term ,char* title) { - size_t len=strlen(title); - if (term->title){ +static void term_set_title(Term *term, char *title) { + size_t len = strlen(title); + if (term->title) { free(term->title); } - term->title=malloc(sizeof(char) * (len+1)); - strncpy(term->title ,title,len); - term->title[len]=0; - term->is_title_changed=true; - return ; + term->title = malloc(sizeof(char) * (len + 1)); + strncpy(term->title, title, len); + term->title[len] = 0; + term->is_title_changed = true; + return; } static int term_settermprop(VTermProp prop, VTermValue *val, void *user_data) { @@ -378,7 +379,7 @@ static int term_settermprop(VTermProp prop, VTermValue *val, void *user_data) { term->cursor.visible = val->boolean; break; case VTERM_PROP_TITLE: - term_set_title(term,val->string); + term_set_title(term, val->string); break; case VTERM_PROP_CURSORBLINK: term->cursor.blinking = val->boolean; @@ -560,9 +561,9 @@ static void term_finalize(void *object) { for (int i = 0; i < term->sb_current; i++) { free(term->sb_buffer[i]); } - if (term->title){ + if (term->title) { free(term->title); - term->title=NULL; + term->title = NULL; } free(term->sb_buffer); @@ -596,7 +597,7 @@ static emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs, term->cursor.visible = true; term->cursor.blinking = false; term->title = NULL; - term->is_title_changed=false; + term->is_title_changed = false; return env->make_user_ptr(env, term_finalize, term); } diff --git a/vterm.el b/vterm.el index 903ce01..791efb2 100644 --- a/vterm.el +++ b/vterm.el @@ -264,8 +264,10 @@ Feeds the size change to the virtual terminal." (defun vterm--delete-lines (line-num count &optional delete-whole-line) - "Delete lines from line-num. If option ‘kill-whole-line’ is non-nil, - then this command kills the whole line including its terminating newline" + "Delete COUNT lines from LINE-NUM. + + If option DELETE-WHOLE-LINE is non-nil, then this command kills + the whole line including its terminating newline" (save-excursion (when (vterm--goto-line line-num) (delete-region (point) (point-at-eol count)) @@ -274,7 +276,7 @@ Feeds the size change to the virtual terminal." (delete-char 1))))) (defun vterm--goto-line(n) - "If move succ return t" + "Go to line N and return true on success." (goto-char (point-min)) (let ((succ (eq 0 (forward-line (1- n))))) succ)) @@ -284,10 +286,9 @@ Feeds the size change to the virtual terminal." (line-number-at-pos (point-max))) (defun vterm--set-title (title) + "Run the `vterm--set-title-hook' with TITLE as argument." (run-hook-with-args 'vterm-set-title-hook title)) - - (provide 'vterm) ;;; vterm.el ends here -- cgit v1.0