To: vim_dev@googlegroups.com Subject: Patch 8.0.0873 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0873 Problem: In a terminal window cannot use CTRL-\ CTRL-N to start Visual mode. Solution: After CTRL-\ CTRL-N enter Terminal-Normal mode for one command. Files: src/main.c, src/terminal.c, src/proto/terminal.pro *** ../vim-8.0.0872/src/main.c 2017-07-30 16:51:35.622144012 +0200 --- src/main.c 2017-08-05 19:44:58.247829235 +0200 *************** *** 1356,1362 **** else { #ifdef FEAT_TERMINAL ! if (term_use_loop() && oa.op_type == OP_NOP && oa.regname == NUL) { /* If terminal_loop() returns OK we got a key that is handled * in Normal model. With FAIL the terminal was closed and the --- 1356,1364 ---- 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 *** ../vim-8.0.0872/src/terminal.c 2017-08-05 19:34:43.344410036 +0200 --- src/terminal.c 2017-08-05 20:12:44.503603800 +0200 *************** *** 115,121 **** int tl_tty_fd; char_u *tl_tty_name; ! int tl_terminal_mode; int tl_channel_closed; #ifdef WIN3264 --- 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 *************** *** 144,149 **** --- 144,152 ---- int tl_cursor_visible; }; + #define TMODE_ONCE 1 /* CTRL-\ CTRL-N used */ + #define TMODE_LOOP 2 /* CTRL-W N used */ + /* * List of all active terminals. */ *************** *** 459,465 **** static void update_cursor(term_T *term, int redraw) { ! if (term->tl_terminal_mode) return; setcursor(); if (redraw && term->tl_buffer == curbuf) --- 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) *************** *** 492,498 **** ch_log(channel, "writing %d bytes to terminal", (int)len); term_write_job_output(term, msg, len); ! if (!term->tl_terminal_mode) { /* 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_terminal_mode == 0) { /* TODO: only update once in a while. */ update_screen(0); *************** *** 805,813 **** } static void ! set_terminal_mode(term_T *term, int on) { ! term->tl_terminal_mode = on; 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 mode) { ! term->tl_terminal_mode = mode; vim_free(term->tl_status_text); term->tl_status_text = NULL; if (term->tl_buffer == curbuf) *************** *** 823,844 **** { move_terminal_to_buffer(term); term_free_vterm(term); ! set_terminal_mode(term, FALSE); } /* ! * Switch from sending keys to the job to Terminal-Normal mode. * Suspends updating the terminal window. */ static void ! term_enter_terminal_mode() { term_T *term = curbuf->b_term; /* Append the current terminal contents to the buffer. */ move_terminal_to_buffer(term); ! set_terminal_mode(term, TRUE); } /* --- 826,860 ---- { move_terminal_to_buffer(term); term_free_vterm(term); ! set_terminal_mode(term, 0); } /* ! * Switch from Terminal-Job mode to Terminal-Normal mode. * 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; ! } } /* *************** *** 850,860 **** { term_T *term = curbuf->b_term; ! return term != NULL && term->tl_terminal_mode; } /* ! * Switch from Terminal-Normal mode to sending keys to the job. * Restores updating the terminal window. */ void --- 866,876 ---- { term_T *term = curbuf->b_term; ! return term != NULL && term->tl_terminal_mode != 0; } /* ! * Switch from Terminal-Normal mode to Terminal-Job mode. * Restores updating the terminal window. */ void *************** *** 877,883 **** } check_cursor(); ! set_terminal_mode(term, FALSE); if (term->tl_channel_closed) cleanup_vterm(term); --- 893,899 ---- } check_cursor(); ! set_terminal_mode(term, 0); if (term->tl_channel_closed) cleanup_vterm(term); *************** *** 1037,1048 **** * keys to the job. */ int ! term_use_loop() { term_T *term = curbuf->b_term; return term != NULL ! && !term->tl_terminal_mode && term->tl_vterm != NULL && term_job_running(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); } *************** *** 1060,1065 **** --- 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,1079 **** update_cursor(curbuf->b_term, FALSE); c = term_vgetc(); ! if (!term_use_loop()) /* job finished while waiting for a character */ break; --- 1097,1103 ---- update_cursor(curbuf->b_term, FALSE); c = term_vgetc(); ! if (!term_use_loop(FALSE)) /* job finished while waiting for a character */ break; *************** *** 1100,1114 **** #ifdef FEAT_CMDL_INFO clear_showcmd(); #endif ! if (!term_use_loop()) /* job finished while waiting for a character */ break; if (prev_c == Ctrl_BSL) { if (c == Ctrl_N) /* CTRL-\ CTRL-N : execute one Normal mode command. */ return OK; /* Send both keys to the terminal. */ send_keys_to_term(curbuf->b_term, prev_c, TRUE); } --- 1124,1141 ---- #ifdef FEAT_CMDL_INFO clear_showcmd(); #endif ! if (!term_use_loop(FALSE)) /* job finished while waiting for a character */ break; if (prev_c == Ctrl_BSL) { 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); } *************** *** 1119,1125 **** } else if (c == 'N') { ! term_enter_terminal_mode(); return FAIL; } else if (c == '"') --- 1146,1152 ---- } else if (c == 'N') { ! term_enter_terminal_mode(TMODE_LOOP); return FAIL; } else if (c == '"') *************** *** 1222,1228 **** if (wp->w_buffer == term->tl_buffer) position_cursor(wp, &pos); } ! if (term->tl_buffer == curbuf && !term->tl_terminal_mode) { may_toggle_cursor(term); update_cursor(term, term->tl_cursor_visible); --- 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); *************** *** 1358,1364 **** term->tl_status_text = NULL; /* Unless in Terminal-Normal mode: clear the vterm. */ ! if (!term->tl_terminal_mode) cleanup_vterm(term); redraw_buf_and_status_later(term->tl_buffer, NOT_VALID); --- 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); *************** *** 1558,1564 **** VTermState *state; VTermPos pos; ! if (term == NULL || term->tl_vterm == NULL || term->tl_terminal_mode) return FAIL; vterm = term->tl_vterm; --- 1585,1591 ---- VTermState *state; VTermPos pos; ! if (term == NULL || term->tl_vterm == NULL || term->tl_terminal_mode != 0) return FAIL; vterm = term->tl_vterm; *************** *** 1687,1693 **** { term_T *term = buf->b_term; ! return term != NULL && (term->tl_vterm == NULL || term->tl_terminal_mode); } /* --- 1714,1721 ---- { term_T *term = buf->b_term; ! return term != NULL ! && (term->tl_vterm == NULL || term->tl_terminal_mode != 0); } /* *************** *** 1770,1776 **** char_u *txt; size_t len; ! if (term->tl_terminal_mode) { if (term_job_running(term)) txt = (char_u *)_("Terminal"); --- 1798,1804 ---- char_u *txt; size_t len; ! if (term->tl_terminal_mode != 0) { if (term_job_running(term)) txt = (char_u *)_("Terminal"); *************** *** 1997,2003 **** STRCPY(val, "running"); else STRCPY(val, "finished"); ! if (term->tl_terminal_mode) STRCAT(val, ",terminal"); rettv->vval.v_string = vim_strsave(val); } --- 2025,2031 ---- STRCPY(val, "running"); else STRCPY(val, "finished"); ! if (term->tl_terminal_mode != 0) STRCAT(val, ",terminal"); rettv->vval.v_string = vim_strsave(val); } *************** *** 2159,2165 **** msg += MB_PTR2LEN(msg); } ! if (!term->tl_terminal_mode) { /* TODO: only update once in a while. */ update_screen(0); --- 2187,2193 ---- msg += MB_PTR2LEN(msg); } ! if (term->tl_terminal_mode == 0) { /* TODO: only update once in a while. */ update_screen(0); *** ../vim-8.0.0872/src/proto/terminal.pro 2017-08-05 19:34:43.344410036 +0200 --- src/proto/terminal.pro 2017-08-05 19:54:28.111573322 +0200 *************** *** 6,12 **** 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(void); int terminal_loop(void); void term_job_ended(job_T *job); void term_channel_closed(channel_T *ch); --- 6,12 ---- 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); *** ../vim-8.0.0872/src/version.c 2017-08-05 19:34:43.344410036 +0200 --- src/version.c 2017-08-05 20:14:21.114899816 +0200 *************** *** 771,772 **** --- 771,774 ---- { /* Add new patch number below this line */ + /**/ + 873, /**/ -- Two cows are standing together in a field. One asks the other: "So what do you think about this Mad Cow Disease?" The other replies: "That doesn't concern me. I'm a helicopter." /// 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 ///