]> granicus.if.org Git - vim/commitdiff
patch 8.1.2248: CTRL-W dot does not work when modifyOtherKeys is enabled v8.1.2248
authorBram Moolenaar <Bram@vim.org>
Sun, 3 Nov 2019 20:19:41 +0000 (21:19 +0100)
committerBram Moolenaar <Bram@vim.org>
Sun, 3 Nov 2019 20:19:41 +0000 (21:19 +0100)
Problem:    CTRL-W dot does not work in a terminal when modifyOtherKeys is
            enabled.
Solution:   Use the modifier when needed.  Pass the modifier along with the
            key to avoid mistakes.

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

index b71ef37a4cbd2ef4a6f53b20a2620c7fa1f146e7..366cbaf542f2bfc1ad726e45f83a60afd18a9936 100644 (file)
@@ -2012,7 +2012,7 @@ nv_mousescroll(cmdarg_T *cap)
        if (term_use_loop())
            // This window is a terminal window, send the mouse event there.
            // Set "typed" to FALSE to avoid an endless loop.
-           send_keys_to_term(curbuf->b_term, cap->cmdchar, FALSE);
+           send_keys_to_term(curbuf->b_term, cap->cmdchar, mod_mask, FALSE);
        else
 # endif
        if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
index 52bb1b8d4a3713d8253ee24f1730732e46552148..5206addd459cb49f482e0ff077f550723a7cbcc0 100644 (file)
@@ -13,7 +13,7 @@ int term_try_stop_job(buf_T *buf);
 int term_check_timers(int next_due_arg, proftime_T *now);
 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 send_keys_to_term(term_T *term, int c, int modmask, int typed);
 int terminal_is_active(void);
 cursorentry_T *term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg);
 int term_use_loop(void);
index 13e32eb5d10ef2bdb14dc96b736b8064d1a805ac..10343fe20ec6f21f8ba177155ac7b04ab233635f 100644 (file)
@@ -1226,11 +1226,12 @@ term_mouse_click(VTerm *vterm, int key)
 }
 
 /*
- * Convert typed key "c" into bytes to send to the job.
+ * Convert typed key "c" with modifiers "modmask" into bytes to send to the
+ * job.
  * Return the number of bytes in "buf".
  */
     static int
-term_convert_key(term_T *term, int c, char *buf)
+term_convert_key(term_T *term, int c, int modmask, char *buf)
 {
     VTerm          *vterm = term->tl_vterm;
     VTermKey       key = VTERM_KEY_NONE;
@@ -1375,11 +1376,11 @@ term_convert_key(term_T *term, int c, char *buf)
     }
 
     // add modifiers for the typed key
-    if (mod_mask & MOD_MASK_SHIFT)
+    if (modmask & MOD_MASK_SHIFT)
        mod |= VTERM_MOD_SHIFT;
-    if (mod_mask & MOD_MASK_CTRL)
+    if (modmask & MOD_MASK_CTRL)
        mod |= VTERM_MOD_CTRL;
-    if (mod_mask & (MOD_MASK_ALT | MOD_MASK_META))
+    if (modmask & (MOD_MASK_ALT | MOD_MASK_META))
        mod |= VTERM_MOD_ALT;
 
     /*
@@ -1933,12 +1934,12 @@ term_vgetc()
 static int     mouse_was_outside = FALSE;
 
 /*
- * Send keys to terminal.
+ * Send key "c" with modifiers "modmask" to terminal.
  * Return FAIL when the key needs to be handled in Normal mode.
  * Return OK when the key was dropped or sent to the terminal.
  */
     int
-send_keys_to_term(term_T *term, int c, int typed)
+send_keys_to_term(term_T *term, int c, int modmask, int typed)
 {
     char       msg[KEY_BUF_LEN];
     size_t     len;
@@ -2005,10 +2006,10 @@ send_keys_to_term(term_T *term, int c, int typed)
     if (typed)
        mouse_was_outside = FALSE;
 
-    /* Convert the typed key to a sequence of bytes for the job. */
-    len = term_convert_key(term, c, msg);
+    // Convert the typed key to a sequence of bytes for the job.
+    len = term_convert_key(term, c, modmask, msg);
     if (len > 0)
-       /* TODO: if FAIL is returned, stop? */
+       // TODO: if FAIL is returned, stop?
        channel_send(term->tl_job->jv_channel, get_tty_part(term),
                                                (char_u *)msg, (int)len, NULL);
 
@@ -2258,6 +2259,34 @@ term_win_entered()
     }
 }
 
+/*
+ * vgetc() may not include CTRL in the key when modify_other_keys is set.
+ * Return the Ctrl-key value in that case.
+ */
+    static int
+raw_c_to_ctrl(int c)
+{
+    if ((mod_mask & MOD_MASK_CTRL)
+           && ((c >= '`' && c <= 0x7f) || (c >= '@' && c <= '_')))
+       return c & 0x1f;
+    return c;
+}
+
+/*
+ * When modify_other_keys is set then do the reverse of raw_c_to_ctrl().
+ * May set "mod_mask".
+ */
+    static int
+ctrl_to_raw_c(int c)
+{
+    if (c < 0x20 && vterm_is_modify_other_keys(curbuf->b_term->tl_vterm))
+    {
+       mod_mask |= MOD_MASK_CTRL;
+       return c + '@';
+    }
+    return c;
+}
+
 /*
  * Wait for input and send it to the job.
  * When "blocking" is TRUE wait for a character to be typed.  Otherwise return
@@ -2312,24 +2341,18 @@ terminal_loop(int blocking)
        update_cursor(curbuf->b_term, FALSE);
        restore_cursor = TRUE;
 
-       c = term_vgetc();
+       raw_c = term_vgetc();
        if (!term_use_loop_check(TRUE) || in_terminal_loop != curbuf->b_term)
        {
            /* Job finished while waiting for a character.  Push back the
             * received character. */
