Patch 8.2.4270
Problem:    Generating nv_cmdidxs.h requires building Vim twice.
Solution:   Move the table into a separate file and use a separate executable
            to extract the command characters. (Ozaki Kiichi, closes #9669)
Files:      src/normal.c, src/nv_cmds.h, 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.c,
            src/create_nvcmdidxs.vim, src/evalfunc.c, src/proto/normal.pro


*** ../vim-8.2.4269/src/normal.c        2022-01-29 13:06:19.340028690 +0000
--- src/normal.c        2022-01-31 12:19:59.489857182 +0000
***************
*** 1,6 ****
  /* vi:set ts=8 sts=4 sw=4 noet:
   *
!  * VIM - Vi IMproved  by Bram Moolenaar
   *
   * Do ":help uganda"  in Vim to read copying and usage conditions.
   * Do ":help credits" in Vim to see a list of people who contributed.
--- 1,6 ----
  /* vi:set ts=8 sts=4 sw=4 noet:
   *
!  * VIM - Vi IMproved  by Bram Moolenaar et al.
   *
   * Do ":help uganda"  in Vim to read copying and usage conditions.
   * Do ":help credits" in Vim to see a list of people who contributed.
***************
*** 127,446 ****
  #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.
!  */
! typedef void (*nv_func_T)(cmdarg_T *cap);
! 
! // Values for cmd_flags.
! #define NV_NCH            0x01          // may need to get a second char
! #define NV_NCH_NOP  (0x02|NV_NCH) // get second char when no operator pending
! #define NV_NCH_ALW  (0x04|NV_NCH) // always get a second char
! #define NV_LANG           0x08        // second char needs language adjustment
! 
! #define NV_SS     0x10        // may start selection
! #define NV_SSS            0x20        // may start selection with shift 
modifier
! #define NV_STS            0x40        // may stop selection without shift 
modif.
! #define NV_RL     0x80        // 'rightleft' modifies command
! #define NV_KEEPREG  0x100     // don't clear regname
! #define NV_NCW            0x200       // not allowed in command-line window
! 
! /*
!  * Generally speaking, every Normal mode command should either clear any
!  * pending operator (with *clearop*()), or set the motion type variable
!  * oap->motion_type.
!  *
!  * When a cursor motion command is made, it is marked as being a character or
!  * line oriented motion.  Then, if an operator is in effect, the operation
!  * becomes character or line oriented accordingly.
!  */
! 
! /*
!  * 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
! {
!     int               cmd_char;       // (first) command character
!     nv_func_T   cmd_func;     // function for this command
!     short_u   cmd_flags;      // NV_ flags
!     short     cmd_arg;        // value for ca.arg
! } nv_cmds[] =
! {
!     {NUL,     nv_error,       0,                      0},
!     {Ctrl_A,  nv_addsub,      0,                      0},
!     {Ctrl_B,  nv_page,        NV_STS,                 BACKWARD},
!     {Ctrl_C,  nv_esc,         0,                      TRUE},
!     {Ctrl_D,  nv_halfpage,    0,                      0},
!     {Ctrl_E,  nv_scroll_line, 0,                      TRUE},
!     {Ctrl_F,  nv_page,        NV_STS,                 FORWARD},
!     {Ctrl_G,  nv_ctrlg,       0,                      0},
!     {Ctrl_H,  nv_ctrlh,       0,                      0},
!     {Ctrl_I,  nv_pcmark,      0,                      0},
!     {NL,      nv_down,        0,                      FALSE},
!     {Ctrl_K,  nv_error,       0,                      0},
!     {Ctrl_L,  nv_clear,       0,                      0},
!     {CAR,     nv_down,        0,                      TRUE},
!     {Ctrl_N,  nv_down,        NV_STS,                 FALSE},
!     {Ctrl_O,  nv_ctrlo,       0,                      0},
!     {Ctrl_P,  nv_up,          NV_STS,                 FALSE},
!     {Ctrl_Q,  nv_visual,      0,                      FALSE},
!     {Ctrl_R,  nv_redo_or_register, 0,                 0},
!     {Ctrl_S,  nv_ignore,      0,                      0},
!     {Ctrl_T,  nv_tagpop,      NV_NCW,                 0},
!     {Ctrl_U,  nv_halfpage,    0,                      0},
!     {Ctrl_V,  nv_visual,      0,                      FALSE},
!     {Ctrl_W,  nv_window,      0,                      0},
!     {Ctrl_X,  nv_addsub,      0,                      0},
!     {Ctrl_Y,  nv_scroll_line, 0,                      FALSE},
!     {Ctrl_Z,  nv_suspend,     0,                      0},
!     {ESC,     nv_esc,         0,                      FALSE},
!     {Ctrl_BSL,        nv_normal,      NV_NCH_ALW,             0},
!     {Ctrl_RSB,        nv_ident,       NV_NCW,                 0},
!     {Ctrl_HAT,        nv_hat,         NV_NCW,                 0},
!     {Ctrl__,  nv_error,       0,                      0},
!     {' ',     nv_right,       0,                      0},
!     {'!',     nv_operator,    0,                      0},
!     {'"',     nv_regname,     NV_NCH_NOP|NV_KEEPREG,  0},
!     {'#',     nv_ident,       0,                      0},
!     {'$',     nv_dollar,      0,                      0},
!     {'%',     nv_percent,     0,                      0},
!     {'&',     nv_optrans,     0,                      0},
!     {'\'',    nv_gomark,      NV_NCH_ALW,             TRUE},
!     {'(',     nv_brace,       0,                      BACKWARD},
!     {')',     nv_brace,       0,                      FORWARD},
!     {'*',     nv_ident,       0,                      0},
!     {'+',     nv_down,        0,                      TRUE},
!     {',',     nv_csearch,     0,                      TRUE},
!     {'-',     nv_up,          0,                      TRUE},
!     {'.',     nv_dot,         NV_KEEPREG,             0},
!     {'/',     nv_search,      0,                      FALSE},
!     {'0',     nv_beginline,   0,                      0},
!     {'1',     nv_ignore,      0,                      0},
!     {'2',     nv_ignore,      0,                      0},
!     {'3',     nv_ignore,      0,                      0},
!     {'4',     nv_ignore,      0,                      0},
!     {'5',     nv_ignore,      0,                      0},
!     {'6',     nv_ignore,      0,                      0},
!     {'7',     nv_ignore,      0,                      0},
!     {'8',     nv_ignore,      0,                      0},
!     {'9',     nv_ignore,      0,                      0},
!     {':',     nv_colon,       0,                      0},
!     {';',     nv_csearch,     0,                      FALSE},
!     {'<',     nv_operator,    NV_RL,                  0},
!     {'=',     nv_operator,    0,                      0},
!     {'>',     nv_operator,    NV_RL,                  0},
!     {'?',     nv_search,      0,                      FALSE},
!     {'@',     nv_at,          NV_NCH_NOP,             FALSE},
!     {'A',     nv_edit,        0,                      0},
!     {'B',     nv_bck_word,    0,                      1},
!     {'C',     nv_abbrev,      NV_KEEPREG,             0},
!     {'D',     nv_abbrev,      NV_KEEPREG,             0},
!     {'E',     nv_wordcmd,     0,                      TRUE},
!     {'F',     nv_csearch,     NV_NCH_ALW|NV_LANG,     BACKWARD},
!     {'G',     nv_goto,        0,                      TRUE},
!     {'H',     nv_scroll,      0,                      0},
!     {'I',     nv_edit,        0,                      0},
!     {'J',     nv_join,        0,                      0},
!     {'K',     nv_ident,       0,                      0},
!     {'L',     nv_scroll,      0,                      0},
!     {'M',     nv_scroll,      0,                      0},
!     {'N',     nv_next,        0,                      SEARCH_REV},
!     {'O',     nv_open,        0,                      0},
!     {'P',     nv_put,         0,                      0},
!     {'Q',     nv_exmode,      NV_NCW,                 0},
!     {'R',     nv_Replace,     0,                      FALSE},
!     {'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},
!     {'Z',     nv_Zet,         NV_NCH_NOP|NV_NCW,      0},
!     {'[',     nv_brackets,    NV_NCH_ALW,             BACKWARD},
!     {'\\',    nv_error,       0,                      0},
!     {']',     nv_brackets,    NV_NCH_ALW,             FORWARD},
!     {'^',     nv_beginline,   0,                      BL_WHITE | BL_FIX},
!     {'_',     nv_lineop,      0,                      0},
!     {'`',     nv_gomark,      NV_NCH_ALW,             FALSE},
!     {'a',     nv_edit,        NV_NCH,                 0},
!     {'b',     nv_bck_word,    0,                      0},
!     {'c',     nv_operator,    0,                      0},
!     {'d',     nv_operator,    0,                      0},
!     {'e',     nv_wordcmd,     0,                      FALSE},
!     {'f',     nv_csearch,     NV_NCH_ALW|NV_LANG,     FORWARD},
!     {'g',     nv_g_cmd,       NV_NCH_ALW,             FALSE},
!     {'h',     nv_left,        NV_RL,                  0},
!     {'i',     nv_edit,        NV_NCH,                 0},
!     {'j',     nv_down,        0,                      FALSE},
!     {'k',     nv_up,          0,                      FALSE},
!     {'l',     nv_right,       NV_RL,                  0},
!     {'m',     nv_mark,        NV_NCH_NOP,             0},
!     {'n',     nv_next,        0,                      0},
!     {'o',     nv_open,        0,                      0},
!     {'p',     nv_put,         0,                      0},
!     {'q',     nv_record,      NV_NCH,                 0},
!     {'r',     nv_replace,     NV_NCH_NOP|NV_LANG,     0},
!     {'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},
!     {'z',     nv_zet,         NV_NCH_ALW,             0},
!     {'{',     nv_findpar,     0,                      BACKWARD},
!     {'|',     nv_pipe,        0,                      0},
!     {'}',     nv_findpar,     0,                      FORWARD},
!     {'~',     nv_tilde,       0,                      0},
! 
!     // pound sign
!     {POUND,   nv_ident,       0,                      0},
!     {K_MOUSEUP, nv_mousescroll,       0,                      MSCR_UP},
!     {K_MOUSEDOWN, nv_mousescroll, 0,                  MSCR_DOWN},
!     {K_MOUSELEFT, nv_mousescroll, 0,                  MSCR_LEFT},
!     {K_MOUSERIGHT, nv_mousescroll, 0,                 MSCR_RIGHT},
!     {K_LEFTMOUSE, nv_mouse,   0,                      0},
!     {K_LEFTMOUSE_NM, nv_mouse,        0,                      0},
!     {K_LEFTDRAG, nv_mouse,    0,                      0},
!     {K_LEFTRELEASE, nv_mouse, 0,                      0},
!     {K_LEFTRELEASE_NM, nv_mouse, 0,                   0},
!     {K_MOUSEMOVE, nv_mouse,   0,                      0},
!     {K_MIDDLEMOUSE, nv_mouse, 0,                      0},
!     {K_MIDDLEDRAG, nv_mouse,  0,                      0},
!     {K_MIDDLERELEASE, nv_mouse,       0,                      0},
!     {K_RIGHTMOUSE, nv_mouse,  0,                      0},
!     {K_RIGHTDRAG, nv_mouse,   0,                      0},
!     {K_RIGHTRELEASE, nv_mouse,        0,                      0},
!     {K_X1MOUSE, nv_mouse,     0,                      0},
!     {K_X1DRAG, nv_mouse,      0,                      0},
!     {K_X1RELEASE, nv_mouse,   0,                      0},
!     {K_X2MOUSE, nv_mouse,     0,                      0},
!     {K_X2DRAG, nv_mouse,      0,                      0},
!     {K_X2RELEASE, nv_mouse,   0,                      0},
!     {K_IGNORE,        nv_ignore,      NV_KEEPREG,             0},
!     {K_NOP,   nv_nop,         0,                      0},
!     {K_INS,   nv_edit,        0,                      0},
!     {K_KINS,  nv_edit,        0,                      0},
!     {K_BS,    nv_ctrlh,       0,                      0},
!     {K_UP,    nv_up,          NV_SSS|NV_STS,          FALSE},
!     {K_S_UP,  nv_page,        NV_SS,                  BACKWARD},
!     {K_DOWN,  nv_down,        NV_SSS|NV_STS,          FALSE},
!     {K_S_DOWN,        nv_page,        NV_SS,                  FORWARD},
!     {K_LEFT,  nv_left,        NV_SSS|NV_STS|NV_RL,    0},
!     {K_S_LEFT,        nv_bck_word,    NV_SS|NV_RL,            0},
!     {K_C_LEFT,        nv_bck_word,    NV_SSS|NV_RL|NV_STS,    1},
!     {K_RIGHT, nv_right,       NV_SSS|NV_STS|NV_RL,    0},
!     {K_S_RIGHT,       nv_wordcmd,     NV_SS|NV_RL,            FALSE},
!     {K_C_RIGHT,       nv_wordcmd,     NV_SSS|NV_RL|NV_STS,    TRUE},
!     {K_PAGEUP,        nv_page,        NV_SSS|NV_STS,          BACKWARD},
!     {K_KPAGEUP,       nv_page,        NV_SSS|NV_STS,          BACKWARD},
!     {K_PAGEDOWN, nv_page,     NV_SSS|NV_STS,          FORWARD},
!     {K_KPAGEDOWN, nv_page,    NV_SSS|NV_STS,          FORWARD},
!     {K_END,   nv_end,         NV_SSS|NV_STS,          FALSE},
!     {K_KEND,  nv_end,         NV_SSS|NV_STS,          FALSE},
!     {K_S_END, nv_end,         NV_SS,                  FALSE},
!     {K_C_END, nv_end,         NV_SSS|NV_STS,          TRUE},
!     {K_HOME,  nv_home,        NV_SSS|NV_STS,          0},
!     {K_KHOME, nv_home,        NV_SSS|NV_STS,          0},
!     {K_S_HOME,        nv_home,        NV_SS,                  0},
!     {K_C_HOME,        nv_goto,        NV_SSS|NV_STS,          FALSE},
!     {K_DEL,   nv_abbrev,      0,                      0},
!     {K_KDEL,  nv_abbrev,      0,                      0},
!     {K_UNDO,  nv_kundo,       0,                      0},
!     {K_HELP,  nv_help,        NV_NCW,                 0},
!     {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},
!     {K_SCRIPT_COMMAND, nv_colon, 0,                   0},
! };
! 
! // 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.
   * Returns -1 for invalid command.
--- 127,139 ----
  #endif
  static void   nv_cursorhold(cmdarg_T *cap);
  
! // Declare nv_cmds[].
! #define DO_DECLARE_NVCMD
! #include "nv_cmds.h"
  
  // Include the lookuptable generated by create_nvcmdidx.vim.
  #include "nv_cmdidxs.h"
  
  /*
   * Search for a command in the commands table.
   * Returns -1 for invalid command.
*** ../vim-8.2.4269/src/nv_cmds.h       2022-01-31 12:24:26.109841007 +0000
--- src/nv_cmds.h       2022-01-31 12:09:54.346982071 +0000
***************
*** 0 ****
--- 1,310 ----
+ /* vi:set ts=8 sts=4 sw=4 noet:
+  *
+  * VIM - Vi IMproved  by Bram Moolenaar et al.
+  *
+  * Do ":help uganda"  in Vim to read copying and usage conditions.
+  * Do ":help credits" in Vim to see a list of people who contributed.
+  * See README.txt for an overview of the Vim source code.
+  */
+ /*
+  * This file defines the Normal mode commands.
+  */
+ 
+ /*
+  * When adding a Normal/Visual mode command:
+  * 1. Add an entry in the table `nv_cmds[]` below.
+  * 2. Run "make nvcmdidxs" to re-generate nv_cmdidxs.h.
+  * 3. Add an entry in the index for Normal/Visual commands at
+  *    ":help normal-index" and ":help visual-index" .
+  * 4. Add documentation in ../doc/xxx.txt.  Add a tag for both the short and
+  *    long name of the command.
+  */
+ 
+ #ifdef DO_DECLARE_NVCMD
+ 
+ /*
+  * Used when building Vim.
+  */
+ # define NVCMD(a, b, c, d)  {a, b, c, d}
+ 
+ #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.
+  */
+ typedef void (*nv_func_T)(cmdarg_T *cap);
+ 
+ // Values for cmd_flags.
+ #define NV_NCH            0x01          // may need to get a second char
+ #define NV_NCH_NOP  (0x02|NV_NCH) // get second char when no operator pending
+ #define NV_NCH_ALW  (0x04|NV_NCH) // always get a second char
+ #define NV_LANG           0x08        // second char needs language adjustment
+ 
+ #define NV_SS     0x10        // may start selection
+ #define NV_SSS            0x20        // may start selection with shift 
modifier
+ #define NV_STS            0x40        // may stop selection without shift 
modif.
+ #define NV_RL     0x80        // 'rightleft' modifies command
+ #define NV_KEEPREG  0x100     // don't clear regname
+ #define NV_NCW            0x200       // not allowed in command-line window
+ 
+ /*
+  * Generally speaking, every Normal mode command should either clear any
+  * pending operator (with *clearop*()), or set the motion type variable
+  * oap->motion_type.
+  *
+  * When a cursor motion command is made, it is marked as being a character or
+  * line oriented motion.  Then, if an operator is in effect, the operation
+  * becomes character or line oriented accordingly.
+  */
+ 
+ /*
+  * 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.
+  */
+ static const struct nv_cmd
+ {
+     int               cmd_char;       // (first) command character
+     nv_func_T   cmd_func;     // function for this command
+     short_u   cmd_flags;      // NV_ flags
+     short     cmd_arg;        // value for ca.arg
+ } nv_cmds[] =
+ 
+ #else  // DO_DECLARE_NVCMD
+ 
+ /*
+  * Used when creating nv_cmdidxs.h.
+  */
+ # define NVCMD(a, b, c, d)  a
+ static const int nv_cmds[] =
+ 
+ #endif // DO_DECLARE_NVCMD
+ {
+     NVCMD(NUL,                nv_error,       0,                      0),
+     NVCMD(Ctrl_A,     nv_addsub,      0,                      0),
+     NVCMD(Ctrl_B,     nv_page,        NV_STS,                 BACKWARD),
+     NVCMD(Ctrl_C,     nv_esc,         0,                      TRUE),
+     NVCMD(Ctrl_D,     nv_halfpage,    0,                      0),
+     NVCMD(Ctrl_E,     nv_scroll_line, 0,                      TRUE),
+     NVCMD(Ctrl_F,     nv_page,        NV_STS,                 FORWARD),
+     NVCMD(Ctrl_G,     nv_ctrlg,       0,                      0),
+     NVCMD(Ctrl_H,     nv_ctrlh,       0,                      0),
+     NVCMD(Ctrl_I,     nv_pcmark,      0,                      0),
+     NVCMD(NL,         nv_down,        0,                      FALSE),
+     NVCMD(Ctrl_K,     nv_error,       0,                      0),
+     NVCMD(Ctrl_L,     nv_clear,       0,                      0),
+     NVCMD(CAR,                nv_down,        0,                      TRUE),
+     NVCMD(Ctrl_N,     nv_down,        NV_STS,                 FALSE),
+     NVCMD(Ctrl_O,     nv_ctrlo,       0,                      0),
+     NVCMD(Ctrl_P,     nv_up,          NV_STS,                 FALSE),
+     NVCMD(Ctrl_Q,     nv_visual,      0,                      FALSE),
+     NVCMD(Ctrl_R,     nv_redo_or_register, 0,                 0),
+     NVCMD(Ctrl_S,     nv_ignore,      0,                      0),
+     NVCMD(Ctrl_T,     nv_tagpop,      NV_NCW,                 0),
+     NVCMD(Ctrl_U,     nv_halfpage,    0,                      0),
+     NVCMD(Ctrl_V,     nv_visual,      0,                      FALSE),
+     NVCMD(Ctrl_W,     nv_window,      0,                      0),
+     NVCMD(Ctrl_X,     nv_addsub,      0,                      0),
+     NVCMD(Ctrl_Y,     nv_scroll_line, 0,                      FALSE),
+     NVCMD(Ctrl_Z,     nv_suspend,     0,                      0),
+     NVCMD(ESC,                nv_esc,         0,                      FALSE),
+     NVCMD(Ctrl_BSL,   nv_normal,      NV_NCH_ALW,             0),
+     NVCMD(Ctrl_RSB,   nv_ident,       NV_NCW,                 0),
+     NVCMD(Ctrl_HAT,   nv_hat,         NV_NCW,                 0),
+     NVCMD(Ctrl__,     nv_error,       0,                      0),
+     NVCMD(' ',                nv_right,       0,                      0),
+     NVCMD('!',                nv_operator,    0,                      0),
+     NVCMD('"',                nv_regname,     NV_NCH_NOP|NV_KEEPREG,  0),
+     NVCMD('#',                nv_ident,       0,                      0),
+     NVCMD('$',                nv_dollar,      0,                      0),
+     NVCMD('%',                nv_percent,     0,                      0),
+     NVCMD('&',                nv_optrans,     0,                      0),
+     NVCMD('\'',               nv_gomark,      NV_NCH_ALW,             TRUE),
+     NVCMD('(',                nv_brace,       0,                      
BACKWARD),
+     NVCMD(')',                nv_brace,       0,                      
FORWARD),
+     NVCMD('*',                nv_ident,       0,                      0),
+     NVCMD('+',                nv_down,        0,                      TRUE),
+     NVCMD(',',                nv_csearch,     0,                      TRUE),
+     NVCMD('-',                nv_up,          0,                      TRUE),
+     NVCMD('.',                nv_dot,         NV_KEEPREG,             0),
+     NVCMD('/',                nv_search,      0,                      FALSE),
+     NVCMD('0',                nv_beginline,   0,                      0),
+     NVCMD('1',                nv_ignore,      0,                      0),
+     NVCMD('2',                nv_ignore,      0,                      0),
+     NVCMD('3',                nv_ignore,      0,                      0),
+     NVCMD('4',                nv_ignore,      0,                      0),
+     NVCMD('5',                nv_ignore,      0,                      0),
+     NVCMD('6',                nv_ignore,      0,                      0),
+     NVCMD('7',                nv_ignore,      0,                      0),
+     NVCMD('8',                nv_ignore,      0,                      0),
+     NVCMD('9',                nv_ignore,      0,                      0),
+     NVCMD(':',                nv_colon,       0,                      0),
+     NVCMD(';',                nv_csearch,     0,                      FALSE),
+     NVCMD('<',                nv_operator,    NV_RL,                  0),
+     NVCMD('=',                nv_operator,    0,                      0),
+     NVCMD('>',                nv_operator,    NV_RL,                  0),
+     NVCMD('?',                nv_search,      0,                      FALSE),
+     NVCMD('@',                nv_at,          NV_NCH_NOP,             FALSE),
+     NVCMD('A',                nv_edit,        0,                      0),
+     NVCMD('B',                nv_bck_word,    0,                      1),
+     NVCMD('C',                nv_abbrev,      NV_KEEPREG,             0),
+     NVCMD('D',                nv_abbrev,      NV_KEEPREG,             0),
+     NVCMD('E',                nv_wordcmd,     0,                      TRUE),
+     NVCMD('F',                nv_csearch,     NV_NCH_ALW|NV_LANG,     
BACKWARD),
+     NVCMD('G',                nv_goto,        0,                      TRUE),
+     NVCMD('H',                nv_scroll,      0,                      0),
+     NVCMD('I',                nv_edit,        0,                      0),
+     NVCMD('J',                nv_join,        0,                      0),
+     NVCMD('K',                nv_ident,       0,                      0),
+     NVCMD('L',                nv_scroll,      0,                      0),
+     NVCMD('M',                nv_scroll,      0,                      0),
+     NVCMD('N',                nv_next,        0,                      
SEARCH_REV),
+     NVCMD('O',                nv_open,        0,                      0),
+     NVCMD('P',                nv_put,         0,                      0),
+     NVCMD('Q',                nv_exmode,      NV_NCW,                 0),
+     NVCMD('R',                nv_Replace,     0,                      FALSE),
+     NVCMD('S',                nv_subst,       NV_KEEPREG,             0),
+     NVCMD('T',                nv_csearch,     NV_NCH_ALW|NV_LANG,     
BACKWARD),
+     NVCMD('U',                nv_Undo,        0,                      0),
+     NVCMD('V',                nv_visual,      0,                      FALSE),
+     NVCMD('W',                nv_wordcmd,     0,                      TRUE),
+     NVCMD('X',                nv_abbrev,      NV_KEEPREG,             0),
+     NVCMD('Y',                nv_abbrev,      NV_KEEPREG,             0),
+     NVCMD('Z',                nv_Zet,         NV_NCH_NOP|NV_NCW,      0),
+     NVCMD('[',                nv_brackets,    NV_NCH_ALW,             
BACKWARD),
+     NVCMD('\\',               nv_error,       0,                      0),
+     NVCMD(']',                nv_brackets,    NV_NCH_ALW,             
FORWARD),
+     NVCMD('^',                nv_beginline,   0,                  BL_WHITE | 
BL_FIX),
+     NVCMD('_',                nv_lineop,      0,                      0),
+     NVCMD('`',                nv_gomark,      NV_NCH_ALW,             FALSE),
+     NVCMD('a',                nv_edit,        NV_NCH,                 0),
+     NVCMD('b',                nv_bck_word,    0,                      0),
+     NVCMD('c',                nv_operator,    0,                      0),
+     NVCMD('d',                nv_operator,    0,                      0),
+     NVCMD('e',                nv_wordcmd,     0,                      FALSE),
+     NVCMD('f',                nv_csearch,     NV_NCH_ALW|NV_LANG,     
FORWARD),
+     NVCMD('g',                nv_g_cmd,       NV_NCH_ALW,             FALSE),
+     NVCMD('h',                nv_left,        NV_RL,                  0),
+     NVCMD('i',                nv_edit,        NV_NCH,                 0),
+     NVCMD('j',                nv_down,        0,                      FALSE),
+     NVCMD('k',                nv_up,          0,                      FALSE),
+     NVCMD('l',                nv_right,       NV_RL,                  0),
+     NVCMD('m',                nv_mark,        NV_NCH_NOP,             0),
+     NVCMD('n',                nv_next,        0,                      0),
+     NVCMD('o',                nv_open,        0,                      0),
+     NVCMD('p',                nv_put,         0,                      0),
+     NVCMD('q',                nv_record,      NV_NCH,                 0),
+     NVCMD('r',                nv_replace,     NV_NCH_NOP|NV_LANG,     0),
+     NVCMD('s',                nv_subst,       NV_KEEPREG,             0),
+     NVCMD('t',                nv_csearch,     NV_NCH_ALW|NV_LANG,     
FORWARD),
+     NVCMD('u',                nv_undo,        0,                      0),
+     NVCMD('v',                nv_visual,      0,                      FALSE),
+     NVCMD('w',                nv_wordcmd,     0,                      FALSE),
+     NVCMD('x',                nv_abbrev,      NV_KEEPREG,             0),
+     NVCMD('y',                nv_operator,    0,                      0),
+     NVCMD('z',                nv_zet,         NV_NCH_ALW,             0),
+     NVCMD('{',                nv_findpar,     0,                      
BACKWARD),
+     NVCMD('|',                nv_pipe,        0,                      0),
+     NVCMD('}',                nv_findpar,     0,                      
FORWARD),
+     NVCMD('~',                nv_tilde,       0,                      0),
+ 
+     // pound sign
+     NVCMD(POUND,      nv_ident,       0,                      0),
+     NVCMD(K_MOUSEUP,  nv_mousescroll, 0,                      MSCR_UP),
+     NVCMD(K_MOUSEDOWN,        nv_mousescroll, 0,                      
MSCR_DOWN),
+     NVCMD(K_MOUSELEFT,        nv_mousescroll, 0,                      
MSCR_LEFT),
+     NVCMD(K_MOUSERIGHT, nv_mousescroll, 0,                    MSCR_RIGHT),
+     NVCMD(K_LEFTMOUSE,        nv_mouse,       0,                      0),
+     NVCMD(K_LEFTMOUSE_NM, nv_mouse,   0,                      0),
+     NVCMD(K_LEFTDRAG, nv_mouse,       0,                      0),
+     NVCMD(K_LEFTRELEASE, nv_mouse,    0,                      0),
+     NVCMD(K_LEFTRELEASE_NM, nv_mouse, 0,                      0),
+     NVCMD(K_MOUSEMOVE,        nv_mouse,       0,                      0),
+     NVCMD(K_MIDDLEMOUSE, nv_mouse,    0,                      0),
+     NVCMD(K_MIDDLEDRAG, nv_mouse,     0,                      0),
+     NVCMD(K_MIDDLERELEASE, nv_mouse,  0,                      0),
+     NVCMD(K_RIGHTMOUSE, nv_mouse,     0,                      0),
+     NVCMD(K_RIGHTDRAG,        nv_mouse,       0,                      0),
+     NVCMD(K_RIGHTRELEASE, nv_mouse,   0,                      0),
+     NVCMD(K_X1MOUSE,  nv_mouse,       0,                      0),
+     NVCMD(K_X1DRAG,   nv_mouse,       0,                      0),
+     NVCMD(K_X1RELEASE,        nv_mouse,       0,                      0),
+     NVCMD(K_X2MOUSE,  nv_mouse,       0,                      0),
+     NVCMD(K_X2DRAG,   nv_mouse,       0,                      0),
+     NVCMD(K_X2RELEASE,        nv_mouse,       0,                      0),
+     NVCMD(K_IGNORE,   nv_ignore,      NV_KEEPREG,             0),
+     NVCMD(K_NOP,      nv_nop,         0,                      0),
+     NVCMD(K_INS,      nv_edit,        0,                      0),
+     NVCMD(K_KINS,     nv_edit,        0,                      0),
+     NVCMD(K_BS,               nv_ctrlh,       0,                      0),
+     NVCMD(K_UP,               nv_up,          NV_SSS|NV_STS,          FALSE),
+     NVCMD(K_S_UP,     nv_page,        NV_SS,                  BACKWARD),
+     NVCMD(K_DOWN,     nv_down,        NV_SSS|NV_STS,          FALSE),
+     NVCMD(K_S_DOWN,   nv_page,        NV_SS,                  FORWARD),
+     NVCMD(K_LEFT,     nv_left,        NV_SSS|NV_STS|NV_RL,    0),
+     NVCMD(K_S_LEFT,   nv_bck_word,    NV_SS|NV_RL,            0),
+     NVCMD(K_C_LEFT,   nv_bck_word,    NV_SSS|NV_RL|NV_STS,    1),
+     NVCMD(K_RIGHT,    nv_right,       NV_SSS|NV_STS|NV_RL,    0),
+     NVCMD(K_S_RIGHT,  nv_wordcmd,     NV_SS|NV_RL,            FALSE),
+     NVCMD(K_C_RIGHT,  nv_wordcmd,     NV_SSS|NV_RL|NV_STS,    TRUE),
+     NVCMD(K_PAGEUP,   nv_page,        NV_SSS|NV_STS,          BACKWARD),
+     NVCMD(K_KPAGEUP,  nv_page,        NV_SSS|NV_STS,          BACKWARD),
+     NVCMD(K_PAGEDOWN, nv_page,        NV_SSS|NV_STS,          FORWARD),
+     NVCMD(K_KPAGEDOWN,        nv_page,        NV_SSS|NV_STS,          
FORWARD),
+     NVCMD(K_END,      nv_end,         NV_SSS|NV_STS,          FALSE),
+     NVCMD(K_KEND,     nv_end,         NV_SSS|NV_STS,          FALSE),
+     NVCMD(K_S_END,    nv_end,         NV_SS,                  FALSE),
+     NVCMD(K_C_END,    nv_end,         NV_SSS|NV_STS,          TRUE),
+     NVCMD(K_HOME,     nv_home,        NV_SSS|NV_STS,          0),
+     NVCMD(K_KHOME,    nv_home,        NV_SSS|NV_STS,          0),
+     NVCMD(K_S_HOME,   nv_home,        NV_SS,                  0),
+     NVCMD(K_C_HOME,   nv_goto,        NV_SSS|NV_STS,          FALSE),
+     NVCMD(K_DEL,      nv_abbrev,      0,                      0),
+     NVCMD(K_KDEL,     nv_abbrev,      0,                      0),
+     NVCMD(K_UNDO,     nv_kundo,       0,                      0),
+     NVCMD(K_HELP,     nv_help,        NV_NCW,                 0),
+     NVCMD(K_F1,               nv_help,        NV_NCW,                 0),
+     NVCMD(K_XF1,      nv_help,        NV_NCW,                 0),
+     NVCMD(K_SELECT,   nv_select,      0,                      0),
+     NVCMD(K_VER_SCROLLBAR, NV_VER_SCROLLBAR, 0,                       0),
+     NVCMD(K_HOR_SCROLLBAR, NV_HOR_SCROLLBAR, 0,                       0),
+     NVCMD(K_TABLINE,  NV_TABLINE,     0,                      0),
+     NVCMD(K_TABMENU,  NV_TABMENU,     0,                      0),
+     NVCMD(K_F21,      NV_NBCMD,       NV_NCH_ALW,             0),
+     NVCMD(K_DROP,     NV_DROP,        NV_STS,                 0),
+     NVCMD(K_CURSORHOLD, nv_cursorhold,        NV_KEEPREG,             0),
+     NVCMD(K_PS,               nv_edit,        0,                      0),
+     NVCMD(K_COMMAND,  nv_colon,       0,                      0),
+     NVCMD(K_SCRIPT_COMMAND, nv_colon, 0,                      0),
+ };
+ 
+ // Number of commands in nv_cmds[].
+ #define NV_CMDS_SIZE ARRAY_LENGTH(nv_cmds)
*** ../vim-8.2.4269/Filelist    2022-01-29 13:06:19.336028749 +0000
--- Filelist    2022-01-31 11:59:27.092480128 +0000
***************
*** 114,119 ****
--- 114,120 ----
                src/netbeans.c \
                src/normal.c \
                src/nv_cmdidxs.h \
+               src/nv_cmds.h \
                src/ops.c \
                src/option.c \
                src/option.h \
***************
*** 444,449 ****
--- 445,451 ----
                src/configure \
                src/configure.ac \
                src/create_cmdidxs.vim \
+               src/create_nvcmdidxs.c \
                src/create_nvcmdidxs.vim \
                src/gui_at_fs.c \
                src/gui_at_sb.c \
*** ../vim-8.2.4269/runtime/doc/builtin.txt     2022-01-30 12:36:48.728985579 
+0000
--- runtime/doc/builtin.txt     2022-01-31 11:59:27.092480128 +0000
***************
*** 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
--- 292,297 ----
***************
*** 4613,4623 ****
  
                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
--- 4617,4622 ----
*** ../vim-8.2.4269/runtime/doc/usr_41.txt      2022-01-30 12:36:48.732985521 
+0000
--- runtime/doc/usr_41.txt      2022-01-31 11:59:27.092480128 +0000
***************
*** 1019,1025 ****
        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
--- 1110,1115 ----
*** ../vim-8.2.4269/src/Make_cyg_ming.mak       2022-01-29 13:06:19.336028749 
+0000
--- src/Make_cyg_ming.mak       2022-01-31 11:59:27.092480128 +0000
***************
*** 1145,1161 ****
  # If this fails because you don't have Vim yet, first build and install Vim
  # without changes.
  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 \
--- 1145,1161 ----
  # If this fails because you don't have Vim yet, first build and install Vim
  # without changes.
  cmdidxs: ex_cmds.h
!       vim --clean -N -X --not-a-term -u create_cmdidxs.vim -c quit
  
  # 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 nv_cmds.h to add the new normal/visual mode command.
! #   - run "make nvcmdidxs" to generate nv_cmdidxs.h
! nvcmdidxs: nv_cmds.h
!       $(CC) $(CFLAGS) -o create_nvcmdidxs.exe create_nvcmdidxs.c $(LIB)
!       vim --clean -N -X --not-a-term -u create_nvcmdidxs.vim -c quit
!       -$(DEL) create_nvcmdidxs.exe
  
  ###########################################################################
  INCL =        vim.h alloc.h ascii.h ex_cmds.h feature.h errors.h globals.h \
***************
*** 1219,1225 ****
  
  $(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
  
--- 1219,1225 ----
  
  $(OUTDIR)/misc1.o: misc1.c $(INCL) version.h
  
! $(OUTDIR)/normal.o: normal.c $(INCL) nv_cmdidxs.h nv_cmds.h
  
  $(OUTDIR)/netbeans.o: netbeans.c $(INCL) version.h
  
*** ../vim-8.2.4269/src/Make_mvc.mak    2022-01-29 13:06:19.336028749 +0000
--- src/Make_mvc.mak    2022-01-31 11:59:27.092480128 +0000
***************
*** 1444,1460 ****
  # If this fails because you don't have Vim yet, first build and install Vim
  # without changes.
  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
--- 1444,1460 ----
  # If this fails because you don't have Vim yet, first build and install Vim
  # without changes.
  cmdidxs: ex_cmds.h
!       vim --clean -N -X --not-a-term -u create_cmdidxs.vim -c quit
  
  # 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 nv_cmds.h to add the new normal/visual mode command.
! #   - run "make nvcmdidxs" to generate nv_cmdidxs.h
! nvcmdidxs: nv_cmds.h
!       $(CC) /nologo -I. -Iproto -DNDEBUG create_nvcmdidxs.c -link 
-subsystem:$(SUBSYSTEM_TOOLS)
!       vim --clean -N -X --not-a-term -u create_nvcmdidxs.vim -c quit
!       -del create_nvcmdidxs.exe
  
  test:
        cd testdir
***************
*** 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
  
--- 1719,1725 ----
  
  $(OUTDIR)/channel.obj:        $(OUTDIR) channel.c $(INCL)
  
! $(OUTDIR)/normal.obj: $(OUTDIR) normal.c  $(INCL) nv_cmdidxs.h nv_cmds.h
  
  $(OUTDIR)/option.obj: $(OUTDIR) option.c  $(INCL) optiondefs.h
  
*** ../vim-8.2.4269/src/Make_vms.mms    2022-01-29 13:06:19.336028749 +0000
--- src/Make_vms.mms    2022-01-31 11:59:27.092480128 +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 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
--- 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 nv_cmds.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.4269/src/Makefile        2022-01-29 13:06:19.336028749 +0000
--- src/Makefile        2022-01-31 12:18:30.019205276 +0000
***************
*** 2141,2159 ****
  # This only needs to be run when a command name has been added or changed.
  # If this fails because you don't have Vim yet, first build and install Vim
  # without changes.
  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.
--- 2141,2161 ----
  # This only needs to be run when a command name has been added or changed.
  # If this fails because you don't have Vim yet, first build and install Vim
  # without changes.
+ # This requires a "vim" executable with the +eval feature.
  cmdidxs: ex_cmds.h
!       vim --clean -N -X --not-a-term -u create_cmdidxs.vim -c quit
  
  # 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.
! # This requires a "vim" executable with the +eval feature.
! # If this fails because you don't have Vim yet:
! #   - change nv_cmds[] in nv_cmds.h to add the new normal/visual mode command.
! #   - run "make nvcmdidxs" to generate nv_cmdidxs.h
! nvcmdidxs: auto/config.mk nv_cmds.h
!       $(CC) -I$(srcdir) $(ALL_CFLAGS) create_nvcmdidxs.c -o create_nvcmdidxs
!       vim --clean -N -X --not-a-term -u create_nvcmdidxs.vim -c quit
!       -rm -f create_nvcmdidxs
  
  # The normal command to compile a .c file to its .o file.
  # Without or with ALL_CFLAGS.
***************
*** 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 \
--- 4014,4020 ----
  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 nv_cmds.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.4269/src/create_nvcmdidxs.c      2022-01-31 12:24:26.149840406 
+0000
--- src/create_nvcmdidxs.c      2022-01-31 12:19:43.282101371 +0000
***************
*** 0 ****
--- 1,38 ----
+ /* vi:set ts=8 sts=4 sw=4 noet:
+  *
+  * VIM - Vi IMproved  by Bram Moolenaar et al.
+  *
+  * Do ":help uganda"  in Vim to read copying and usage conditions.
+  * Do ":help credits" in Vim to see a list of people who contributed.
+  * See README.txt for an overview of the Vim source code.
+  */
+ 
+ /*
+  * create_nvcmdidxs.c: helper program for `make nvcmdidxs`
+  *
+  * This outputs the list of command characters from the nv_cmds table in
+  * decimal form, one per line.
+  */
+ 
+ #include "vim.h"
+ 
+ // Declare nv_cmds[].
+ #include "nv_cmds.h"
+ 
+ #include <stdio.h>
+ 
+ int main(void)
+ {
+     size_t i;
+ 
+     for (i = 0; i < NV_CMDS_SIZE; i++)
+     {
+       int cmdchar = nv_cmds[i];
+ 
+       // Special keys are negative, use the negated value for sorting.
+       if (cmdchar < 0)
+           cmdchar = -cmdchar;
+       printf("%d\n", cmdchar);
+     }
+     return 0;
+ }
*** ../vim-8.2.4269/src/create_nvcmdidxs.vim    2022-01-29 13:06:19.336028749 
+0000
--- src/create_nvcmdidxs.vim    2022-01-31 12:22:48.627309249 +0000
***************
*** 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
--- 1,60 ----
! " 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/nv_cmds.h changes.
! "
! " This is written in legacy Vim script so that it can be run by a slightly
! " older Vim version.
! 
! " Generate the table of normal/visual mode command characters and their
! " corresponding index.
! let cmd = 'create_nvcmdidxs'
! if has('unix')
!   let cmd = './' .. cmd
! endif
! let nv_cmdtbl = systemlist(cmd)->map({i, ch -> {'idx': i, 'cmdchar': ch}})
! 
! " sort the table by the command character
! call 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.
! let nv_max_linear = 0
! for i in range(nv_cmdtbl->len())
!   if i != nv_cmdtbl[i].cmdchar
!     let nv_max_linear = i - 1
!     break
!   endif
! endfor
! 
! " Generate a header file with the table
! let output =<< 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
! let output += nv_cmdtbl->map({_, v ->
!       \ printf('  /* %5d */ %3d,', v.cmdchar, v.idx)})
! 
! let output += ['};', '',
!       \ '// The highest index for which',
!       \ '// nv_cmds[idx].cmd_char == nv_cmd_idx[nv_cmds[idx].cmd_char]']
  
! let output += ['static const int nv_max_linear = ' .. nv_max_linear .. ';']
  
! call writefile(output, "nv_cmdidxs.h")
  quit
  
! " vim: shiftwidth=2 sts=2 expandtab
*** ../vim-8.2.4269/src/evalfunc.c      2022-01-30 12:36:48.732985521 +0000
--- src/evalfunc.c      2022-01-31 11:59:27.096480069 +0000
***************
*** 1735,1742 ****
                        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,
--- 1735,1740 ----
*** ../vim-8.2.4269/src/proto/normal.pro        2022-01-29 13:06:19.340028690 
+0000
--- src/proto/normal.pro        2022-01-31 11:59:27.096480069 +0000
***************
*** 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);
--- 1,4 ----
*** ../vim-8.2.4269/src/version.c       2022-01-31 11:44:44.409529899 +0000
--- src/version.c       2022-01-31 12:00:01.251960787 +0000
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     4270,
  /**/

-- 
BLACK KNIGHT: The Black Knight always triumphs. Have at you!
   ARTHUR takes his last leg off.  The BLACK KNIGHT's body lands upright.
BLACK KNIGHT: All right, we'll call it a draw.
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD

 /// Bram Moolenaar -- b...@moolenaar.net -- 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 vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220131122754.C73FE1C1918%40moolenaar.net.

Raspunde prin e-mail lui