aboutsummaryrefslogtreecommitdiff
path: root/src/gen/gen_ex_cmds.lua
diff options
context:
space:
mode:
Diffstat (limited to 'src/gen/gen_ex_cmds.lua')
-rw-r--r--src/gen/gen_ex_cmds.lua194
1 files changed, 194 insertions, 0 deletions
diff --git a/src/gen/gen_ex_cmds.lua b/src/gen/gen_ex_cmds.lua
new file mode 100644
index 0000000000..6c03e8fc4d
--- /dev/null
+++ b/src/gen/gen_ex_cmds.lua
@@ -0,0 +1,194 @@
+local includedir = arg[1]
+local autodir = arg[2]
+
+-- Will generate files ex_cmds_enum.generated.h with cmdidx_T enum
+-- and ex_cmds_defs.generated.h with main Ex commands definitions.
+
+local enumfname = includedir .. '/ex_cmds_enum.generated.h'
+local defsfname = autodir .. '/ex_cmds_defs.generated.h'
+
+local enumfile = io.open(enumfname, 'w')
+local defsfile = io.open(defsfname, 'w')
+
+local bit = require 'bit'
+local ex_cmds = require('nvim.ex_cmds')
+local defs = ex_cmds.cmds
+local flags = ex_cmds.flags
+
+local byte_a = string.byte('a')
+local byte_z = string.byte('z')
+local a_to_z = byte_z - byte_a + 1
+
+-- Table giving the index of the first command in cmdnames[] to lookup
+-- based on the first letter of a command.
+local cmdidxs1_out = string.format(
+ [[
+static const uint16_t cmdidxs1[%u] = {
+]],
+ a_to_z
+)
+-- Table giving the index of the first command in cmdnames[] to lookup
+-- based on the first 2 letters of a command.
+-- Values in cmdidxs2[c1][c2] are relative to cmdidxs1[c1] so that they
+-- fit in a byte.
+local cmdidxs2_out = string.format(
+ [[
+static const uint8_t cmdidxs2[%u][%u] = {
+ /* 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 */
+]],
+ a_to_z,
+ a_to_z
+)
+
+enumfile:write([[
+// IWYU pragma: private, include "nvim/ex_cmds_defs.h"
+
+typedef enum CMD_index {
+]])
+defsfile:write(string.format(
+ [[
+#include "nvim/arglist.h"
+#include "nvim/autocmd.h"
+#include "nvim/buffer.h"
+#include "nvim/cmdhist.h"
+#include "nvim/debugger.h"
+#include "nvim/diff.h"
+#include "nvim/digraph.h"
+#include "nvim/eval.h"
+#include "nvim/eval/userfunc.h"
+#include "nvim/eval/vars.h"
+#include "nvim/ex_cmds.h"
+#include "nvim/ex_cmds2.h"
+#include "nvim/ex_docmd.h"
+#include "nvim/ex_eval.h"
+#include "nvim/ex_session.h"
+#include "nvim/help.h"
+#include "nvim/indent.h"
+#include "nvim/lua/executor.h"
+#include "nvim/lua/secure.h"
+#include "nvim/mapping.h"
+#include "nvim/mark.h"
+#include "nvim/match.h"
+#include "nvim/menu.h"
+#include "nvim/message.h"
+#include "nvim/ops.h"
+#include "nvim/option.h"
+#include "nvim/os/lang.h"
+#include "nvim/profile.h"
+#include "nvim/quickfix.h"
+#include "nvim/runtime.h"
+#include "nvim/sign.h"
+#include "nvim/spell.h"
+#include "nvim/spellfile.h"
+#include "nvim/syntax.h"
+#include "nvim/undo.h"
+#include "nvim/usercmd.h"
+#include "nvim/version.h"
+
+static const int command_count = %u;
+static CommandDefinition cmdnames[%u] = {
+]],
+ #defs,
+ #defs
+))
+local cmds, cmdidxs1, cmdidxs2 = {}, {}, {}
+for _, cmd in ipairs(defs) do
+ if bit.band(cmd.flags, flags.RANGE) == flags.RANGE then
+ assert(
+ cmd.addr_type ~= 'ADDR_NONE',
+ string.format('ex_cmds.lua:%s: Using RANGE with ADDR_NONE\n', cmd.command)
+ )
+ else
+ assert(
+ cmd.addr_type == 'ADDR_NONE',
+ string.format('ex_cmds.lua:%s: Missing ADDR_NONE\n', cmd.command)
+ )
+ end
+ if bit.band(cmd.flags, flags.DFLALL) == flags.DFLALL then
+ assert(
+ cmd.addr_type ~= 'ADDR_OTHER' and cmd.addr_type ~= 'ADDR_NONE',
+ string.format('ex_cmds.lua:%s: Missing misplaced DFLALL\n', cmd.command)
+ )
+ end
+ if bit.band(cmd.flags, flags.PREVIEW) == flags.PREVIEW then
+ assert(
+ cmd.preview_func ~= nil,
+ string.format('ex_cmds.lua:%s: Missing preview_func\n', cmd.command)
+ )
+ end
+ local enumname = cmd.enum or ('CMD_' .. cmd.command)
+ local byte_cmd = cmd.command:sub(1, 1):byte()
+ if byte_a <= byte_cmd and byte_cmd <= byte_z then
+ table.insert(cmds, cmd.command)
+ end
+ local preview_func
+ if cmd.preview_func then
+ preview_func = string.format('&%s', cmd.preview_func)
+ else
+ preview_func = 'NULL'
+ end
+ enumfile:write(' ' .. enumname .. ',\n')
+ defsfile:write(string.format(
+ [[
+ [%s] = {
+ .cmd_name = "%s",
+ .cmd_func = (ex_func_T)&%s,
+ .cmd_preview_func = %s,
+ .cmd_argt = %uL,
+ .cmd_addr_type = %s
+ },
+]],
+ enumname,
+ cmd.command,
+ cmd.func,
+ preview_func,
+ cmd.flags,
+ cmd.addr_type
+ ))
+end
+for i = #cmds, 1, -1 do
+ local cmd = cmds[i]
+ -- First and second characters of the command
+ local c1 = cmd:sub(1, 1)
+ cmdidxs1[c1] = i - 1
+ if cmd:len() >= 2 then
+ local c2 = cmd:sub(2, 2)
+ local byte_c2 = string.byte(c2)
+ if byte_a <= byte_c2 and byte_c2 <= byte_z then
+ if not cmdidxs2[c1] then
+ cmdidxs2[c1] = {}
+ end
+ cmdidxs2[c1][c2] = i - 1
+ end
+ end
+end
+for i = byte_a, byte_z do
+ local c1 = string.char(i)
+ cmdidxs1_out = cmdidxs1_out .. ' /* ' .. c1 .. ' */ ' .. cmdidxs1[c1] .. ',\n'
+ cmdidxs2_out = cmdidxs2_out .. ' /* ' .. c1 .. ' */ {'
+ for j = byte_a, byte_z do
+ local c2 = string.char(j)
+ cmdidxs2_out = cmdidxs2_out
+ .. ((cmdidxs2[c1] and cmdidxs2[c1][c2]) and string.format(
+ '%3d',
+ cmdidxs2[c1][c2] - cmdidxs1[c1]
+ ) or ' 0')
+ .. ','
+ end
+ cmdidxs2_out = cmdidxs2_out .. ' },\n'
+end
+enumfile:write([[
+ CMD_SIZE,
+ CMD_USER = -1,
+ CMD_USER_BUF = -2
+} cmdidx_T;
+]])
+defsfile:write(string.format(
+ [[
+};
+%s};
+%s};
+]],
+ cmdidxs1_out,
+ cmdidxs2_out
+))