neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

gen_ex_cmds.lua (5035B)


      1 -- Will generate files ex_cmds_enum.generated.h with cmdidx_T enum
      2 -- and ex_cmds_defs.generated.h with main Ex commands definitions.
      3 
      4 local enumfname = arg[1] -- '/ex_cmds_enum.generated.h'
      5 local defsfname = arg[2] -- '/ex_cmds_defs.generated.h'
      6 local ex_cmds_name = arg[3] -- 'ex_cmds.lua'
      7 
      8 local enumfile = io.open(enumfname, 'w')
      9 local defsfile = io.open(defsfname, 'w')
     10 
     11 local bit = require 'bit'
     12 local ex_cmds = loadfile(ex_cmds_name)()
     13 local defs = ex_cmds.cmds
     14 local flags = ex_cmds.flags
     15 
     16 local byte_a = string.byte('a')
     17 local byte_z = string.byte('z')
     18 local a_to_z = byte_z - byte_a + 1
     19 
     20 -- Table giving the index of the first command in cmdnames[] to lookup
     21 -- based on the first letter of a command.
     22 local cmdidxs1_out = string.format(
     23  [[
     24 static const uint16_t cmdidxs1[%u] = {
     25 ]],
     26  a_to_z
     27 )
     28 -- Table giving the index of the first command in cmdnames[] to lookup
     29 -- based on the first 2 letters of a command.
     30 -- Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they
     31 -- fit in a byte.
     32 local cmdidxs2_out = string.format(
     33  [[
     34 static const uint8_t cmdidxs2[%u][%u] = {
     35  /*           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 */
     36 ]],
     37  a_to_z,
     38  a_to_z
     39 )
     40 
     41 enumfile:write([[
     42 // IWYU pragma: private, include "nvim/ex_cmds_defs.h"
     43 
     44 typedef enum CMD_index {
     45 ]])
     46 defsfile:write(string.format(
     47  [[
     48 #include "nvim/arglist.h"
     49 #include "nvim/autocmd.h"
     50 #include "nvim/buffer.h"
     51 #include "nvim/cmdhist.h"
     52 #include "nvim/debugger.h"
     53 #include "nvim/diff.h"
     54 #include "nvim/digraph.h"
     55 #include "nvim/eval.h"
     56 #include "nvim/eval/userfunc.h"
     57 #include "nvim/eval/vars.h"
     58 #include "nvim/ex_cmds.h"
     59 #include "nvim/ex_cmds2.h"
     60 #include "nvim/ex_docmd.h"
     61 #include "nvim/ex_eval.h"
     62 #include "nvim/ex_session.h"
     63 #include "nvim/help.h"
     64 #include "nvim/indent.h"
     65 #include "nvim/lua/executor.h"
     66 #include "nvim/lua/secure.h"
     67 #include "nvim/mapping.h"
     68 #include "nvim/mark.h"
     69 #include "nvim/match.h"
     70 #include "nvim/menu.h"
     71 #include "nvim/message.h"
     72 #include "nvim/ops.h"
     73 #include "nvim/option.h"
     74 #include "nvim/os/lang.h"
     75 #include "nvim/profile.h"
     76 #include "nvim/quickfix.h"
     77 #include "nvim/register.h"
     78 #include "nvim/runtime.h"
     79 #include "nvim/sign.h"
     80 #include "nvim/spell.h"
     81 #include "nvim/spellfile.h"
     82 #include "nvim/syntax.h"
     83 #include "nvim/undo.h"
     84 #include "nvim/usercmd.h"
     85 #include "nvim/version.h"
     86 
     87 static const int command_count = %u;
     88 static CommandDefinition cmdnames[%u] = {
     89 ]],
     90  #defs,
     91  #defs
     92 ))
     93 local cmds, cmdidxs1, cmdidxs2 = {}, {}, {}
     94 for _, cmd in ipairs(defs) do
     95  if bit.band(cmd.flags, flags.RANGE) == flags.RANGE then
     96    assert(
     97      cmd.addr_type ~= 'ADDR_NONE',
     98      string.format('ex_cmds.lua:%s: Using RANGE with ADDR_NONE\n', cmd.command)
     99    )
    100  else
    101    assert(
    102      cmd.addr_type == 'ADDR_NONE',
    103      string.format('ex_cmds.lua:%s: Missing ADDR_NONE\n', cmd.command)
    104    )
    105  end
    106  if bit.band(cmd.flags, flags.DFLALL) == flags.DFLALL then
    107    assert(
    108      cmd.addr_type ~= 'ADDR_OTHER' and cmd.addr_type ~= 'ADDR_NONE',
    109      string.format('ex_cmds.lua:%s: Missing misplaced DFLALL\n', cmd.command)
    110    )
    111  end
    112  if bit.band(cmd.flags, flags.PREVIEW) == flags.PREVIEW then
    113    assert(
    114      cmd.preview_func ~= nil,
    115      string.format('ex_cmds.lua:%s: Missing preview_func\n', cmd.command)
    116    )
    117  end
    118  local enumname = cmd.enum or ('CMD_' .. cmd.command)
    119  local byte_cmd = cmd.command:sub(1, 1):byte()
    120  if byte_a <= byte_cmd and byte_cmd <= byte_z then
    121    table.insert(cmds, cmd.command)
    122  end
    123  local preview_func
    124  if cmd.preview_func then
    125    preview_func = string.format('&%s', cmd.preview_func)
    126  else
    127    preview_func = 'NULL'
    128  end
    129  enumfile:write('  ' .. enumname .. ',\n')
    130  defsfile:write(string.format(
    131    [[
    132  [%s] = {
    133    .cmd_name = "%s",
    134    .cmd_func = (ex_func_T)&%s,
    135    .cmd_preview_func = %s,
    136    .cmd_argt = %uL,
    137    .cmd_addr_type = %s
    138  },
    139 ]],
    140    enumname,
    141    cmd.command,
    142    cmd.func,
    143    preview_func,
    144    cmd.flags,
    145    cmd.addr_type
    146  ))
    147 end
    148 for i = #cmds, 1, -1 do
    149  local cmd = cmds[i]
    150  -- First and second characters of the command
    151  local c1 = cmd:sub(1, 1)
    152  cmdidxs1[c1] = i - 1
    153  if cmd:len() >= 2 then
    154    local c2 = cmd:sub(2, 2)
    155    local byte_c2 = string.byte(c2)
    156    if byte_a <= byte_c2 and byte_c2 <= byte_z then
    157      if not cmdidxs2[c1] then
    158        cmdidxs2[c1] = {}
    159      end
    160      cmdidxs2[c1][c2] = i - 1
    161    end
    162  end
    163 end
    164 for i = byte_a, byte_z do
    165  local c1 = string.char(i)
    166  cmdidxs1_out = cmdidxs1_out .. '  /*  ' .. c1 .. '  */ ' .. cmdidxs1[c1] .. ',\n'
    167  cmdidxs2_out = cmdidxs2_out .. '  /*  ' .. c1 .. '  */ {'
    168  for j = byte_a, byte_z do
    169    local c2 = string.char(j)
    170    cmdidxs2_out = cmdidxs2_out
    171      .. ((cmdidxs2[c1] and cmdidxs2[c1][c2]) and string.format(
    172        '%3d',
    173        cmdidxs2[c1][c2] - cmdidxs1[c1]
    174      ) or '  0')
    175      .. ','
    176  end
    177  cmdidxs2_out = cmdidxs2_out .. ' },\n'
    178 end
    179 enumfile:write([[
    180  CMD_SIZE,
    181  CMD_USER = -1,
    182  CMD_USER_BUF = -2
    183 } cmdidx_T;
    184 ]])
    185 defsfile:write(string.format(
    186  [[
    187 };
    188 %s};
    189 %s};
    190 ]],
    191  cmdidxs1_out,
    192  cmdidxs2_out
    193 ))