1
0
forked from aniani/vim

patch 8.0.0918: cannot get terminal window cursor shape or attributes

Problem:    Cannot get terminal window cursor shape or attributes.
Solution:   Support cursor shape, attributes and color.
This commit is contained in:
Bram Moolenaar
2017-08-12 19:51:41 +02:00
parent 589b1109c5
commit 3cd43ccccb
13 changed files with 196 additions and 31 deletions

View File

@@ -36,9 +36,7 @@
* that buffer, attributes come from the scrollback buffer tl_scrollback.
*
* TODO:
* - support different cursor shapes, colors and attributes
* - make term_getcursor() return type (none/block/bar/underline) and
* attributes (color, blink, etc.)
* - cursor shape/color/blink in the GUI
* - Make argument list work on MS-Windows. #1954
* - MS-Windows: no redraw for 'updatetime' #1915
* - To set BS correctly, check get_stty(); Pass the fd of the pty.
@@ -143,6 +141,9 @@ struct terminal_S {
VTermPos tl_cursor_pos;
int tl_cursor_visible;
int tl_cursor_blink;
int tl_cursor_shape; /* 1: block, 2: underline, 3: bar */
char_u *tl_cursor_color; /* NULL or allocated */
int tl_using_altscreen;
};
@@ -155,6 +156,8 @@ struct terminal_S {
*/
static term_T *first_term = NULL;
/* Terminal active in terminal_loop(). */
static term_T *in_terminal_loop = NULL;
#define MAX_ROW 999999 /* used for tl_dirty_row_end to update all rows */
#define KEY_BUF_LEN 200
@@ -256,6 +259,7 @@ term_start(char_u *cmd, jobopt_T *opt, int forceit)
return;
term->tl_dirty_row_end = MAX_ROW;
term->tl_cursor_visible = TRUE;
term->tl_cursor_shape = VTERM_PROP_CURSORSHAPE_BLOCK;
term->tl_finish = opt->jo_term_finish;
ga_init2(&term->tl_scrollback, sizeof(sb_line_T), 300);
@@ -517,6 +521,7 @@ free_terminal(buf_T *buf)
vim_free(term->tl_title);
vim_free(term->tl_status_text);
vim_free(term->tl_opencmd);
vim_free(term->tl_cursor_color);
vim_free(term);
buf->b_term = NULL;
}
@@ -1158,6 +1163,35 @@ term_paste_register(int prev_c UNUSED)
}
}
static int did_change_cursor = FALSE;
static void
may_set_cursor_props(term_T *term)
{
if (in_terminal_loop == term)
{
if (term->tl_cursor_color != NULL)
term_cursor_color(term->tl_cursor_color);
else
term_cursor_color((char_u *)"");
/* do both blink and shape+blink, in case setting shape does not work */
term_cursor_blink(term->tl_cursor_blink);
term_cursor_shape(term->tl_cursor_shape, term->tl_cursor_blink);
}
}
static void
may_restore_cursor_props(void)
{
if (did_change_cursor)
{
did_change_cursor = FALSE;
ui_cursor_shape_forced(TRUE);
term_cursor_color((char_u *)"");
term_cursor_blink(FALSE);
}
}
/*
* Returns TRUE if the current window contains a terminal and we are sending
* keys to the job.
@@ -1185,10 +1219,14 @@ terminal_loop(void)
{
int c;
int termkey = 0;
int ret;
in_terminal_loop = curbuf->b_term;
if (*curwin->w_p_tk != NUL)
termkey = string_to_key(curwin->w_p_tk, TRUE);
position_cursor(curwin, &curbuf->b_term->tl_cursor_pos);
may_set_cursor_props(curbuf->b_term);
for (;;)
{
@@ -1235,7 +1273,8 @@ terminal_loop(void)
{
/* CTRL-\ CTRL-N : go to Terminal-Normal mode. */
term_enter_normal_mode();
return FAIL;
ret = FAIL;
goto theend;
}
/* Send both keys to the terminal. */
send_keys_to_term(curbuf->b_term, prev_c, TRUE);
@@ -1249,7 +1288,8 @@ terminal_loop(void)
{
/* CTRL-W N : go to Terminal-Normal mode. */
term_enter_normal_mode();
return FAIL;
ret = FAIL;
goto theend;
}
else if (c == '"')
{
@@ -1260,13 +1300,22 @@ terminal_loop(void)
{
stuffcharReadbuff(Ctrl_W);
stuffcharReadbuff(c);
return OK;
ret = OK;
goto theend;
}
}
if (send_keys_to_term(curbuf->b_term, c, TRUE) != OK)
return OK;
{
ret = OK;
goto theend;
}
}
return FAIL;
ret = FAIL;
theend:
in_terminal_loop = NULL;
may_restore_cursor_props();
return ret;
}
/*
@@ -1303,7 +1352,7 @@ term_job_ended(job_T *job)
static void
may_toggle_cursor(term_T *term)
{
if (curbuf == term->tl_buffer)
if (in_terminal_loop == term)
{
if (term->tl_cursor_visible)
cursor_on();
@@ -1385,6 +1434,22 @@ handle_settermprop(
out_flush();
break;
case VTERM_PROP_CURSORBLINK:
term->tl_cursor_blink = value->boolean;
may_set_cursor_props(term);
break;
case VTERM_PROP_CURSORSHAPE:
term->tl_cursor_shape = value->number;
may_set_cursor_props(term);
break;
case VTERM_PROP_CURSORCOLOR:
vim_free(term->tl_cursor_color);
term->tl_cursor_color = vim_strsave((char_u *)value->string);
may_set_cursor_props(term);
break;
case VTERM_PROP_ALTSCREEN:
/* TODO: do anything else? */
term->tl_using_altscreen = value->boolean;
@@ -2076,17 +2141,30 @@ f_term_getattr(typval_T *argvars, typval_T *rettv)
f_term_getcursor(typval_T *argvars, typval_T *rettv)
{
buf_T *buf = term_get_buf(argvars);
term_T *term;
list_T *l;
dict_T *d;
if (rettv_list_alloc(rettv) == FAIL)
return;
if (buf == NULL)
return;
term = buf->b_term;
l = rettv->vval.v_list;
list_append_number(l, buf->b_term->tl_cursor_pos.row + 1);
list_append_number(l, buf->b_term->tl_cursor_pos.col + 1);
list_append_number(l, buf->b_term->tl_cursor_visible);
list_append_number(l, term->tl_cursor_pos.row + 1);
list_append_number(l, term->tl_cursor_pos.col + 1);
d = dict_alloc();
if (d != NULL)
{
dict_add_nr_str(d, "visible", term->tl_cursor_visible, NULL);
dict_add_nr_str(d, "blink", term->tl_cursor_blink, NULL);
dict_add_nr_str(d, "shape", term->tl_cursor_shape, NULL);
dict_add_nr_str(d, "color", 0L, term->tl_cursor_color == NULL
? (char_u *)"" : term->tl_cursor_color);
list_append_dict(l, d);
}
}
/*