diff options
| author | Bram Moolenaar <Bram@vim.org> | 2017-08-12 19:51:41 +0200 |
|---|---|---|
| committer | Bram Moolenaar <Bram@vim.org> | 2017-08-12 19:51:41 +0200 |
| commit | 3cd43ccccb03b2e68df9c8a344a87e51c007c656 (patch) | |
| tree | 51e41f2ba0520be2c6f4b0753538259545feca05 /src/terminal.c | |
| parent | 589b1109c55409baf27f79920d8ffc95111eaa01 (diff) | |
| download | vim-git-3cd43ccccb03b2e68df9c8a344a87e51c007c656.tar.gz | |
patch 8.0.0918: cannot get terminal window cursor shape or attributesv8.0.0918
Problem: Cannot get terminal window cursor shape or attributes.
Solution: Support cursor shape, attributes and color.
Diffstat (limited to 'src/terminal.c')
| -rw-r--r-- | src/terminal.c | 102 |
1 files changed, 90 insertions, 12 deletions
diff --git a/src/terminal.c b/src/terminal.c index e8727ee6e..fe1d5da2f 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -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); + } } /* |
