xref: /vim-8.2.3635/src/create_cmdidxs.vim (revision 577fadfc)
1" This script generates the tables cmdidxs1[] and cmdidxs2[][] which,
2" given a Ex command, determine the first value to probe to find
3" a matching command in cmdnames[] based on the first character
4" and the first 2 characters of the command.
5" This is used to speed up lookup in cmdnames[].
6"
7" Script should be run every time new Ex commands are added in Vim,
8" from the src/vim directory, since it reads commands from "ex_cmds.h".
9
10let cmds = []
11let skipped_cmds = 0
12
13for line in readfile('ex_cmds.h')
14  if line =~ '^EX(CMD_'
15    let m = matchlist(line, '^EX(CMD_\S*,\s*"\([a-z][^"]*\)"')
16    if len(m) >= 2
17      let cmds += [ m[1] ]
18    else
19      let skipped_cmds += 1
20    endif
21  endif
22endfor
23
24let cmdidxs1 = {}
25let cmdidxs2 = {}
26
27for i in range(len(cmds) - 1, 0, -1)
28  let cmd = cmds[i]
29  let c1 = cmd[0] " First character of command
30  let c2 = cmd[1] " Second character of command (if any)
31
32  let cmdidxs1{c1} = i
33  if c2 >= 'a' && c2 <= 'z'
34    let cmdidxs2{c1}{c2} = i
35  endif
36endfor
37
38let output =  [ '/* Automatically generated code by create_cmdidxs.vim' ]
39let output += [ ' *' ]
40let output += [ ' * Table giving the index of the first command in cmdnames[] to lookup' ]
41let output += [ ' * based on the first letter of a command.' ]
42let output += [ ' */' ]
43let output += [ 'static const unsigned short cmdidxs1[26] =' ]
44let output += [ '{' ]
45
46let a_to_z = map(range(char2nr('a'), char2nr('z')), 'nr2char(v:val)')
47for c1 in a_to_z
48  let line = '  /* ' . c1 . ' */ ' . cmdidxs1{c1} . ((c1 == 'z') ? '' : ',')
49  let output += [ line ]
50endfor
51let output += [ '};' ]
52let output += [ '' ]
53let output += [ '/*' ]
54let output += [ ' * Table giving the index of the first command in cmdnames[] to lookup' ]
55let output += [ ' * based on the first 2 letters of a command.' ]
56let output += [ ' * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they' ]
57let output += [ ' * fit in a byte.' ]
58let output += [ ' */' ]
59let output += [ 'static const unsigned char cmdidxs2[26][26] =' ]
60let output += [ '{ /*         a   b   c   d   e   f   g   h   i   j   k   l   m   n   o   p   q   r   s   t   u   v   w   x   y   z */' ]
61
62for c1 in a_to_z
63  let line = '  /* ' . c1 . ' */ {'
64  for c2 in a_to_z
65    if exists('cmdidxs2{c1}{c2}')
66      let line .= printf('%3d', cmdidxs2{c1}{c2} - cmdidxs1{c1})
67    else
68      let line .= '  0'
69    endif
70    let line .= (c2 == 'z') ? '' : ','
71  endfor
72  let line .= ' }' . ((c1 == 'z') ? '' : ',')
73  let output += [ line ]
74endfor
75
76let output += [ '};' ]
77let output += [ '' ]
78let output += [ 'static const int command_count = ' . (len(cmds) + skipped_cmds) . ';' ]
79
80call writefile(output, "ex_cmdidxs.h")
81quit
82