aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYubao Liu <yubao.liu@gmail.com>2021-01-11 12:32:08 +0800
committerYubao Liu <yubao.liu@gmail.com>2021-01-11 12:32:08 +0800
commitefc75ea3f3a7338fb5c87e70ce8c501fb0b3549a (patch)
treef1b930d3910b1d1c84fa309b652b2cddda76d333
parentb6592f94d76098d19f242c0d09f660f6a6461b76 (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.md7
-rw-r--r--elisp.c9
-rw-r--r--elisp.h2
-rw-r--r--vterm-module.c50
-rw-r--r--vterm-module.h12
-rw-r--r--vterm.el11
6 files changed, 63 insertions, 28 deletions
diff --git a/README.md b/README.md
index f3bf4c1..a440563 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/elisp.c b/elisp.c
index 8b4dfed..9ae32a0 100644
--- a/elisp.c
+++ b/elisp.c
@@ -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) {
diff --git a/elisp.h b/elisp.h
index 2fd64f4..39be710 100644
--- a/elisp.h
+++ b/elisp.h
@@ -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;
diff --git a/vterm.el b/vterm.el
index 9371df7..3ea54bd 100644
--- a/vterm.el
+++ b/vterm.el
@@ -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)