diff options
| -rw-r--r-- | elisp.c | 3 | ||||
| -rw-r--r-- | elisp.h | 2 | ||||
| -rw-r--r-- | vterm-module.c | 31 | ||||
| -rw-r--r-- | vterm-module.h | 2 | ||||
| -rw-r--r-- | vterm.el | 29 |
5 files changed, 63 insertions, 4 deletions
@@ -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}); +} @@ -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..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,6 +321,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 +358,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 +378,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 +561,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 +596,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 +710,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 @@ -65,6 +65,22 @@ Note that this hook will not work if another package like :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." @@ -252,8 +268,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)) @@ -262,7 +280,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)) @@ -271,5 +289,10 @@ 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 the `vterm--set-title-hook' with TITLE as argument." + (run-hook-with-args 'vterm-set-title-hook title)) + + (provide 'vterm) ;;; vterm.el ends here |
