]> granicus.if.org Git - vim/commitdiff
patch 8.0.0873: in terminal cannot use CTRL-\ CTRL-N to start Visual mode v8.0.0873
authorBram Moolenaar <Bram@vim.org>
Sat, 5 Aug 2017 18:17:00 +0000 (20:17 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 5 Aug 2017 18:17:00 +0000 (20:17 +0200)
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.

src/main.c
src/proto/terminal.pro
src/terminal.c
src/version.c

index 81eb1a6799391309fe08e0432bd3c3661f8d1618..615858bcc074b47e582519ce5e5010cf1b8b6b16 100644 (file)
@@ -1356,7 +1356,9 @@ main_loop(
        else
        {
 #ifdef FEAT_TERMINAL
-           if (term_use_loop() && oa.op_type == OP_NOP && oa.regname == NUL)
+           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
index b6c27ed0b64e3470174f92fd5b73fb8dc3b68dd1..fbd17eddeea7d109c11ef6d5bbf1ad44b4a4b71a 100644 (file)
@@ -6,7 +6,7 @@ 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(void);
+int term_use_loop(int once);
 int terminal_loop(void);
 void term_job_ended(job_T *job);
 void term_channel_closed(channel_T *ch);
index 20c927248a3c60655535272ef371343f05eac5e5..7d26deb142b2eba61aa4dba1f2fefe4dca48a24f 100644 (file)
@@ -115,7 +115,7 @@ struct terminal_S {
     int                tl_tty_fd;
     char_u     *tl_tty_name;
 
-    int                tl_terminal_mode;
+    int                tl_terminal_mode; /* 0, TMODE_ONCE or TMODE_LOOP */
     int                tl_channel_closed;
 
 #ifdef WIN3264
@@ -144,6 +144,9 @@ struct terminal_S {
     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,7 +462,7 @@ term_write_job_output(term_T *term, char_u *msg, size_t len)
     static void
 update_cursor(term_T *term, int redraw)
 {
-    if (term->tl_terminal_mode)
+    if (term->tl_terminal_mode != 0)
        return;
     setcursor();
     if (redraw && term->tl_buffer == curbuf)
@@ -492,7 +495,7 @@ write_to_term(buf_T *buffer, char_u *msg, channel_T *channel)
     ch_log(channel, "writing %d bytes to terminal", (int)len);
     term_write_job_output(term, msg, len);
 
-    if (!term->tl_terminal_mode)
+    if (term->tl_terminal_mode == 0)
     {
        /* TODO: only update once in a while. */
        update_screen(0);
@@ -805,9 +808,9 @@ move_terminal_to_buffer(term_T *term)
 }
 
     static void
-set_terminal_mode(term_T *term, int on)
+set_terminal_mode(term_T *term, int mode)
 {
-    term->tl_terminal_mode = on;
+    term->tl_terminal_mode = mode;
     vim_free(term->tl_status_text);
     term->tl_status_text = NULL;
     if (term->tl_buffer == curbuf)
@@ -823,22 +826,35 @@ cleanup_vterm(term_T *term)
 {
     move_terminal_to_buffer(term);
     term_free_vterm(term);
-    set_terminal_mode(term, FALSE);
+    set_terminal_mode(term, 0);
 }
 
 /*
- * Switch from sending keys to the job to Terminal-Normal mode.
+ * Switch from Terminal-Job mode to Terminal-Normal mode.
  * Suspends updating the terminal window.
  */
     static void
-term_enter_terminal_mode()
+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, TRUE);
+    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,11 +866,11 @@ term_in_terminal_mode()
 {
     term_T *term = curbuf->b_term;
 
-    return term != NULL && term->tl_terminal_mode;
+    return term != NULL && term->tl_terminal_mode != 0;
 }
 
 /*
- * Switch from Terminal-Normal mode to sending keys to the job.
+ * Switch from Terminal-Normal mode to Terminal-Job mode.
  * Restores updating the terminal window.
  */
     void
@@ -877,7 +893,7 @@ term_leave_terminal_mode()
     }
     check_cursor();
 
-    set_terminal_mode(term, FALSE);
+    set_terminal_mode(term, 0);
 
     if (term->tl_channel_closed)
        cleanup_vterm(term);
@@ -1037,12 +1053,13 @@ term_paste_register(int prev_c UNUSED)
  * keys to the job.
  */
     int
-term_use_loop()
+term_use_loop(int once)
 {
     term_T *term = curbuf->b_term;
 
     return term != NULL
-       && !term->tl_terminal_mode
+       && (once ? term->tl_terminal_mode != TMODE_LOOP
+                : term->tl_terminal_mode == 0)
        && term->tl_vterm != NULL
        && term_job_running(term);
 }
@@ -1060,6 +1077,13 @@ terminal_loop(void)
     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,7 +1097,7 @@ terminal_loop(void)
        update_cursor(curbuf->b_term, FALSE);
 
        c = term_vgetc();
-       if (!term_use_loop())
+       if (!term_use_loop(FALSE))
            /* job finished while waiting for a character */
            break;
 
@@ -1100,15 +1124,18 @@ terminal_loop(void)
 #ifdef FEAT_CMDL_INFO
            clear_showcmd();
 #endif
-           if (!term_use_loop())
+           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,7 +1146,7 @@ terminal_loop(void)
            }
            else if (c == 'N')
            {
-               term_enter_terminal_mode();
+               term_enter_terminal_mode(TMODE_LOOP);
                return FAIL;
            }
            else if (c == '"')
@@ -1222,7 +1249,7 @@ handle_movecursor(
        if (wp->w_buffer == term->tl_buffer)
            position_cursor(wp, &pos);
     }
-    if (term->tl_buffer == curbuf && !term->tl_terminal_mode)
+    if (term->tl_buffer == curbuf && term->tl_terminal_mode == 0)
     {
        may_toggle_cursor(term);
        update_cursor(term, term->tl_cursor_visible);
@@ -1358,7 +1385,7 @@ term_channel_closed(channel_T *ch)
            term->tl_status_text = NULL;
 
            /* Unless in Terminal-Normal mode: clear the vterm. */
-           if (!term->tl_terminal_mode)
+           if (term->tl_terminal_mode == 0)
                cleanup_vterm(term);
 
            redraw_buf_and_status_later(term->tl_buffer, NOT_VALID);
@@ -1558,7 +1585,7 @@ term_update_window(win_T *wp)
     VTermState *state;
     VTermPos   pos;
 
-    if (term == NULL || term->tl_vterm == NULL || term->tl_terminal_mode)
+    if (term == NULL || term->tl_vterm == NULL || term->tl_terminal_mode != 0)
        return FAIL;
 
     vterm = term->tl_vterm;
@@ -1687,7 +1714,8 @@ term_show_buffer(buf_T *buf)
 {
     term_T *term = buf->b_term;
 
-    return term != NULL && (term->tl_vterm == NULL || term->tl_terminal_mode);
+    return term != NULL
+                   && (term->tl_vterm == NULL || term->tl_terminal_mode != 0);
 }
 
 /*
@@ -1770,7 +1798,7 @@ term_get_status_text(term_T *term)
        char_u *txt;
        size_t len;
 
-       if (term->tl_terminal_mode)
+       if (term->tl_terminal_mode != 0)
        {
            if (term_job_running(term))
                txt = (char_u *)_("Terminal");
@@ -1997,7 +2025,7 @@ f_term_getstatus(typval_T *argvars, typval_T *rettv)
        STRCPY(val, "running");
     else
        STRCPY(val, "finished");
-    if (term->tl_terminal_mode)
+    if (term->tl_terminal_mode != 0)
        STRCAT(val, ",terminal");
     rettv->vval.v_string = vim_strsave(val);
 }
@@ -2159,7 +2187,7 @@ f_term_sendkeys(typval_T *argvars, typval_T *rettv)
        msg += MB_PTR2LEN(msg);
     }
 
-    if (!term->tl_terminal_mode)
+    if (term->tl_terminal_mode == 0)
     {
        /* TODO: only update once in a while. */
        update_screen(0);
index b3f3eb5253467a850cb8a722acd211bf066eb524..54acc59d330c0083dee99bbe3a3d81ee0aceeef4 100644 (file)
@@ -769,6 +769,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    873,
 /**/
     872,
 /**/