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 13let lines = readfile('ex_cmds.h') 14let idx = 0 15while idx < len(lines) 16 let line = lines[idx] 17 if line =~ '^EX(CMD_' 18 let m = matchlist(line, '^EX(CMD_\S*,\s*"\([a-z][^"]*\)"') 19 if len(m) >= 2 20 let cmds += [ m[1] ] 21 else 22 let skipped_cmds += 1 23 endif 24 25 let idx += 1 26 let flags = lines[idx] 27 let idx += 1 28 let addr_type = lines[idx] 29 30 if flags =~ '\<RANGE\>' 31 if addr_type =~ 'ADDR_NONE' 32 echoerr 'ex_cmds.h:' .. (idx - 1) .. ': Using RANGE with ADDR_NONE: ' .. line 33 endif 34 else 35 if addr_type !~ 'ADDR_NONE' 36 echoerr 'ex_cmds.h:' .. (idx - 1) .. ': Missing ADDR_NONE: ' .. line 37 endif 38 endif 39 40 if flags =~ '\<DFLALL\>' && (addr_type =~ 'ADDR_OTHER' || addr_type =~ 'ADDR_NONE') 41 echoerr 'ex_cmds.h:' .. (idx - 1) .. ': Missing misplaced DFLALL: ' .. line 42 endif 43 endif 44 let idx += 1 45endwhile 46 47let cmdidxs1 = {} 48let cmdidxs2 = {} 49 50for i in range(len(cmds) - 1, 0, -1) 51 let cmd = cmds[i] 52 let c1 = cmd[0] " First character of command 53 let c2 = cmd[1] " Second character of command (if any) 54 55 let cmdidxs1{c1} = i 56 if c2 >= 'a' && c2 <= 'z' 57 let cmdidxs2{c1}{c2} = i 58 endif 59endfor 60 61let output = [ '/* Automatically generated code by create_cmdidxs.vim' ] 62let output += [ ' *' ] 63let output += [ ' * Table giving the index of the first command in cmdnames[] to lookup' ] 64let output += [ ' * based on the first letter of a command.' ] 65let output += [ ' */' ] 66let output += [ 'static const unsigned short cmdidxs1[26] =' ] 67let output += [ '{' ] 68 69let a_to_z = map(range(char2nr('a'), char2nr('z')), 'nr2char(v:val)') 70for c1 in a_to_z 71 let line = ' /* ' . c1 . ' */ ' . cmdidxs1{c1} . ((c1 == 'z') ? '' : ',') 72 let output += [ line ] 73endfor 74let output += [ '};' ] 75let output += [ '' ] 76let output += [ '/*' ] 77let output += [ ' * Table giving the index of the first command in cmdnames[] to lookup' ] 78let output += [ ' * based on the first 2 letters of a command.' ] 79let output += [ ' * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they' ] 80let output += [ ' * fit in a byte.' ] 81let output += [ ' */' ] 82let output += [ 'static const unsigned char cmdidxs2[26][26] =' ] 83let 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 */' ] 84 85for c1 in a_to_z 86 let line = ' /* ' . c1 . ' */ {' 87 for c2 in a_to_z 88 if exists('cmdidxs2{c1}{c2}') 89 let line .= printf('%3d', cmdidxs2{c1}{c2} - cmdidxs1{c1}) 90 else 91 let line .= ' 0' 92 endif 93 let line .= (c2 == 'z') ? '' : ',' 94 endfor 95 let line .= ' }' . ((c1 == 'z') ? '' : ',') 96 let output += [ line ] 97endfor 98 99let output += [ '};' ] 100let output += [ '' ] 101let output += [ 'static const int command_count = ' . (len(cmds) + skipped_cmds) . ';' ] 102 103call writefile(output, "ex_cmdidxs.h") 104quit 105