Patch 8.2.4252
Problem:    Generating the normal command table at runtime is inefficient.
Solution:   Generate the table with a Vim script and put it in a header file.
            (Yegappan Lakshmanan, closes #9648)
Files:      Filelist, runtime/doc/builtin.txt, runtime/doc/usr_41.txt,
            src/Make_cyg_ming.mak, src/Make_mvc.mak, src/Make_vms.mms,
            src/Makefile, src/create_nvcmdidxs.vim, src/evalfunc.c,
            src/main.c, src/normal.c, src/nv_cmdidxs.h, src/proto/normal.pro


*** ../vim-8.2.4251/Filelist    2022-01-25 10:30:52.473915958 +0000
--- Filelist    2022-01-29 12:48:39.199668357 +0000
***************
*** 113,118 ****
--- 113,119 ----
                src/nbdebug.h \
                src/netbeans.c \
                src/normal.c \
+               src/nv_cmdidxs.h \
                src/ops.c \
                src/option.c \
                src/option.h \
***************
*** 443,448 ****
--- 444,450 ----
                src/configure \
                src/configure.ac \
                src/create_cmdidxs.vim \
+               src/create_nvcmdidxs.vim \
                src/gui_at_fs.c \
                src/gui_at_sb.c \
                src/gui_at_sb.h \
*** ../vim-8.2.4251/runtime/doc/builtin.txt     2022-01-27 13:16:54.328078845 
+0000
--- runtime/doc/builtin.txt     2022-01-29 12:48:39.203668297 +0000
***************
*** 292,297 ****
--- 292,298 ----
  inputsave()                   Number  save and clear typeahead
  inputsecret({prompt} [, {text}]) String       like input() but hiding the text
  insert({object}, {item} [, {idx}]) List       insert {item} in {object} 
[before {idx}]
+ internal_get_nv_cmdchar({idx})        Number  command character at this index
  interrupt()                   none    interrupt script execution
  invert({expr})                        Number  bitwise invert
  isdirectory({directory})      Number  |TRUE| if {directory} is a directory
***************
*** 4618,4623 ****
--- 4624,4634 ----
  
                Can also be used as a |method|: >
                        mylist->insert(item)
+ <
+                                               *internal_get_nv_cmdchar()*
+ internal_get_nv_cmdchar({idx})
+               Return the normal/visual mode command character at the
+               specified index. To be used only during the Vim build process.
  
  interrupt()                                           *interrupt()*
                Interrupt script execution.  It works more or less like the
*** ../vim-8.2.4251/runtime/doc/usr_41.txt      2022-01-27 13:16:54.328078845 
+0000
--- runtime/doc/usr_41.txt      2022-01-29 12:48:39.203668297 +0000
***************
*** 1019,1024 ****
--- 1110,1116 ----
        assert_nobeep()         assert that a command does not cause a beep
        assert_fails()          assert that a command fails
        assert_report()         report a test failure
+       internal_get_nv_cmdchar()  normal/visual command character at an index
        test_alloc_fail()       make memory allocation fail
        test_autochdir()        enable 'autochdir' during startup
        test_override()         test with Vim internal overrides
*** ../vim-8.2.4251/src/Make_cyg_ming.mak       2022-01-19 13:32:53.439930008 
+0000
--- src/Make_cyg_ming.mak       2022-01-29 12:48:39.203668297 +0000
***************
*** 1147,1152 ****
--- 1147,1162 ----
  cmdidxs: ex_cmds.h
        vim --clean -X --not-a-term -u create_cmdidxs.vim
  
+ # Run vim script to generate the normal/visual mode command lookup table.
+ # This only needs to be run when a new normal/visual mode command has been
+ # added.  If this fails because you don't have Vim yet:
+ #   - change nv_cmds[] in normal.c to add the new normal/visual mode command.
+ #   - build Vim
+ #   - run "make nvcmdidxs" using the new Vim to generate nv_cmdidxs.h
+ #   - rebuild Vim to use the newly generated nv_cmdidxs.h file.
+ nvcmdidxs: normal.c
+       ./$(TARGET) --clean -X --not-a-term -u create_nvcmdidxs.vim
+ 
  ###########################################################################
  INCL =        vim.h alloc.h ascii.h ex_cmds.h feature.h errors.h globals.h \
        keymap.h macros.h option.h os_dos.h os_win32.h proto.h regexp.h \
***************
*** 1209,1214 ****
--- 1219,1226 ----
  
  $(OUTDIR)/misc1.o: misc1.c $(INCL) version.h
  
+ $(OUTDIR)/normal.o: normal.c $(INCL) nv_cmdidxs.h
+ 
  $(OUTDIR)/netbeans.o: netbeans.c $(INCL) version.h
  
  $(OUTDIR)/version.o: version.c $(INCL) version.h
*** ../vim-8.2.4251/src/Make_mvc.mak    2022-01-28 18:54:10.125520952 +0000
--- src/Make_mvc.mak    2022-01-29 12:48:39.203668297 +0000
***************
*** 1446,1451 ****
--- 1446,1461 ----
  cmdidxs: ex_cmds.h
        vim --clean -X --not-a-term -u create_cmdidxs.vim
  
+ # Run vim script to generate the normal/visual mode command lookup table.
+ # This only needs to be run when a new normal/visual mode command has been
+ # added.  If this fails because you don't have Vim yet:
+ #   - change nv_cmds[] in normal.c to add the new normal/visual mode command.
+ #   - build Vim
+ #   - run "make nvcmdidxs" using the new Vim to generate nv_cmdidxs.h
+ #   - rebuild Vim to use the newly generated nv_cmdidxs.h file.
+ nvcmdidxs: normal.c
+       .\$(VIM) --clean -X --not-a-term -u create_nvcmdidxs.vim
+ 
  test:
        cd testdir
        $(MAKE) /NOLOGO -f Make_dos.mak
***************
*** 1709,1715 ****
  
  $(OUTDIR)/channel.obj:        $(OUTDIR) channel.c $(INCL)
  
! $(OUTDIR)/normal.obj: $(OUTDIR) normal.c  $(INCL)
  
  $(OUTDIR)/option.obj: $(OUTDIR) option.c  $(INCL) optiondefs.h
  
--- 1719,1725 ----
  
  $(OUTDIR)/channel.obj:        $(OUTDIR) channel.c $(INCL)
  
! $(OUTDIR)/normal.obj: $(OUTDIR) normal.c  $(INCL) nv_cmdidxs.h
  
  $(OUTDIR)/option.obj: $(OUTDIR) option.c  $(INCL) optiondefs.h
  
*** ../vim-8.2.4251/src/Make_vms.mms    2022-01-13 18:09:08.241764850 +0000
--- src/Make_vms.mms    2022-01-29 12:48:39.203668297 +0000
***************
*** 977,983 ****
  normal.obj : normal.c vim.h [.auto]config.h feature.h os_unix.h \
   ascii.h keymap.h termdefs.h macros.h structs.h regexp.h \
   gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \
!  errors.h globals.h
  ops.obj : ops.c vim.h [.auto]config.h feature.h os_unix.h   \
   ascii.h keymap.h termdefs.h macros.h structs.h regexp.h gui.h beval.h \
   [.proto]gui_beval.pro option.h ex_cmds.h proto.h errors.h globals.h
--- 977,983 ----
  normal.obj : normal.c vim.h [.auto]config.h feature.h os_unix.h \
   ascii.h keymap.h termdefs.h macros.h structs.h regexp.h \
   gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \
!  errors.h globals.h nv_cmdidxs.h
  ops.obj : ops.c vim.h [.auto]config.h feature.h os_unix.h   \
   ascii.h keymap.h termdefs.h macros.h structs.h regexp.h gui.h beval.h \
   [.proto]gui_beval.pro option.h ex_cmds.h proto.h errors.h globals.h
*** ../vim-8.2.4251/src/Makefile        2022-01-13 18:09:08.245764844 +0000
--- src/Makefile        2022-01-29 12:48:39.203668297 +0000
***************
*** 2144,2149 ****
--- 2144,2159 ----
  cmdidxs: ex_cmds.h
        vim --clean -X --not-a-term -u create_cmdidxs.vim
  
+ # Run vim script to generate the normal/visual mode command lookup table.
+ # This only needs to be run when a new normal/visual mode command has been
+ # added.  If this fails because you don't have Vim yet:
+ #   - change nv_cmds[] in normal.c to add the new normal/visual mode command.
+ #   - build Vim
+ #   - run "make nvcmdidxs" using the new Vim to generate nv_cmdidxs.h
+ #   - rebuild Vim to use the newly generated nv_cmdidxs.h file.
+ nvcmdidxs: normal.c
+       ./$(VIMTARGET) --clean -X --not-a-term -u create_nvcmdidxs.vim
+ 
  
  # The normal command to compile a .c file to its .o file.
  # Without or with ALL_CFLAGS.
***************
*** 4002,4008 ****
  objects/normal.o: normal.c vim.h protodef.h auto/config.h feature.h os_unix.h 
\
   auto/osdef.h ascii.h keymap.h termdefs.h macros.h option.h beval.h \
   proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
!  proto.h globals.h errors.h
  objects/ops.o: ops.c vim.h protodef.h auto/config.h feature.h os_unix.h \
   auto/osdef.h ascii.h keymap.h termdefs.h macros.h option.h beval.h \
   proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
--- 4012,4018 ----
  objects/normal.o: normal.c vim.h protodef.h auto/config.h feature.h os_unix.h 
\
   auto/osdef.h ascii.h keymap.h termdefs.h macros.h option.h beval.h \
   proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
!  proto.h globals.h errors.h nv_cmdidxs.h
  objects/ops.o: ops.c vim.h protodef.h auto/config.h feature.h os_unix.h \
   auto/osdef.h ascii.h keymap.h termdefs.h macros.h option.h beval.h \
   proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
*** ../vim-8.2.4251/src/create_nvcmdidxs.vim    2022-01-29 13:03:20.418637626 
+0000
--- src/create_nvcmdidxs.vim    2022-01-29 12:58:30.902875604 +0000
***************
*** 0 ****
--- 1,72 ----
+ vim9script
+ 
+ # This script generates the table nv_cmd_idx[] which contains the index in
+ # nv_cmds[] table (normal.c) for each of the command character supported in
+ # normal/visual mode.
+ # This is used to speed up the command lookup in nv_cmds[].
+ #
+ # Script should be run using "make nvcmdidxs", every time the nv_cmds[] table
+ # in src/normal.c changes.
+ 
+ def Create_nvcmdidxs_table()
+   var nv_cmdtbl: list<dict<number>> = []
+ 
+   # Generate the table of normal/visual mode command characters and their
+   # corresponding index.
+   var idx: number = 0
+   var ch: number
+   while true
+     ch = internal_get_nv_cmdchar(idx)
+     if ch == -1
+       break
+     endif
+     add(nv_cmdtbl, {idx: idx, cmdchar: ch})
+     idx += 1
+   endwhile
+ 
+   # sort the table by the command character
+   sort(nv_cmdtbl, (a, b) => a.cmdchar - b.cmdchar)
+ 
+   # Compute the highest index upto which the command character can be directly
+   # used as an index.
+   var nv_max_linear: number = 0
+   for i in range(nv_cmdtbl->len())
+     if i != nv_cmdtbl[i].cmdchar
+       nv_max_linear = i - 1
+       break
+     endif
+   endfor
+ 
+   # Generate a header file with the table
+   var output: list<string> =<< trim END
+     /*
+      * Automatically generated code by the create_nvcmdidxs.vim script.
+      *
+      * Table giving the index in nv_cmds[] to lookup based on
+      * the command character.
+      */
+ 
+     // nv_cmd_idx[<normal mode command character>] => nv_cmds[] index
+     static const unsigned short nv_cmd_idx[] =
+     {
+   END
+ 
+   # Add each command character in comment and the corresponding index
+   var tbl: list<string> = mapnew(nv_cmdtbl, (k, v) =>
+         '  /* ' .. printf('%5d', v.cmdchar) .. ' */ ' ..
+         printf('%3d', v.idx) .. ','
+     )
+   output += tbl
+ 
+   output += [ '};', '',
+               '// The highest index for which',
+               '// nv_cmds[idx].cmd_char == nv_cmd_idx[nv_cmds[idx].cmd_char]']
+   output += ['static const int nv_max_linear = ' .. nv_max_linear .. ';']
+ 
+   writefile(output, "nv_cmdidxs.h")
+ enddef
+ 
+ Create_nvcmdidxs_table()
+ quit
+ 
+ # vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.2.4251/src/evalfunc.c      2022-01-28 15:28:00.204927781 +0000
--- src/evalfunc.c      2022-01-29 12:48:39.203668297 +0000
***************
*** 1737,1742 ****
--- 1737,1744 ----
                        ret_string,         f_inputsecret},
      {"insert",                2, 3, FEARG_1,      arg23_insert,
                        ret_first_arg,      f_insert},
+     {"internal_get_nv_cmdchar",       1, 1, FEARG_1,    arg1_number,
+                       ret_number,         f_internal_get_nv_cmdchar},
      {"interrupt",     0, 0, 0,            NULL,
                        ret_void,           f_interrupt},
      {"invert",                1, 1, FEARG_1,      arg1_number,
*** ../vim-8.2.4251/src/main.c  2022-01-15 15:23:40.911170017 +0000
--- src/main.c  2022-01-29 12:48:39.203668297 +0000
***************
*** 901,909 ****
      qnx_init();               // PhAttach() for clipboard, (and gui)
  #endif
  
-     // Init the table of Normal mode commands.
-     init_normal_cmds();
- 
      /*
       * Allocate space for the generic buffers (needed for set_init_1() and
       * emsg()).
--- 901,906 ----
*** ../vim-8.2.4251/src/normal.c        2022-01-28 16:01:09.548028394 +0000
--- src/normal.c        2022-01-29 13:02:59.914937021 +0000
***************
*** 19,25 ****
  #ifdef FEAT_EVAL
  static void   set_vcount_ca(cmdarg_T *cap, int *set_prevcount);
  #endif
- static int    nv_compare(const void *s1, const void *s2);
  static void   unshift_special(cmdarg_T *cap);
  #ifdef FEAT_CMDL_INFO
  static void   del_from_showcmd(int);
--- 19,24 ----
***************
*** 128,133 ****
--- 127,160 ----
  #endif
  static void   nv_cursorhold(cmdarg_T *cap);
  
+ #ifdef FEAT_GUI
+ #define NV_VER_SCROLLBAR      nv_ver_scrollbar
+ #define NV_HOR_SCROLLBAR      nv_hor_scrollbar
+ #else
+ #define NV_VER_SCROLLBAR nv_error
+ #define NV_HOR_SCROLLBAR nv_error
+ #endif
+ 
+ #ifdef FEAT_GUI_TABLINE
+ #define NV_TABLINE    nv_tabline
+ #define NV_TABMENU    nv_tabmenu
+ #else
+ #define NV_TABLINE    nv_error
+ #define NV_TABMENU    nv_error
+ #endif
+ 
+ #ifdef FEAT_NETBEANS_INTG
+ #define NV_NBCMD      nv_nbcmd
+ #else
+ #define NV_NBCMD      nv_error
+ #endif
+ 
+ #ifdef FEAT_DND
+ #define NV_DROP               nv_drop
+ #else
+ #define NV_DROP               nv_error
+ #endif
+ 
  /*
   * Function to be called for a Normal or Visual mode command.
   * The argument is a cmdarg_T.
***************
*** 159,166 ****
  
  /*
   * This table contains one entry for every Normal or Visual mode command.
!  * The order doesn't matter, init_normal_cmds() will create a sorted index.
   * It is faster when all keys from zero to '~' are present.
   */
  static const struct nv_cmd
  {
--- 186,199 ----
  
  /*
   * This table contains one entry for every Normal or Visual mode command.
!  * The order doesn't matter, this will be sorted by the create_nvcmdidx.vim
!  * script to generate the nv_cmd_idx[] lookup table.
   * It is faster when all keys from zero to '~' are present.
+  *
+  * After changing the "nv_cmds" table:
+  * 1. Build Vim with "make"
+  * 2. Run "make nvcmdidxs" to re-generate the nv_cmdidxs.h file.
+  * 3. Build Vim with "make" to use the newly generated index table.
   */
  static const struct nv_cmd
  {
***************
*** 193,200 ****
      {Ctrl_T,  nv_tagpop,      NV_NCW,                 0},
      {Ctrl_U,  nv_halfpage,    0,                      0},
      {Ctrl_V,  nv_visual,      0,                      FALSE},
-     {'V',     nv_visual,      0,                      FALSE},
-     {'v',     nv_visual,      0,                      FALSE},
      {Ctrl_W,  nv_window,      0,                      0},
      {Ctrl_X,  nv_addsub,      0,                      0},
      {Ctrl_Y,  nv_scroll_line, 0,                      FALSE},
--- 226,231 ----
***************
*** 258,263 ****
--- 289,295 ----
      {'S',     nv_subst,       NV_KEEPREG,             0},
      {'T',     nv_csearch,     NV_NCH_ALW|NV_LANG,     BACKWARD},
      {'U',     nv_Undo,        0,                      0},
+     {'V',     nv_visual,      0,                      FALSE},
      {'W',     nv_wordcmd,     0,                      TRUE},
      {'X',     nv_abbrev,      NV_KEEPREG,             0},
      {'Y',     nv_abbrev,      NV_KEEPREG,             0},
***************
*** 289,294 ****
--- 321,327 ----
      {'s',     nv_subst,       NV_KEEPREG,             0},
      {'t',     nv_csearch,     NV_NCH_ALW|NV_LANG,     FORWARD},
      {'u',     nv_undo,        0,                      0},
+     {'v',     nv_visual,      0,                      FALSE},
      {'w',     nv_wordcmd,     0,                      FALSE},
      {'x',     nv_abbrev,      NV_KEEPREG,             0},
      {'y',     nv_operator,    0,                      0},
***************
*** 356,375 ****
      {K_F1,    nv_help,        NV_NCW,                 0},
      {K_XF1,   nv_help,        NV_NCW,                 0},
      {K_SELECT,        nv_select,      0,                      0},
! #ifdef FEAT_GUI
!     {K_VER_SCROLLBAR, nv_ver_scrollbar, 0,            0},
!     {K_HOR_SCROLLBAR, nv_hor_scrollbar, 0,            0},
! #endif
! #ifdef FEAT_GUI_TABLINE
!     {K_TABLINE, nv_tabline,   0,                      0},
!     {K_TABMENU, nv_tabmenu,   0,                      0},
! #endif
! #ifdef FEAT_NETBEANS_INTG
!     {K_F21,   nv_nbcmd,       NV_NCH_ALW,             0},
! #endif
! #ifdef FEAT_DND
!     {K_DROP,  nv_drop,        NV_STS,                 0},
! #endif
      {K_CURSORHOLD, nv_cursorhold, NV_KEEPREG,         0},
      {K_PS,    nv_edit,        0,                      0},
      {K_COMMAND,       nv_colon,       0,                      0},
--- 389,400 ----
      {K_F1,    nv_help,        NV_NCW,                 0},
      {K_XF1,   nv_help,        NV_NCW,                 0},
      {K_SELECT,        nv_select,      0,                      0},
!     {K_VER_SCROLLBAR, NV_VER_SCROLLBAR, 0,            0},
!     {K_HOR_SCROLLBAR, NV_HOR_SCROLLBAR, 0,            0},
!     {K_TABLINE, NV_TABLINE,   0,                      0},
!     {K_TABMENU, NV_TABMENU,   0,                      0},
!     {K_F21,   NV_NBCMD,       NV_NCH_ALW,             0},
!     {K_DROP,  NV_DROP,        NV_STS,                 0},
      {K_CURSORHOLD, nv_cursorhold, NV_KEEPREG,         0},
      {K_PS,    nv_edit,        0,                      0},
      {K_COMMAND,       nv_colon,       0,                      0},
***************
*** 379,433 ****
  // Number of commands in nv_cmds[].
  #define NV_CMDS_SIZE ARRAY_LENGTH(nv_cmds)
  
! #ifndef PROTO  // cproto doesn't like this
! // Sorted index of commands in nv_cmds[].
! static short nv_cmd_idx[NV_CMDS_SIZE];
! #endif
! 
! // The highest index for which
! // nv_cmds[idx].cmd_char == nv_cmd_idx[nv_cmds[idx].cmd_char]
! static int nv_max_linear;
  
  /*
!  * Compare functions for qsort() below, that checks the command character
!  * through the index in nv_cmd_idx[].
   */
!     static int
! nv_compare(const void *s1, const void *s2)
  {
!     int               c1, c2;
  
!     // The commands are sorted on absolute value.
!     c1 = nv_cmds[*(const short *)s1].cmd_char;
!     c2 = nv_cmds[*(const short *)s2].cmd_char;
!     if (c1 < 0)
!       c1 = -c1;
!     if (c2 < 0)
!       c2 = -c2;
!     return c1 - c2;
! }
  
! /*
!  * Initialize the nv_cmd_idx[] table.
!  */
!     void
! init_normal_cmds(void)
! {
!     int               i;
  
!     // Fill the index table with a one to one relation.
!     for (i = 0; i < (int)NV_CMDS_SIZE; ++i)
!       nv_cmd_idx[i] = i;
! 
!     // Sort the commands by the command character.
!     qsort((void *)&nv_cmd_idx, (size_t)NV_CMDS_SIZE, sizeof(short), 
nv_compare);
! 
!     // Find the first entry that can't be indexed by the command character.
!     for (i = 0; i < (int)NV_CMDS_SIZE; ++i)
!       if (i != nv_cmds[nv_cmd_idx[i]].cmd_char)
!           break;
!     nv_max_linear = i - 1;
  }
  
  /*
   * Search for a command in the commands table.
--- 404,445 ----
  // Number of commands in nv_cmds[].
  #define NV_CMDS_SIZE ARRAY_LENGTH(nv_cmds)
  
! // Include the lookuptable generated by create_nvcmdidx.vim.
! #include "nv_cmdidxs.h"
  
+ #if defined(FEAT_EVAL) || defined(PROTO)
  /*
!  * Return the command character for the given command index. This function is
!  * used to auto-generate nv_cmd_idx[].
   */
!     void
! f_internal_get_nv_cmdchar(typval_T *argvars, typval_T *rettv)
  {
!     int       idx;
!     int       cmd_char;
  
!     rettv->v_type = VAR_NUMBER;
!     rettv->vval.v_number = -1;
  
!     if (check_for_number_arg(argvars, 0) == FAIL)
!       return;
! 
!     idx = tv_get_number(&argvars[0]);
!     if (idx < 0 || idx >= (int)NV_CMDS_SIZE)
!       return;
  
!     cmd_char = nv_cmds[idx].cmd_char;
! 
!     // We use the absolute value of the character.  Special keys have a
!     // negative value, but are sorted on their absolute value.
!     if (cmd_char < 0)
!       cmd_char = -cmd_char;
! 
!     rettv->vval.v_number = cmd_char;
! 
!     return;
  }
+ #endif
  
  /*
   * Search for a command in the commands table.
*** ../vim-8.2.4251/src/nv_cmdidxs.h    2022-01-29 13:03:20.434637392 +0000
--- src/nv_cmdidxs.h    2022-01-29 12:54:05.798784932 +0000
***************
*** 0 ****
--- 1,209 ----
+ /*
+  * Automatically generated code by the create_nvcmdidxs.vim script.
+  *
+  * Table giving the index in nv_cmds[] to lookup based on
+  * the command character.
+  */
+ 
+ // nv_cmd_idx[<normal mode command character>] => nv_cmds[] index
+ static const unsigned short nv_cmd_idx[] =
+ {
+   /*     0 */   0,
+   /*     1 */   1,
+   /*     2 */   2,
+   /*     3 */   3,
+   /*     4 */   4,
+   /*     5 */   5,
+   /*     6 */   6,
+   /*     7 */   7,
+   /*     8 */   8,
+   /*     9 */   9,
+   /*    10 */  10,
+   /*    11 */  11,
+   /*    12 */  12,
+   /*    13 */  13,
+   /*    14 */  14,
+   /*    15 */  15,
+   /*    16 */  16,
+   /*    17 */  17,
+   /*    18 */  18,
+   /*    19 */  19,
+   /*    20 */  20,
+   /*    21 */  21,
+   /*    22 */  22,
+   /*    23 */  23,
+   /*    24 */  24,
+   /*    25 */  25,
+   /*    26 */  26,
+   /*    27 */  27,
+   /*    28 */  28,
+   /*    29 */  29,
+   /*    30 */  30,
+   /*    31 */  31,
+   /*    32 */  32,
+   /*    33 */  33,
+   /*    34 */  34,
+   /*    35 */  35,
+   /*    36 */  36,
+   /*    37 */  37,
+   /*    38 */  38,
+   /*    39 */  39,
+   /*    40 */  40,
+   /*    41 */  41,
+   /*    42 */  42,
+   /*    43 */  43,
+   /*    44 */  44,
+   /*    45 */  45,
+   /*    46 */  46,
+   /*    47 */  47,
+   /*    48 */  48,
+   /*    49 */  49,
+   /*    50 */  50,
+   /*    51 */  51,
+   /*    52 */  52,
+   /*    53 */  53,
+   /*    54 */  54,
+   /*    55 */  55,
+   /*    56 */  56,
+   /*    57 */  57,
+   /*    58 */  58,
+   /*    59 */  59,
+   /*    60 */  60,
+   /*    61 */  61,
+   /*    62 */  62,
+   /*    63 */  63,
+   /*    64 */  64,
+   /*    65 */  65,
+   /*    66 */  66,
+   /*    67 */  67,
+   /*    68 */  68,
+   /*    69 */  69,
+   /*    70 */  70,
+   /*    71 */  71,
+   /*    72 */  72,
+   /*    73 */  73,
+   /*    74 */  74,
+   /*    75 */  75,
+   /*    76 */  76,
+   /*    77 */  77,
+   /*    78 */  78,
+   /*    79 */  79,
+   /*    80 */  80,
+   /*    81 */  81,
+   /*    82 */  82,
+   /*    83 */  83,
+   /*    84 */  84,
+   /*    85 */  85,
+   /*    86 */  86,
+   /*    87 */  87,
+   /*    88 */  88,
+   /*    89 */  89,
+   /*    90 */  90,
+   /*    91 */  91,
+   /*    92 */  92,
+   /*    93 */  93,
+   /*    94 */  94,
+   /*    95 */  95,
+   /*    96 */  96,
+   /*    97 */  97,
+   /*    98 */  98,
+   /*    99 */  99,
+   /*   100 */ 100,
+   /*   101 */ 101,
+   /*   102 */ 102,
+   /*   103 */ 103,
+   /*   104 */ 104,
+   /*   105 */ 105,
+   /*   106 */ 106,
+   /*   107 */ 107,
+   /*   108 */ 108,
+   /*   109 */ 109,
+   /*   110 */ 110,
+   /*   111 */ 111,
+   /*   112 */ 112,
+   /*   113 */ 113,
+   /*   114 */ 114,
+   /*   115 */ 115,
+   /*   116 */ 116,
+   /*   117 */ 117,
+   /*   118 */ 118,
+   /*   119 */ 119,
+   /*   120 */ 120,
+   /*   121 */ 121,
+   /*   122 */ 122,
+   /*   123 */ 123,
+   /*   124 */ 124,
+   /*   125 */ 125,
+   /*   126 */ 126,
+   /*   163 */ 127,
+   /*  1277 */ 156,
+   /*  1533 */ 158,
+   /* 11517 */ 132,
+   /* 11773 */ 134,
+   /* 12029 */ 135,
+   /* 12285 */ 138,
+   /* 12541 */ 139,
+   /* 12581 */ 180,
+   /* 12619 */ 174,
+   /* 12651 */ 181,
+   /* 12797 */ 140,
+   /* 12835 */ 175,
+   /* 13053 */ 141,
+   /* 13131 */ 166,
+   /* 13309 */ 142,
+   /* 13347 */ 160,
+   /* 13387 */ 170,
+   /* 13565 */ 143,
+   /* 13643 */ 168,
+   /* 13821 */ 150,
+   /* 14122 */ 171,
+   /* 14144 */ 169,
+   /* 14374 */ 179,
+   /* 14845 */ 182,
+   /* 16966 */ 188,
+   /* 17515 */ 177,
+   /* 17917 */ 133,
+   /* 18173 */ 136,
+   /* 18795 */ 152,
+   /* 19453 */ 129,
+   /* 19709 */ 128,
+   /* 19965 */ 130,
+   /* 20075 */ 167,
+   /* 20221 */ 131,
+   /* 20477 */ 153,
+   /* 20587 */ 165,
+   /* 20733 */ 178,
+   /* 21328 */ 191,
+   /* 22013 */ 161,
+   /* 22269 */ 164,
+   /* 22525 */ 176,
+   /* 22767 */ 187,
+   /* 22768 */ 186,
+   /* 22773 */ 183,
+   /* 22776 */ 185,
+   /* 22777 */ 184,
+   /* 22781 */ 172,
+   /* 23037 */ 144,
+   /* 23293 */ 145,
+   /* 23549 */ 146,
+   /* 23805 */ 147,
+   /* 24061 */ 148,
+   /* 24317 */ 149,
+   /* 24573 */ 189,
+   /* 24829 */ 190,
+   /* 25085 */ 151,
+   /* 25195 */ 154,
+   /* 25707 */ 157,
+   /* 25853 */ 137,
+   /* 26621 */ 192,
+   /* 26731 */ 173,
+   /* 26877 */ 193,
+   /* 26917 */ 163,
+   /* 27755 */ 159,
+   /* 29291 */ 162,
+   /* 30059 */ 155,
+ };
+ 
+ // The highest index for which
+ // nv_cmds[idx].cmd_char == nv_cmd_idx[nv_cmds[idx].cmd_char]
+ static const int nv_max_linear = 126;
*** ../vim-8.2.4251/src/proto/normal.pro        2021-11-22 14:16:05.113603052 
+0000
--- src/proto/normal.pro        2022-01-29 12:48:39.207668237 +0000
***************
*** 1,5 ****
  /* normal.c */
! void init_normal_cmds(void);
  void normal_cmd(oparg_T *oap, int toplevel);
  void check_visual_highlight(void);
  void end_visual_mode(void);
--- 1,5 ----
  /* normal.c */
! void f_internal_get_nv_cmdchar(typval_T *argvars, typval_T *rettv);
  void normal_cmd(oparg_T *oap, int toplevel);
  void check_visual_highlight(void);
  void end_visual_mode(void);
*** ../vim-8.2.4251/src/version.c       2022-01-29 12:45:43.958338766 +0000
--- src/version.c       2022-01-29 12:50:54.497633415 +0000
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     4252,
  /**/

-- 
CART DRIVER: Bring out your dead!
LARGE MAN:   Here's one!
CART DRIVER: Ninepence.
BODY:        I'm not dead!
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// 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/20220129130719.8A2BF1C1918%40moolenaar.net.

Raspunde prin e-mail lui