To: vim_dev@googlegroups.com Subject: Patch 8.0.0877 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0877 Problem: Using CTRL-\ CTRL-N in terminal is inconsistent. Solution: Stay in Normal mode. Files: src/terminal.c, src/proto/terminal.pro, src/main.c, src/normal.c, src/option.c *** ../vim-8.0.0876/src/terminal.c 2017-08-05 20:16:55.861771375 +0200 --- src/terminal.c 2017-08-06 14:32:48.526442502 +0200 *************** *** 36,43 **** * that buffer, attributes come from the scrollback buffer tl_scrollback. * * TODO: ! * - MS-Windows: no redraw for 'updatetime' #1915 ! * - add argument to term_wait() for waiting time. * - For the scrollback buffer store lines in the buffer, only attributes in * tl_scrollback. * - When the job ends: --- 36,42 ---- * that buffer, attributes come from the scrollback buffer tl_scrollback. * * TODO: ! * - Add argument to term_wait() for waiting time. * - For the scrollback buffer store lines in the buffer, only attributes in * tl_scrollback. * - When the job ends: *************** *** 47,52 **** --- 46,52 ---- * - add option values to the command: * :term <24x80> vim notes.txt * - support different cursor shapes, colors and attributes + * - MS-Windows: no redraw for 'updatetime' #1915 * - make term_getcursor() return type (none/block/bar/underline) and * attributes (color, blink, etc.) * - To set BS correctly, check get_stty(); Pass the fd of the pty. *************** *** 115,121 **** int tl_tty_fd; char_u *tl_tty_name; ! int tl_terminal_mode; /* 0, TMODE_ONCE or TMODE_LOOP */ int tl_channel_closed; #ifdef WIN3264 --- 115,121 ---- int tl_tty_fd; char_u *tl_tty_name; ! int tl_normal_mode; /* TRUE: Terminal-Normal mode */ int tl_channel_closed; #ifdef WIN3264 *************** *** 462,468 **** static void update_cursor(term_T *term, int redraw) { ! if (term->tl_terminal_mode != 0) return; setcursor(); if (redraw && term->tl_buffer == curbuf) --- 462,468 ---- static void update_cursor(term_T *term, int redraw) { ! if (term->tl_normal_mode) return; setcursor(); if (redraw && term->tl_buffer == curbuf) *************** *** 495,501 **** ch_log(channel, "writing %d bytes to terminal", (int)len); term_write_job_output(term, msg, len); ! if (term->tl_terminal_mode == 0) { /* TODO: only update once in a while. */ update_screen(0); --- 495,501 ---- ch_log(channel, "writing %d bytes to terminal", (int)len); term_write_job_output(term, msg, len); ! if (!term->tl_normal_mode) { /* TODO: only update once in a while. */ update_screen(0); *************** *** 808,816 **** } static void ! set_terminal_mode(term_T *term, int mode) { ! term->tl_terminal_mode = mode; vim_free(term->tl_status_text); term->tl_status_text = NULL; if (term->tl_buffer == curbuf) --- 808,816 ---- } static void ! set_terminal_mode(term_T *term, int normal_mode) { ! term->tl_normal_mode = normal_mode; vim_free(term->tl_status_text); term->tl_status_text = NULL; if (term->tl_buffer == curbuf) *************** *** 826,832 **** { move_terminal_to_buffer(term); term_free_vterm(term); ! set_terminal_mode(term, 0); } /* --- 826,832 ---- { move_terminal_to_buffer(term); term_free_vterm(term); ! set_terminal_mode(term, FALSE); } /* *************** *** 834,860 **** * Suspends updating the terminal window. */ static void ! term_enter_terminal_mode(int mode) { term_T *term = curbuf->b_term; /* Append the current terminal contents to the buffer. */ move_terminal_to_buffer(term); ! set_terminal_mode(term, mode); ! if (mode == TMODE_ONCE) ! { ! /* Move the window cursor to the position of the cursor in the ! * terminal. */ ! curwin->w_cursor.lnum = term->tl_scrollback_scrolled ! + term->tl_cursor_pos.row + 1; ! check_cursor(); ! coladvance(term->tl_cursor_pos.col); ! /* Display the same lines as in the terminal. */ ! curwin->w_topline = term->tl_scrollback_scrolled + 1; ! } } /* --- 834,857 ---- * Suspends updating the terminal window. */ static void ! term_enter_normal_mode(void) { term_T *term = curbuf->b_term; /* Append the current terminal contents to the buffer. */ move_terminal_to_buffer(term); ! set_terminal_mode(term, TRUE); ! /* Move the window cursor to the position of the cursor in the ! * terminal. */ ! curwin->w_cursor.lnum = term->tl_scrollback_scrolled ! + term->tl_cursor_pos.row + 1; ! check_cursor(); ! coladvance(term->tl_cursor_pos.col); ! /* Display the same lines as in the terminal. */ ! curwin->w_topline = term->tl_scrollback_scrolled + 1; } /* *************** *** 862,872 **** * Terminal-Normal mode. */ int ! term_in_terminal_mode() { term_T *term = curbuf->b_term; ! return term != NULL && term->tl_terminal_mode != 0; } /* --- 859,869 ---- * Terminal-Normal mode. */ int ! term_in_normal_mode(void) { term_T *term = curbuf->b_term; ! return term != NULL && term->tl_normal_mode; } /* *************** *** 874,880 **** * Restores updating the terminal window. */ void ! term_leave_terminal_mode() { term_T *term = curbuf->b_term; sb_line_T *line; --- 871,877 ---- * Restores updating the terminal window. */ void ! term_enter_job_mode() { term_T *term = curbuf->b_term; sb_line_T *line; *************** *** 893,899 **** } check_cursor(); ! set_terminal_mode(term, 0); if (term->tl_channel_closed) cleanup_vterm(term); --- 890,896 ---- } check_cursor(); ! set_terminal_mode(term, FALSE); if (term->tl_channel_closed) cleanup_vterm(term); *************** *** 1053,1065 **** * keys to the job. */ int ! term_use_loop(int once) { term_T *term = curbuf->b_term; return term != NULL ! && (once ? term->tl_terminal_mode != TMODE_LOOP ! : term->tl_terminal_mode == 0) && term->tl_vterm != NULL && term_job_running(term); } --- 1050,1061 ---- * keys to the job. */ int ! term_use_loop(void) { term_T *term = curbuf->b_term; return term != NULL ! && !term->tl_normal_mode && term->tl_vterm != NULL && term_job_running(term); } *************** *** 1077,1089 **** int c; int termkey = 0; - if (curbuf->b_term->tl_terminal_mode != 0) - { - /* Got back from TMODE_ONCE, enter Terminal-Job mode. */ - term_leave_terminal_mode(); - update_cursor(curbuf->b_term, TRUE); - } - if (*curwin->w_p_tk != NUL) termkey = string_to_key(curwin->w_p_tk, TRUE); position_cursor(curwin, &curbuf->b_term->tl_cursor_pos); --- 1073,1078 ---- *************** *** 1097,1103 **** update_cursor(curbuf->b_term, FALSE); c = term_vgetc(); ! if (!term_use_loop(FALSE)) /* job finished while waiting for a character */ break; --- 1086,1092 ---- update_cursor(curbuf->b_term, FALSE); c = term_vgetc(); ! if (!term_use_loop()) /* job finished while waiting for a character */ break; *************** *** 1124,1130 **** #ifdef FEAT_CMDL_INFO clear_showcmd(); #endif ! if (!term_use_loop(FALSE)) /* job finished while waiting for a character */ break; --- 1113,1119 ---- #ifdef FEAT_CMDL_INFO clear_showcmd(); #endif ! if (!term_use_loop()) /* job finished while waiting for a character */ break; *************** *** 1132,1140 **** { if (c == Ctrl_N) { ! /* CTRL-\ CTRL-N : execute one Normal mode command. */ ! term_enter_terminal_mode(TMODE_ONCE); ! return OK; } /* Send both keys to the terminal. */ send_keys_to_term(curbuf->b_term, prev_c, TRUE); --- 1121,1129 ---- { if (c == Ctrl_N) { ! /* CTRL-\ CTRL-N : go to Terminal-Normal mode. */ ! term_enter_normal_mode(); ! return FAIL; } /* Send both keys to the terminal. */ send_keys_to_term(curbuf->b_term, prev_c, TRUE); *************** *** 1146,1152 **** } else if (c == 'N') { ! term_enter_terminal_mode(TMODE_LOOP); return FAIL; } else if (c == '"') --- 1135,1142 ---- } else if (c == 'N') { ! /* CTRL-W N : go to Terminal-Normal mode. */ ! term_enter_normal_mode(); return FAIL; } else if (c == '"') *************** *** 1249,1255 **** if (wp->w_buffer == term->tl_buffer) position_cursor(wp, &pos); } ! if (term->tl_buffer == curbuf && term->tl_terminal_mode == 0) { may_toggle_cursor(term); update_cursor(term, term->tl_cursor_visible); --- 1239,1245 ---- if (wp->w_buffer == term->tl_buffer) position_cursor(wp, &pos); } ! if (term->tl_buffer == curbuf && !term->tl_normal_mode) { may_toggle_cursor(term); update_cursor(term, term->tl_cursor_visible); *************** *** 1385,1391 **** term->tl_status_text = NULL; /* Unless in Terminal-Normal mode: clear the vterm. */ ! if (term->tl_terminal_mode == 0) cleanup_vterm(term); redraw_buf_and_status_later(term->tl_buffer, NOT_VALID); --- 1375,1381 ---- term->tl_status_text = NULL; /* Unless in Terminal-Normal mode: clear the vterm. */ ! if (!term->tl_normal_mode) cleanup_vterm(term); redraw_buf_and_status_later(term->tl_buffer, NOT_VALID); *************** *** 1573,1580 **** } /* ! * Called to update the window that contains a terminal. ! * Returns FAIL when there is no terminal running in this window. */ int term_update_window(win_T *wp) --- 1563,1571 ---- } /* ! * Called to update a window that contains an active terminal. ! * Returns FAIL when there is no terminal running in this window or in ! * Terminal-Normal mode. */ int term_update_window(win_T *wp) *************** *** 1585,1591 **** VTermState *state; VTermPos pos; ! if (term == NULL || term->tl_vterm == NULL || term->tl_terminal_mode != 0) return FAIL; vterm = term->tl_vterm; --- 1576,1582 ---- VTermState *state; VTermPos pos; ! if (term == NULL || term->tl_vterm == NULL || term->tl_normal_mode) return FAIL; vterm = term->tl_vterm; *************** *** 1707,1721 **** /* * Return TRUE if "wp" is a terminal window where the job has finished or we ! * are in Terminal-Normal mode. */ int term_show_buffer(buf_T *buf) { term_T *term = buf->b_term; ! return term != NULL ! && (term->tl_vterm == NULL || term->tl_terminal_mode != 0); } /* --- 1698,1711 ---- /* * Return TRUE if "wp" is a terminal window where the job has finished or we ! * are in Terminal-Normal mode, thus we show the buffer contents. */ int term_show_buffer(buf_T *buf) { term_T *term = buf->b_term; ! return term != NULL && (term->tl_vterm == NULL || term->tl_normal_mode); } /* *************** *** 1798,1804 **** char_u *txt; size_t len; ! if (term->tl_terminal_mode != 0) { if (term_job_running(term)) txt = (char_u *)_("Terminal"); --- 1788,1794 ---- char_u *txt; size_t len; ! if (term->tl_normal_mode) { if (term_job_running(term)) txt = (char_u *)_("Terminal"); *************** *** 2025,2032 **** STRCPY(val, "running"); else STRCPY(val, "finished"); ! if (term->tl_terminal_mode != 0) ! STRCAT(val, ",terminal"); rettv->vval.v_string = vim_strsave(val); } --- 2015,2022 ---- STRCPY(val, "running"); else STRCPY(val, "finished"); ! if (term->tl_normal_mode) ! STRCAT(val, ",normal"); rettv->vval.v_string = vim_strsave(val); } *************** *** 2187,2193 **** msg += MB_PTR2LEN(msg); } ! if (term->tl_terminal_mode == 0) { /* TODO: only update once in a while. */ update_screen(0); --- 2177,2183 ---- msg += MB_PTR2LEN(msg); } ! if (!term->tl_normal_mode) { /* TODO: only update once in a while. */ update_screen(0); *** ../vim-8.0.0876/src/proto/terminal.pro 2017-08-05 20:16:55.861771375 +0200 --- src/proto/terminal.pro 2017-08-06 14:27:20.664790907 +0200 *************** *** 3,12 **** void free_terminal(buf_T *buf); void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel); int term_job_running(term_T *term); ! int term_in_terminal_mode(void); ! void term_leave_terminal_mode(void); int send_keys_to_term(term_T *term, int c, int typed); ! int term_use_loop(int once); int terminal_loop(void); void term_job_ended(job_T *job); void term_channel_closed(channel_T *ch); --- 3,12 ---- void free_terminal(buf_T *buf); void write_to_term(buf_T *buffer, char_u *msg, channel_T *channel); int term_job_running(term_T *term); ! int term_in_normal_mode(void); ! void term_enter_job_mode(void); int send_keys_to_term(term_T *term, int c, int typed); ! int term_use_loop(void); int terminal_loop(void); void term_job_ended(job_T *job); void term_channel_closed(channel_T *ch); *** ../vim-8.0.0876/src/main.c 2017-08-05 20:16:55.857771404 +0200 --- src/main.c 2017-08-06 14:29:15.047971639 +0200 *************** *** 1356,1368 **** else { #ifdef FEAT_TERMINAL ! if (term_use_loop(TRUE) && oa.op_type == OP_NOP && oa.regname == NUL && !VIsual_active) { /* If terminal_loop() returns OK we got a key that is handled ! * in Normal model. With FAIL the terminal was closed and the ! * screen needs to be redrawn. */ if (terminal_loop() == OK) normal_cmd(&oa, TRUE); } --- 1356,1368 ---- else { #ifdef FEAT_TERMINAL ! if (term_use_loop() && oa.op_type == OP_NOP && oa.regname == NUL && !VIsual_active) { /* If terminal_loop() returns OK we got a key that is handled ! * in Normal model. With FAIL we first need to position the ! * cursor and the screen needs to be redrawn. */ if (terminal_loop() == OK) normal_cmd(&oa, TRUE); } *** ../vim-8.0.0876/src/normal.c 2017-08-05 21:13:32.716908729 +0200 --- src/normal.c 2017-08-06 14:29:19.667938542 +0200 *************** *** 4639,4645 **** if (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN) { # ifdef FEAT_TERMINAL ! if (term_use_loop(FALSE)) send_keys_to_term(curbuf->b_term, cap->cmdchar, TRUE); else # endif --- 4639,4645 ---- if (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN) { # ifdef FEAT_TERMINAL ! if (term_use_loop()) send_keys_to_term(curbuf->b_term, cap->cmdchar, TRUE); else # endif *************** *** 9061,9070 **** #endif } #ifdef FEAT_TERMINAL ! else if (term_in_terminal_mode()) { clearop(cap->oap); ! term_leave_terminal_mode(); return; } #endif --- 9061,9070 ---- #endif } #ifdef FEAT_TERMINAL ! else if (term_in_normal_mode()) { clearop(cap->oap); ! term_enter_job_mode(); return; } #endif *** ../vim-8.0.0876/src/option.c 2017-08-01 20:25:17.877279253 +0200 --- src/option.c 2017-08-06 14:24:11.022148462 +0200 *************** *** 8228,8234 **** { # ifdef FEAT_TERMINAL /* Cannot set 'modifiable' when in Terminal mode. */ ! if (term_in_terminal_mode() || (bt_terminal(curbuf) && !term_is_finished(curbuf))) { curbuf->b_p_ma = FALSE; --- 8228,8234 ---- { # ifdef FEAT_TERMINAL /* Cannot set 'modifiable' when in Terminal mode. */ ! if (term_in_normal_mode() || (bt_terminal(curbuf) && !term_is_finished(curbuf))) { curbuf->b_p_ma = FALSE; *** ../vim-8.0.0876/src/version.c 2017-08-05 23:09:26.754452764 +0200 --- src/version.c 2017-08-06 14:56:51.908143213 +0200 *************** *** 771,772 **** --- 771,774 ---- { /* Add new patch number below this line */ + /**/ + 877, /**/ -- TIM: But follow only if you are men of valour. For the entrance to this cave is guarded by a monster, a creature so foul and cruel that no man yet has fought with it and lived. Bones of full fifty men lie strewn about its lair ... "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///