Patch 9.0.1220
Problem:    Termcap/terminfo entries do not indicate where modifiers might
            appear.
Solution:   Add ";*" for function keys where modifiers are likely to be used.
Files:      src/term.c


*** ../vim-9.0.1219/src/term.c  2023-01-14 21:07:03.998952303 +0000
--- src/term.c  2023-01-18 17:10:29.050692379 +0000
***************
*** 65,70 ****
--- 65,71 ----
  static int find_term_bykeys(char_u *src);
  static int term_is_builtin(char_u *name);
  static int term_7to8bit(char_u *p);
+ static void accept_modifiers_for_function_keys(void);
  
      // Change this to "if 1" to debug what happens with termresponse.
  #  if 0
***************
*** 2097,2102 ****
--- 2098,2108 ----
                && term_strings_not_set(KS_8U))
            apply_builtin_tcap(term, builtin_rgb, TRUE);
  #endif
+ 
+       if (kpc != KEYPROTOCOL_NONE)
+           // Some function keys may accept modifiers even though the
+           // terminfo/termcap entry does not indicate this.
+           accept_modifiers_for_function_keys();
      }
  
  /*
***************
*** 2212,2217 ****
--- 2218,2226 ----
  
  #ifdef FEAT_MOUSE_XTERM
      // Focus reporting is supported by xterm compatible terminals and tmux.
+     // We hard-code the received escape sequences here.  There are the 
terminfo
+     // entries kxIN and kxOUT, but they are rarely used and do hot have a
+     // two-letter termcap name.
      if (use_xterm_like_mouse(term))
      {
        char_u name[3];
***************
*** 4471,4476 ****
--- 4480,4504 ----
  #define ATC_FROM_TERM 55
  
  /*
+  * For xterm we recognize special codes like "ESC[42;*X" and "ESC O*X" that
+  * accept modifiers.
+  * Set "termcodes[idx].modlen".
+  */
+     static void
+ adjust_modlen(int idx)
+ {
+     termcodes[idx].modlen = 0;
+     int j = termcode_star(termcodes[idx].code, termcodes[idx].len);
+     if (j <= 0)
+       return;
+ 
+     termcodes[idx].modlen = termcodes[idx].len - 1 - j;
+     // For "CSI[@;X" the "@" is not included in "modlen".
+     if (termcodes[idx].code[termcodes[idx].modlen - 1] == '@')
+       --termcodes[idx].modlen;
+ }
+ 
+ /*
   * Add a new entry for "name[2]" to the list of terminal codes.
   * Note that "name" may not have a terminating NUL.
   * The list is kept alphabetical for ":set termcap"
***************
*** 4618,4639 ****
      termcodes[i].name[1] = name[1];
      termcodes[i].code = s;
      termcodes[i].len = len;
  
-     // For xterm we recognize special codes like "ESC[42;*X" and "ESC O*X" 
that
-     // accept modifiers.
-     termcodes[i].modlen = 0;
-     j = termcode_star(s, len);
-     if (j > 0)
-     {
-       termcodes[i].modlen = len - 1 - j;
-       // For "CSI[@;X" the "@" is not included in "modlen".
-       if (termcodes[i].code[termcodes[i].modlen - 1] == '@')
-           --termcodes[i].modlen;
-     }
      ++tc_len;
  }
  
  /*
   * Check termcode "code[len]" for ending in ;*X or *X.
   * The "X" can be any character.
   * Return 0 if not found, 2 for ;*X and 1 for *X.
--- 4646,4699 ----
      termcodes[i].name[1] = name[1];
      termcodes[i].code = s;
      termcodes[i].len = len;
+     adjust_modlen(i);
  
      ++tc_len;
  }
  
  /*
+  * Some function keys may include modifiers, but the terminfo/termcap entries
+  * do not indicate that.  Insert ";*" where we expect modifiers might appear.
+  */
+     static void
+ accept_modifiers_for_function_keys(void)
+ {
+     regmatch_T regmatch;
+     CLEAR_FIELD(regmatch);
+     regmatch.rm_ic = TRUE;
+     regmatch.regprog = vim_regcomp((char_u *)"^\033[\\d\\+\\~$", RE_MAGIC);
+ 
+     for (int i = 0; i < tc_len; ++i)
+     {
+       if (regmatch.regprog == NULL)
+           return;
+ 
+       // skip PasteStart and PasteEnd
+       if (termcodes[i].name[0] == 'P'
+               && (termcodes[i].name[1] == 'S' || termcodes[i].name[1] == 'E'))
+           continue;
+ 
+       char_u *s = termcodes[i].code;
+       if (s != NULL && vim_regexec(&regmatch, s, (colnr_T)0))
+       {
+           size_t len = STRLEN(s);
+           char_u *ns = alloc(len + 3);
+           if (ns != NULL)
+           {
+               mch_memmove(ns, s, len - 1);
+               mch_memmove(ns + len - 1, ";*~", 4);
+               vim_free(s);
+               termcodes[i].code = ns;
+               termcodes[i].len += 2;
+               adjust_modlen(i);
+           }
+       }
+     }
+ 
+     vim_regfree(regmatch.regprog);
+ }
+ 
+ /*
   * Check termcode "code[len]" for ending in ;*X or *X.
   * The "X" can be any character.
   * Return 0 if not found, 2 for ;*X and 1 for *X.
*** ../vim-9.0.1219/src/version.c       2023-01-18 16:09:48.109103156 +0000
--- src/version.c       2023-01-18 16:52:45.165293160 +0000
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     1220,
  /**/

-- 
How To Keep A Healthy Level Of Insanity:
18. When leaving the zoo, start running towards the parking lot,
    yelling "run for your lives, they're loose!!"

 /// 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/20230118172115.C6D021C1261%40moolenaar.net.

Raspunde prin e-mail lui