Patch 8.1.2248
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.
Files:      src/terminal.c, src/proto/terminal.pro, src/mouse.c


*** ../vim-8.1.2247/src/terminal.c      2019-10-26 16:21:34.511468348 +0200
--- src/terminal.c      2019-11-03 20:58:13.371134721 +0100
***************
*** 1226,1236 ****
  }
  
  /*
!  * Convert typed key "c" 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)
  {
      VTerm         *vterm = term->tl_vterm;
      VTermKey      key = VTERM_KEY_NONE;
--- 1226,1237 ----
  }
  
  /*
!  * 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, int modmask, char *buf)
  {
      VTerm         *vterm = term->tl_vterm;
      VTermKey      key = VTERM_KEY_NONE;
***************
*** 1375,1385 ****
      }
  
      // add modifiers for the typed key
!     if (mod_mask & MOD_MASK_SHIFT)
        mod |= VTERM_MOD_SHIFT;
!     if (mod_mask & MOD_MASK_CTRL)
        mod |= VTERM_MOD_CTRL;
!     if (mod_mask & (MOD_MASK_ALT | MOD_MASK_META))
        mod |= VTERM_MOD_ALT;
  
      /*
--- 1376,1386 ----
      }
  
      // add modifiers for the typed key
!     if (modmask & MOD_MASK_SHIFT)
        mod |= VTERM_MOD_SHIFT;
!     if (modmask & MOD_MASK_CTRL)
        mod |= VTERM_MOD_CTRL;
!     if (modmask & (MOD_MASK_ALT | MOD_MASK_META))
        mod |= VTERM_MOD_ALT;
  
      /*
***************
*** 1933,1944 ****
  static int    mouse_was_outside = FALSE;
  
  /*
!  * Send keys 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)
  {
      char      msg[KEY_BUF_LEN];
      size_t    len;
--- 1934,1945 ----
  static int    mouse_was_outside = FALSE;
  
  /*
!  * 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 modmask, int typed)
  {
      char      msg[KEY_BUF_LEN];
      size_t    len;
***************
*** 2005,2014 ****
      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);
      if (len > 0)
!       /* TODO: if FAIL is returned, stop? */
        channel_send(term->tl_job->jv_channel, get_tty_part(term),
                                                (char_u *)msg, (int)len, NULL);
  
--- 2006,2015 ----
      if (typed)
        mouse_was_outside = FALSE;
  
!     // 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?
        channel_send(term->tl_job->jv_channel, get_tty_part(term),
                                                (char_u *)msg, (int)len, NULL);
  
***************
*** 2259,2264 ****
--- 2260,2293 ----
  }
  
  /*
+  * 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
   * when there is no more typahead.
***************
*** 2312,2335 ****
        update_cursor(curbuf->b_term, FALSE);
        restore_cursor = TRUE;
  
!       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);
            break;
        }
!       if (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;
  
  #ifdef UNIX
        /*
--- 2341,2358 ----
        update_cursor(curbuf->b_term, FALSE);
        restore_cursor = TRUE;
  
!       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 (raw_c != K_IGNORE)
!               vungetc(raw_c);
            break;
        }
!       if (raw_c == K_IGNORE)
            continue;
!       c = raw_c_to_ctrl(raw_c);
  
  #ifdef UNIX
        /*
***************
*** 2362,2373 ****
                )
        {
            int     prev_c = c;
  
  #ifdef FEAT_CMDL_INFO
            if (add_to_showcmd(c))
                out_flush();
  #endif
!           c = term_vgetc();
  #ifdef FEAT_CMDL_INFO
            clear_showcmd();
  #endif
--- 2385,2400 ----
                )
        {
            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
!           raw_c = term_vgetc();
!           c = raw_c_to_ctrl(raw_c);
! 
  #ifdef FEAT_CMDL_INFO
            clear_showcmd();
  #endif
***************
*** 2385,2392 ****
                    ret = FAIL;
                    goto theend;
                }
!               /* Send both keys to the terminal. */
!               send_keys_to_term(curbuf->b_term, prev_c, TRUE);
            }
            else if (c == Ctrl_C)
            {
--- 2412,2421 ----
                    ret = FAIL;
                    goto theend;
                }
