Bram Moolenaar | 6de5e12 | 2017-04-20 21:55:44 +0200 | [diff] [blame^] | 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 | |
| 10 | let cmds = [] |
| 11 | let skipped_cmds = 0 |
| 12 | |
| 13 | for 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 |
| 22 | endfor |
| 23 | |
| 24 | let cmdidxs1 = {} |
| 25 | let cmdidxs2 = {} |
| 26 | |
| 27 | for 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 |
| 36 | endfor |
| 37 | |
| 38 | let output = [ '/* Automatically generated code by create_cmdidxs.vim' ] |
| 39 | let output += [ ' *' ] |
| 40 | let output += [ ' * Table giving the index of the first command in cmdnames[] to lookup' ] |
| 41 | let output += [ ' * based on the first letter of a command.' ] |
| 42 | let output += [ ' */' ] |
| 43 | let output += [ 'static const unsigned short cmdidxs1[26] =' ] |
| 44 | let output += [ '{' ] |
| 45 | |
| 46 | let a_to_z = map(range(char2nr('a'), char2nr('z')), 'nr2char(v:val)') |
| 47 | for c1 in a_to_z |
| 48 | let line = ' /* ' . c1 . ' */ ' . cmdidxs1{c1} . ((c1 == 'z') ? '' : ',') |
| 49 | let output += [ line ] |
| 50 | endfor |
| 51 | let output += [ '};' ] |
| 52 | let output += [ '' ] |
| 53 | let output += [ '/*' ] |
| 54 | let output += [ ' * Table giving the index of the first command in cmdnames[] to lookup' ] |
| 55 | let output += [ ' * based on the first 2 letters of a command.' ] |
| 56 | let output += [ ' * Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they' ] |
| 57 | let output += [ ' * fit in a byte.' ] |
| 58 | let output += [ ' */' ] |
| 59 | let output += [ 'static const unsigned char cmdidxs2[26][26] =' ] |
| 60 | let 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 | |
| 62 | for 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 ] |
| 74 | endfor |
| 75 | |
| 76 | let output += [ '};' ] |
| 77 | let output += [ '' ] |
| 78 | let output += [ 'static const int command_count = ' . (len(cmds) + skipped_cmds) . ';' ] |
| 79 | |
| 80 | call writefile(output, "ex_cmdidxs.h") |
| 81 | quit |