Patch 9.0.0912
Problem:    libvterm with modifyOtherKeys level 2 does not match xterm.
Solution:   Adjust key code escape sequences to be the same as what xterm
            sends in modifyOtherKeys level 2 mode.  Check the value of
            no_reduce_keys before using it.
Files:      src/libvterm/src/keyboard.c, src/terminal.c,
            src/proto/terminal.pro, src/getchar.c, src/misc2.c,
            src/testdir/keycode_check.vim, src/testdir/keycode_check.json


*** ../vim-9.0.0911/src/libvterm/src/keyboard.c 2022-10-16 19:26:31.676328577 
+0100
--- src/libvterm/src/keyboard.c 2022-11-19 18:42:56.791430809 +0000
***************
*** 14,20 ****
  void vterm_keyboard_unichar(VTerm *vt, uint32_t c, VTermModifier mod)
  {
    // VIM: added modifyOtherKeys support
!   if (vt->state->mode.modify_other_keys && mod != 0) {
      vterm_push_output_sprintf_ctrl(vt, C1_CSI, "27;%d;%d~", mod+1, c);
      return;
    }
--- 14,20 ----
  void vterm_keyboard_unichar(VTerm *vt, uint32_t c, VTermModifier mod)
  {
    // VIM: added modifyOtherKeys support
!   if (vterm_is_modify_other_keys(vt) && mod != 0) {
      vterm_push_output_sprintf_ctrl(vt, C1_CSI, "27;%d;%d~", mod+1, c);
      return;
    }
***************
*** 184,190 ****
      break;
  
    case KEYCODE_LITERAL: case_LITERAL:
!     if(mod & (VTERM_MOD_SHIFT|VTERM_MOD_CTRL))
        vterm_push_output_sprintf_ctrl(vt, C1_CSI, "%d;%du", k.literal, mod+1);
      else
        vterm_push_output_sprintf(vt, mod & VTERM_MOD_ALT ? ESC_S "%c" : "%c", 
k.literal);
--- 184,192 ----
      break;
  
    case KEYCODE_LITERAL: case_LITERAL:
!     if (vterm_is_modify_other_keys(vt) && mod != 0)
!       vterm_push_output_sprintf_ctrl(vt, C1_CSI, "27;%d;%d~", mod+1, 
k.literal);
!     else if(mod & (VTERM_MOD_SHIFT|VTERM_MOD_CTRL))
        vterm_push_output_sprintf_ctrl(vt, C1_CSI, "%d;%du", k.literal, mod+1);
      else
        vterm_push_output_sprintf(vt, mod & VTERM_MOD_ALT ? ESC_S "%c" : "%c", 
k.literal);
*** ../vim-9.0.0911/src/terminal.c      2022-11-02 13:30:37.542314565 +0000
--- src/terminal.c      2022-11-19 18:58:50.085214716 +0000
***************
*** 2168,2173 ****
--- 2168,2205 ----
  }
  
  /*
+  * When "modify_other_keys" is set then vgetc() should not reduce a key with
+  * modifiers into a basic key.  However, we may only find out after calling
+  * vgetc().  Therefore vgetorpeek() will call check_no_reduce_keys() to update
+  * "no_reduce_keys" before using it.
+  */
+ typedef enum {
+     NRKS_NONE,            // initial value
+     NRKS_CHECK,           // modify_other_keys was off before calling vgetc()
+     NRKS_SET,     // no_reduce_keys was incremented in term_vgetc() or
+                   // check_no_reduce_keys(), must be decremented.
+ } reduce_key_state_T;
+ 
+ static reduce_key_state_T  no_reduce_key_state = NRKS_NONE;
+ 
+     void
+ check_no_reduce_keys(void)
+ {
+     if (no_reduce_key_state != NRKS_CHECK
+           || no_reduce_keys >= 1
+           || curbuf->b_term == NULL
+           || curbuf->b_term->tl_vterm == NULL)
+       return;
+ 
+     if (vterm_is_modify_other_keys(curbuf->b_term->tl_vterm))
+     {
+       // "modify_other_keys" was enabled while waiting.
+       no_reduce_key_state = NRKS_SET;
+       ++no_reduce_keys;
+     }
+ }
+ 
+ /*
   * Get a key from the user with terminal mode mappings.
   * Note: while waiting a terminal may be closed and freed if the channel is
   * closed and ++close was used.  This may even happen before we get here.
***************
*** 2177,2197 ****
  {
      int c;
      int save_State = State;
-     int modify_other_keys = curbuf->b_term->tl_vterm == NULL ? FALSE
-                       : vterm_is_modify_other_keys(curbuf->b_term->tl_vterm);
  
      State = MODE_TERMINAL;
      got_int = FALSE;
  #ifdef MSWIN
      ctrl_break_was_pressed = FALSE;
  #endif
!     if (modify_other_keys)
        ++no_reduce_keys;
      c = vgetc();
      got_int = FALSE;
      State = save_State;
!     if (modify_other_keys)
        --no_reduce_keys;
      return c;
  }
  
--- 2209,2240 ----
  {
      int c;
      int save_State = State;
  
      State = MODE_TERMINAL;
      got_int = FALSE;
  #ifdef MSWIN
      ctrl_break_was_pressed = FALSE;
  #endif
! 
!     if (curbuf->b_term->tl_vterm != NULL
!                      && vterm_is_modify_other_keys(curbuf->b_term->tl_vterm))
!     {
        ++no_reduce_keys;
+       no_reduce_key_state = NRKS_SET;
+     }
+     else
+     {
+       no_reduce_key_state = NRKS_CHECK;
+     }
+ 
      c = vgetc();
      got_int = FALSE;
      State = save_State;
! 
!     if (no_reduce_key_state == NRKS_SET)
        --no_reduce_keys;
+     no_reduce_key_state = NRKS_NONE;
+ 
      return c;
  }
  
*** ../vim-9.0.0911/src/proto/terminal.pro      2022-10-09 18:53:29.024591198 
+0100
--- src/proto/terminal.pro      2022-11-19 18:58:56.153221592 +0000
***************
*** 15,20 ****
--- 15,21 ----
  int term_check_timers(int next_due_arg, proftime_T *now);
  int term_in_normal_mode(void);
  void term_enter_job_mode(void);
+ void check_no_reduce_keys(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);
*** ../vim-9.0.0911/src/getchar.c       2022-11-18 22:14:04.802988148 +0000
--- src/getchar.c       2022-11-19 18:49:20.256385118 +0000
***************
*** 2778,2783 ****
--- 2778,2786 ----
  
            // If no termcode matched, try to include the modifier into the
            // key.  This is for when modifyOtherKeys is working.
+ #ifdef FEAT_TERMINAL
+           check_no_reduce_keys();  // may update the no_reduce_keys flag
+ #endif
            if (keylen == 0 && !no_reduce_keys)
            {
                keylen = check_simplify_modifier(max_mlen + 1);
***************
*** 3919,3927 ****
        {
            // CTRL-V is followed by octal, hex or other characters, reverses
            // what AppendToRedobuffLit() does.
!           no_reduce_keys = TRUE;  //  don't merge modifyOtherKeys
            c1 = get_literal(TRUE);
!           no_reduce_keys = FALSE;
        }
  
        if (got_int)
--- 3922,3930 ----
        {
            // CTRL-V is followed by octal, hex or other characters, reverses
            // what AppendToRedobuffLit() does.
!           ++no_reduce_keys;  //  don't merge modifyOtherKeys
            c1 = get_literal(TRUE);
!           --no_reduce_keys;
        }
  
        if (got_int)
*** ../vim-9.0.0911/src/misc2.c 2022-11-18 14:07:16.116692387 +0000
--- src/misc2.c 2022-11-19 18:50:34.112520897 +0000
***************
*** 1516,1522 ****
   * CTRL-2 is CTRL-@
   * CTRL-6 is CTRL-^
   * CTRL-- is CTRL-_
!  * Also, <C-H> and <C-h> mean the same thing, always use "H".
   * Returns the possibly adjusted key.
   */
      int
--- 1516,1523 ----
   * CTRL-2 is CTRL-@
   * CTRL-6 is CTRL-^
   * CTRL-- is CTRL-_
!  * Also, unless no_reduce_keys is set then <C-H> and <C-h> mean the same 
thing,
!  * use "H".
   * Returns the possibly adjusted key.
   */
      int
***************
*** 1525,1531 ****
      if (modifiers & MOD_MASK_CTRL)
      {
        if (ASCII_ISALPHA(key))
!           return TOUPPER_ASC(key);
        if (key == '2')
            return '@';
        if (key == '6')
--- 1526,1537 ----
      if (modifiers & MOD_MASK_CTRL)
      {
        if (ASCII_ISALPHA(key))
!       {
! #ifdef FEAT_TERMINAL
!           check_no_reduce_keys();  // may update the no_reduce_keys flag
! #endif
!           return no_reduce_keys == 0 ? TOUPPER_ASC(key) : key;
!       }
        if (key == '2')
            return '@';
        if (key == '6')
*** ../vim-9.0.0911/src/testdir/keycode_check.vim       2022-11-18 
21:20:21.811312017 +0000
--- src/testdir/keycode_check.vim       2022-11-19 18:27:21.857590174 +0000
***************
*** 319,328 ****
      ch_logfile('keylog-ignore', 'a')
      while 1
        sleep 100m
!       if !getchar(1)
        break
        endif
!       while getchar(1)
        getchar()
        endwhile
      endwhile
--- 319,328 ----
      ch_logfile('keylog-ignore', 'a')
      while 1
        sleep 100m
!       if getchar(1) == 0
        break
        endif
!       while getchar(1) != 0
        getchar()
        endwhile
      endwhile
*** ../vim-9.0.0911/src/testdir/keycode_check.json      2022-11-16 
16:08:26.987063566 +0000
--- src/testdir/keycode_check.json      2022-11-19 18:46:50.044068528 +0000
***************
*** 1 ****
! 
{"12xterm":{"Space":"20","version":"1b5b3e34313b3335363b3063","C-Tab":"1b5b32373b353b397e","A-Esc":"1b5b32373b333b32377e","C-Space":"1b5b32373b353b33327e","status":"","S-C-I":"1b5b32373b363b37337e","C-I":"1b5b32373b353b3130357e","S-Tab":"1b5b5a","Tab":"09","S-Space":"1b5b32373b323b33327e","A-Tab":"1b5b32373b333b397e","C-Esc":"1b5b32373b353b32377e","protocol":"mok2","A-Space":"1b5b32373b333b33327e","S-Esc":"1b","Esc":"1b"},"2kitty":{"Space":"20","version":"1b5b3e313b343030303b323163","C-Tab":"","A-Esc":"1b5b32373b313175","C-Space":"1b5b33323b3575","status":"1b5b3f3175","S-C-I":"1b5b3130353b3675","C-I":"1b5b3130353b3575","S-Tab":"1b5b393b3275","Tab":"09","S-Space":"20","A-Tab":"1b5b393b313175","C-Esc":"1b5b32373b3575","protocol":"kitty","A-Space":"1b5b33323b313175","S-Esc":"1b5b32373b3275","Esc":"1b5b323775"},"11xterm":{"Space":"20","version":"1b5b3e34313b3335363b3063","C-Tab":"09","A-Esc":"9b00","status":"","S-C-I":"09","C-I":"09","S-Tab":"1b5b5a","Tab":"09","S-Space":"20","A-Tab":"
 8900","C-Esc":"1b","protocol":"none","A-Space":"a000","S-Esc":"1b","Esc":"1b"}}
--- 1 ----
! 
{"12xterm":{"Space":"20","version":"1b5b3e34313b3335363b3063","C-Tab":"1b5b32373b353b397e","A-Esc":"1b5b32373b333b32377e","C-Space":"1b5b32373b353b33327e","status":"","S-C-I":"1b5b32373b363b37337e","C-I":"1b5b32373b353b3130357e","S-Tab":"1b5b5a","Tab":"09","S-Space":"1b5b32373b323b33327e","A-Tab":"1b5b32373b333b397e","C-Esc":"1b5b32373b353b32377e","protocol":"mok2","A-Space":"1b5b32373b333b33327e","S-Esc":"1b","Esc":"1b"},"libvterm":{"Space":"20","version":"1b5b3e303b3130303b3063","C-Tab":"1b5b32373b353b397e","A-Esc":"1b5b32373b333b32377e","C-Space":"1b5b32373b353b33327e","status":"","S-C-I":"1b5b32373b363b37337e","C-I":"1b5b32373b353b3130357e","S-Tab":"1b5b5a","Tab":"09","resource":"","A-Tab":"1b5b32373b333b397e","S-Space":"1b5b32373b323b33327e","C-Esc":"1b5b32373b353b32377e","protocol":"mok2","A-Space":"1b5b32373b333b33327e","S-Esc":"1b","Esc":"1b"},"2kitty":{"Space":"20","version":"1b5b3e313b343030303b323163","C-Tab":"","A-Esc":"1b5b32373b313175","C-Space":"1b5b33323b3575","stat
 
us":"1b5b3f3175","S-C-I":"1b5b3130353b3675","C-I":"1b5b3130353b3575","S-Tab":"1b5b393b3275","Tab":"09","S-Space":"20","A-Tab":"1b5b393b313175","C-Esc":"1b5b32373b3575","protocol":"kitty","A-Space":"1b5b33323b313175","S-Esc":"1b5b32373b3275","Esc":"1b5b323775"},"11xterm":{"Space":"20","version":"1b5b3e34313b3335363b3063","C-Tab":"09","A-Esc":"9b00","status":"","S-C-I":"09","C-I":"09","S-Tab":"1b5b5a","Tab":"09","S-Space":"20","A-Tab":"8900","C-Esc":"1b","protocol":"none","A-Space":"a000","S-Esc":"1b","Esc":"1b"}}
*** ../vim-9.0.0911/src/version.c       2022-11-19 14:31:04.356796241 +0000
--- src/version.c       2022-11-19 15:44:04.016892513 +0000
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     912,
  /**/

-- 
A fool learns from his mistakes, a wise man from someone else's.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            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/20221119190312.14D6C1C12B2%40moolenaar.net.

Raspunde prin e-mail lui