!               // 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,2408 ****
            {
                /* "CTRL-W .": send CTRL-W to the job */
                /* "'termwinkey' .": send 'termwinkey' to the job */
!               c = termwinkey == 0 ? Ctrl_W : termwinkey;
            }
            else if (c == Ctrl_BSL)
            {
                /* "CTRL-W CTRL-\": send CTRL-\ to the job */
!               c = Ctrl_BSL;
            }
            else if (c == 'N')
            {
--- 2426,2437 ----
            {
                /* "CTRL-W .": send CTRL-W to the job */
                /* "'termwinkey' .": send 'termwinkey' to the job */
!               raw_c = ctrl_to_raw_c(termwinkey == 0 ? Ctrl_W : termwinkey);
            }
            else if (c == Ctrl_BSL)
            {
                /* "CTRL-W CTRL-\": send CTRL-\ to the job */
!               raw_c = ctrl_to_raw_c(Ctrl_BSL);
            }
            else if (c == 'N')
            {
***************
*** 2430,2449 ****
            }
        }
  # ifdef MSWIN
!       if (!enc_utf8 && has_mbyte && c >= 0x80)
        {
            WCHAR   wc;
            char_u  mb[3];
  
!           mb[0] = (unsigned)c >> 8;
!           mb[1] = c;
            if (MultiByteToWideChar(GetACP(), 0, (char*)mb, 2, &wc, 1) > 0)
!               c = wc;
        }
  # endif
!       if (send_keys_to_term(curbuf->b_term, raw_c, TRUE) != OK)
        {
!           if (c == K_MOUSEMOVE)
                /* We are sure to come back here, don't reset the cursor color
                 * and shape to avoid flickering. */
                restore_cursor = FALSE;
--- 2459,2478 ----
            }
        }
  # ifdef MSWIN
!       if (!enc_utf8 && has_mbyte && raw_c >= 0x80)
        {
            WCHAR   wc;
            char_u  mb[3];
  
!           mb[0] = (unsigned)raw_c >> 8;
!           mb[1] = raw_c;
            if (MultiByteToWideChar(GetACP(), 0, (char*)mb, 2, &wc, 1) > 0)
!               raw_c = wc;
        }
  # endif
!       if (send_keys_to_term(curbuf->b_term, raw_c, mod_mask, TRUE) != OK)
        {
!           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,5551 ****
            c = PTR2CHAR(msg);
            msg += MB_CPTR2LEN(msg);
        }
!       send_keys_to_term(term, c, FALSE);
      }
  }
  
--- 5574,5580 ----
            c = PTR2CHAR(msg);
            msg += MB_CPTR2LEN(msg);
        }
!       send_keys_to_term(term, c, 0, FALSE);
      }
  }
  
***************
*** 5811,5817 ****
  typedef int SIZE_T;
  typedef int PSIZE_T;
  typedef int PVOID;
! typedef int WINAPI;
  #endif
  
  HRESULT (WINAPI *pCreatePseudoConsole)(COORD, HANDLE, HANDLE, DWORD, HPCON*);
--- 5840,5847 ----
  typedef int SIZE_T;
  typedef int PSIZE_T;
  typedef int PVOID;
! typedef int BOOL;
! # define WINAPI
  #endif
  
  HRESULT (WINAPI *pCreatePseudoConsole)(COORD, HANDLE, HANDLE, DWORD, HPCON*);
*** ../vim-8.1.2247/src/proto/terminal.pro      2019-09-26 23:08:10.501926883 
+0200
--- src/proto/terminal.pro      2019-11-03 20:58:15.111125061 +0100
***************
*** 13,19 ****
  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 terminal_is_active(void);
  cursorentry_T *term_get_cursor_shape(guicolor_T *fg, guicolor_T *bg);
  int term_use_loop(void);
--- 13,19 ----
  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 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);
*** ../vim-8.1.2247/src/mouse.c 2019-10-17 22:58:59.066497012 +0200
--- src/mouse.c 2019-11-03 19:56:50.723673238 +0100
***************
*** 2012,2018 ****
        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);
        else
  # endif
        if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
--- 2012,2018 ----
        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, mod_mask, FALSE);
        else
  # endif
        if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL))
*** ../vim-8.1.2247/src/version.c       2019-11-03 18:38:44.492598820 +0100
--- src/version.c       2019-11-03 21:17:41.969127362 +0100
***************
*** 743,744 ****
--- 743,746 ----
  {   /* Add new patch number below this line */
+ /**/
+     2248,
  /**/

-- 
How To Keep A Healthy Level Of Insanity:
13. Go to a poetry recital and ask why the poems don't rhyme.

 /// Bram Moolenaar -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/201911032020.xA3KKLLJ020307%40masaka.moolenaar.net.

Raspunde prin e-mail lui