diff options
| author | Yubao Liu <yubao.liu@gmail.com> | 2021-01-11 12:32:08 +0800 |
|---|---|---|
| committer | Yubao Liu <yubao.liu@gmail.com> | 2021-01-11 12:32:08 +0800 |
| commit | efc75ea3f3a7338fb5c87e70ce8c501fb0b3549a (patch) | |
| tree | f1b930d3910b1d1c84fa309b652b2cddda76d333 | |
| parent | b6592f94d76098d19f242c0d09f660f6a6461b76 (diff) | |
fix cursor type after hide cursor and show again
This patch also adds support for cursor blink.
VIM emits these ANSI escape sequences in insert mode:
\x1b[?25h show cursor
\x1b[?25l hide cursor
| -rw-r--r-- | README.md | 7 | ||||
| -rw-r--r-- | elisp.c | 9 | ||||
| -rw-r--r-- | elisp.h | 2 | ||||
| -rw-r--r-- | vterm-module.c | 50 | ||||
| -rw-r--r-- | vterm-module.h | 12 | ||||
| -rw-r--r-- | vterm.el | 11 |
6 files changed, 63 insertions, 28 deletions
@@ -475,6 +475,13 @@ In addition to that, you can disable some text properties (bold, underline, reverse video) setting the relative option to `t` (`vterm-disable-bold`, `vterm-disable-underline`, or `vterm-disable-inverse-video`). +## Blink cursor + +When `vterm-ignore-blink-cursor` is `t`, vterm will ignore request from application to turn on or off cursor blink. + +If `nil`, cursor in any window may begin to blink or not blink because `blink-cursor-mode` +is a global minor mode in Emacs, you can use `M-x blink-cursor-mode` to toggle. + ## Colors Set the `:foreground` and `:background` attributes of the following faces to a @@ -26,6 +26,7 @@ emacs_value Qrear_nonsticky; emacs_value Qvterm_prompt; // Emacs functions +emacs_value Fblink_cursor_mode; emacs_value Fsymbol_value; emacs_value Flength; emacs_value Flist; @@ -172,8 +173,12 @@ emacs_value selected_window(emacs_env *env) { return env->funcall(env, Fselected_window, 0, (emacs_value[]){}); } -void set_cursor_type(emacs_env *env, emacs_value QCursorType) { - env->funcall(env, Fset, 2, (emacs_value[]){Qcursor_type, QCursorType}); +void set_cursor_type(emacs_env *env, emacs_value cursor_type) { + env->funcall(env, Fset, 2, (emacs_value[]){Qcursor_type, cursor_type}); +} + +void set_cursor_blink(emacs_env *env, bool blink) { + env->funcall(env, Fblink_cursor_mode, 1, (emacs_value[]){env->make_integer(env, blink)}); } emacs_value vterm_get_color(emacs_env *env, int index) { @@ -29,6 +29,7 @@ extern emacs_value Qrear_nonsticky; extern emacs_value Qvterm_prompt; // Emacs functions +extern emacs_value Fblink_cursor_mode; extern emacs_value Fsymbol_value; extern emacs_value Flength; extern emacs_value Flist; @@ -77,6 +78,7 @@ void goto_char(emacs_env *env, int pos); void forward_line(emacs_env *env, int n); void goto_line(emacs_env *env, int n); void set_cursor_type(emacs_env *env, emacs_value cursor_type); +void set_cursor_blink(emacs_env *env, bool blink); void delete_lines(emacs_env *env, int linenum, int count, bool del_whole_line); void recenter(emacs_env *env, emacs_value pos); void set_window_point(emacs_env *env, emacs_value win, emacs_value point); diff --git a/vterm-module.c b/vterm-module.c index 0146ed3..8c9de4e 100644 --- a/vterm-module.c +++ b/vterm-module.c @@ -536,26 +536,32 @@ static int term_movecursor(VTermPos new, VTermPos old, int visible, } static void term_redraw_cursor(Term *term, emacs_env *env) { + if (term->cursor.cursor_blink_changed) { + term->cursor.cursor_blink_changed = false; + set_cursor_blink(env, term->cursor.cursor_blink); + } + if (term->cursor.cursor_type_changed) { term->cursor.cursor_type_changed = false; - switch (term->cursor.cursor_type) { - case VTERM_PROP_CURSOR_VISIBLE: - set_cursor_type(env, Qt); - break; - case VTERM_PROP_CURSOR_NOT_VISIBLE: + + if (! term->cursor.cursor_visible) { set_cursor_type(env, Qnil); - break; - case VTERM_PROP_CURSOR_BLOCK: + return; + } + + switch (term->cursor.cursor_type) { + case VTERM_PROP_CURSORSHAPE_BLOCK: set_cursor_type(env, Qbox); break; - case VTERM_PROP_CURSOR_UNDERLINE: + case VTERM_PROP_CURSORSHAPE_UNDERLINE: set_cursor_type(env, Qhbar); break; - case VTERM_PROP_CURSOR_BAR_LEFT: + case VTERM_PROP_CURSORSHAPE_BAR_LEFT: set_cursor_type(env, Qbar); break; default: - return; + set_cursor_type(env, Qt); + break; } } } @@ -669,18 +675,20 @@ static int term_settermprop(VTermProp prop, VTermValue *val, void *user_data) { switch (prop) { case VTERM_PROP_CURSORVISIBLE: invalidate_terminal(term, term->cursor.row, term->cursor.row + 1); - if (val->boolean) { - term->cursor.cursor_type = VTERM_PROP_CURSOR_VISIBLE; - } else { - term->cursor.cursor_type = VTERM_PROP_CURSOR_NOT_VISIBLE; - } + term->cursor.cursor_visible = val->boolean; term->cursor.cursor_type_changed = true; break; + case VTERM_PROP_CURSORBLINK: + if (term->ignore_blink_cursor) + break; + invalidate_terminal(term, term->cursor.row, term->cursor.row + 1); + term->cursor.cursor_blink = val->boolean; + term->cursor.cursor_blink_changed = true; + break; case VTERM_PROP_CURSORSHAPE: invalidate_terminal(term, term->cursor.row, term->cursor.row + 1); term->cursor.cursor_type = val->number; term->cursor.cursor_type_changed = true; - break; case VTERM_PROP_TITLE: #ifdef VTermStringFragmentNotExists @@ -1177,6 +1185,7 @@ emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs, emacs_value args[], int disable_bold_font = env->is_not_nil(env, args[3]); int disable_underline = env->is_not_nil(env, args[4]); int disable_inverse_video = env->is_not_nil(env, args[5]); + int ignore_blink_cursor = env->is_not_nil(env, args[6]); term->vt = vterm_new(rows, cols); vterm_set_utf8(term->vt, 1); @@ -1203,6 +1212,7 @@ emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs, emacs_value args[], term->disable_bold_font = disable_bold_font; term->disable_underline = disable_underline; term->disable_inverse_video = disable_inverse_video; + term->ignore_blink_cursor = ignore_blink_cursor; emacs_value newline = env->make_string(env, "\n", 1); for (int i = 0; i < term->height; i++) { insert(env, newline); @@ -1218,6 +1228,11 @@ emacs_value Fvterm_new(emacs_env *env, ptrdiff_t nargs, emacs_value args[], term->cursor.row = 0; term->cursor.col = 0; + term->cursor.cursor_type = -1; + term->cursor.cursor_visible = true; + term->cursor.cursor_type_changed = false; + term->cursor.cursor_blink = false; + term->cursor.cursor_blink_changed = false; term->directory = NULL; term->directory_changed = false; term->elisp_code = NULL; @@ -1391,6 +1406,7 @@ int emacs_module_init(struct emacs_runtime *ert) { Qcursor_type = env->make_global_ref(env, env->intern(env, "cursor-type")); // Functions + Fblink_cursor_mode = env->make_global_ref(env, env->intern(env, "blink-cursor-mode")); Fsymbol_value = env->make_global_ref(env, env->intern(env, "symbol-value")); Flength = env->make_global_ref(env, env->intern(env, "length")); Flist = env->make_global_ref(env, env->intern(env, "list")); @@ -1438,7 +1454,7 @@ int emacs_module_init(struct emacs_runtime *ert) { // Exported functions emacs_value fun; fun = - env->make_function(env, 4, 6, Fvterm_new, "Allocate a new vterm.", NULL); + env->make_function(env, 4, 7, Fvterm_new, "Allocate a new vterm.", NULL); bind_function(env, "vterm--new", fun); fun = env->make_function(env, 1, 5, Fvterm_update, diff --git a/vterm-module.h b/vterm-module.h index 6330827..78964a7 100644 --- a/vterm-module.h +++ b/vterm-module.h @@ -30,14 +30,6 @@ typedef struct ScrollbackLine { VTermScreenCell cells[]; } ScrollbackLine; -enum { - VTERM_PROP_CURSOR_BLOCK = VTERM_PROP_CURSORSHAPE_BLOCK, - VTERM_PROP_CURSOR_UNDERLINE = VTERM_PROP_CURSORSHAPE_UNDERLINE, - VTERM_PROP_CURSOR_BAR_LEFT = VTERM_PROP_CURSORSHAPE_BAR_LEFT, - VTERM_PROP_CURSOR_VISIBLE = 4, - VTERM_PROP_CURSOR_NOT_VISIBLE = 5, -}; - /* c , p , q , s , 0 , 1 , 2 , 3 , 4 , 5 , 6 , and 7 */ /* clipboard, primary, secondary, select, or cut buffers 0 through 7 */ #define SELECTION_TARGET_MAX 12 @@ -45,7 +37,10 @@ enum { typedef struct Cursor { int row, col; int cursor_type; + bool cursor_visible; + bool cursor_blink; bool cursor_type_changed; + bool cursor_blink_changed; } Cursor; typedef struct Term { @@ -94,6 +89,7 @@ typedef struct Term { bool disable_bold_font; bool disable_underline; bool disable_inverse_video; + bool ignore_blink_cursor; char *cmd_buffer; @@ -339,6 +339,14 @@ This means that vterm will render bold with the default face weight." :type 'boolean :group 'vterm) +(defcustom vterm-ignore-blink-cursor t + "When t, vterm will ignore request from application to turn on or off cursor blink. + +If nil, cursor in any window may begin to blink or not blink because `blink-cursor-mode` +is a global minor mode in Emacs, you can use `M-x blink-cursor-mode` to toggle." + :type 'boolean + :group 'vterm) + (defcustom vterm-copy-exclude-prompt t "When not-nil, the prompt is not included by `vterm-copy-mode-done'." :type 'boolean @@ -627,7 +635,8 @@ Exceptions are defined by `vterm-keymap-exceptions'." width vterm-max-scrollback vterm-disable-bold-font vterm-disable-underline - vterm-disable-inverse-video)) + vterm-disable-inverse-video + vterm-ignore-blink-cursor)) (setq buffer-read-only t) (setq-local scroll-conservatively 101) (setq-local scroll-margin 0) |
