patch 8.2.4270: generating nv_cmdidxs.h requires building Vim twice

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)
diff --git a/src/create_nvcmdidxs.vim b/src/create_nvcmdidxs.vim
index 2dd5fdb..1319276 100644
--- a/src/create_nvcmdidxs.vim
+++ b/src/create_nvcmdidxs.vim
@@ -1,72 +1,60 @@
-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/nv_cmds.h changes.
+"
+" This is written in legacy Vim script so that it can be run by a slightly
+" older Vim version.
 
-# 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.
+" 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}})
 
-def Create_nvcmdidxs_table()
-  var nv_cmdtbl: list<dict<number>> = []
+" sort the table by the command character
+call sort(nv_cmdtbl, {a, b -> a.cmdchar - b.cmdchar})
 
-  # 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
+" 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
 
-  # sort the table by the command character
-  sort(nv_cmdtbl, (a, b) => a.cmdchar - b.cmdchar)
+" 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.
+   */
 
-  # 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
+  // nv_cmd_idx[<normal mode command character>] => nv_cmds[] index
+  static const unsigned short nv_cmd_idx[] =
+  {
+END
 
-  # 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.
-     */
+" Add each command character in comment and the corresponding index
+let output += nv_cmdtbl->map({_, v ->
+      \ printf('  /* %5d */ %3d,', v.cmdchar, v.idx)})
 
-    // nv_cmd_idx[<normal mode command character>] => nv_cmds[] index
-    static const unsigned short nv_cmd_idx[] =
-    {
-  END
+let output += ['};', '',
+      \ '// The highest index for which',
+      \ '// nv_cmds[idx].cmd_char == nv_cmd_idx[nv_cmds[idx].cmd_char]']
 
-  # 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
+let output += ['static const int nv_max_linear = ' .. nv_max_linear .. ';']
 
-  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()
+call writefile(output, "nv_cmdidxs.h")
 quit
 
-# vim: shiftwidth=2 sts=2 expandtab
+" vim: shiftwidth=2 sts=2 expandtab