-           if (c != K_IGNORE)
-               vungetc(c);
+           if (raw_c != K_IGNORE)
+               vungetc(raw_c);
            break;
        }
-       if (c == K_IGNORE)
+       if (raw_c == K_IGNORE)
            continue;
-
-       // vgetc may not include CTRL in the key when modify_other_keys is set.
-       raw_c = c;
-       if ((mod_mask & MOD_MASK_CTRL)
-               && ((c >= '`' && c <= 0x7f)
-                   || (c >= '@' && c <= '_')))
-           c &= 0x1f;
+       c = raw_c_to_ctrl(raw_c);
 
 #ifdef UNIX
        /*
@@ -2362,12 +2385,16 @@ terminal_loop(int blocking)
                )
        {
            int     prev_c = c;
+           int     prev_raw_c = raw_c;
+           int     prev_mod_mask = mod_mask;
 
 #ifdef FEAT_CMDL_INFO
            if (add_to_showcmd(c))
                out_flush();
 #endif
-           c = term_vgetc();
+           raw_c = term_vgetc();
+           c = raw_c_to_ctrl(raw_c);
+
 #ifdef FEAT_CMDL_INFO
            clear_showcmd();
 #endif
@@ -2385,8 +2412,10 @@ terminal_loop(int blocking)
                    ret = FAIL;
                    goto theend;
                }
-               /* Send both keys to the terminal. */
-               send_keys_to_term(curbuf->b_term, prev_c, TRUE);
+               // Send both keys to the terminal, first one here, second one
+               // below.
+               send_keys_to_term(curbuf->b_term, prev_raw_c, prev_mod_mask,
+                                                                        TRUE);
            }
            else if (c == Ctrl_C)
            {
@@ -2397,12 +2426,12 @@ terminal_loop(int blocking)
            {
                /* "CTRL-W .": send CTRL-W to the job */
                /* "'termwinkey' .": send 'termwinkey' to the job */
-               c = termwinkey == 0 ? Ctrl_W : termwinkey;
+               raw_c = ctrl_to_raw_c(termwinkey == 0 ? Ctrl_W : termwinkey);
            }
            else if (c == Ctrl_BSL)
            {
                /* "CTRL-W CTRL-\": send CTRL-\ to the job */
-               c = Ctrl_BSL;
+               raw_c = ctrl_to_raw_c(Ctrl_BSL);
            }
            else if (c == 'N')
            {
@@ -2430,20 +2459,20 @@ terminal_loop(int blocking)
            }
        }
 # ifdef MSWIN
-       if (!enc_utf8 && has_mbyte && c >= 0x80)
+       if (!enc_utf8 && has_mbyte && raw_c >= 0x80)
        {
            WCHAR   wc;
            char_u  mb[3];
 
-           mb[0] = (unsigned)c >> 8;
-           mb[1] = c;
+           mb[0] = (unsigned)raw_c >> 8;
+           mb[1] = raw_c;
            if (MultiByteToWideChar(GetACP(), 0, (char*)mb, 2, &wc, 1) > 0)
-               c = wc;
+               raw_c = wc;
        }
 # endif
-       if (send_keys_to_term(curbuf->b_term, raw_c, TRUE) != OK)
+       if (send_keys_to_term(curbuf->b_term, raw_c, mod_mask, TRUE) != OK)
        {
-           if (c == K_MOUSEMOVE)
+           if (raw_c == K_MOUSEMOVE)
                /* We are sure to come back here, don't reset the cursor color
                 * and shape to avoid flickering. */
                restore_cursor = FALSE;
@@ -5545,7 +5574,7 @@ f_term_sendkeys(typval_T *argvars, typval_T *rettv)
            c = PTR2CHAR(msg);
            msg += MB_CPTR2LEN(msg);
        }
-       send_keys_to_term(term, c, FALSE);
+       send_keys_to_term(term, c, 0, FALSE);
     }
 }
 
@@ -5811,7 +5840,8 @@ typedef int LPPROC_THREAD_ATTRIBUTE_LIST;
 typedef int SIZE_T;
 typedef int PSIZE_T;
 typedef int PVOID;
-typedef int WINAPI;
+typedef int BOOL;
+# define WINAPI
 #endif
 
 HRESULT (WINAPI *pCreatePseudoConsole)(COORD, HANDLE, HANDLE, DWORD, HPCON*);
index 62897987c5b1dfffa8a99aa7c5da908e07c09a2f..a577dab70baf2abfc787bf207e4871323ebfd90b 100644 (file)
@@ -741,6 +741,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2248,
 /**/
     2247,
 /**/