aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/generators
diff options
context:
space:
mode:
authorLewis Russell <lewis6991@gmail.com>2025-02-26 11:38:07 +0000
committerLewis Russell <me@lewisr.dev>2025-02-26 16:54:37 +0000
commit0f24b0826a27b7868a3aacc25199787e7453d4cc (patch)
tree49585aac252581a735577f2e5711201a85ab8a7e /src/nvim/generators
parent85caaa70d44b7b18c633aa0b140de5f3f6d3eee7 (diff)
downloadrneovim-0f24b0826a27b7868a3aacc25199787e7453d4cc.tar.gz
rneovim-0f24b0826a27b7868a3aacc25199787e7453d4cc.tar.bz2
rneovim-0f24b0826a27b7868a3aacc25199787e7453d4cc.zip
build: move all generator scripts to `src/gen/`
- Move all generator Lua scripts to the `src/gen/` - Add a `.luarc.json` to `src/gen/` - Add a `preload.lua` to `src/gen/` - Add `src` to `package.path` so it aligns with `.luarc.json' - Fix all `require` statements in `src/gen/` so they are consistent: - `require('scripts.foo')` -> `require('gen.foo')` - `require('src.nvim.options')` -> `require('nvim.options')` - `require('api.dispatch_deprecated')` -> `require('nvim.api.dispatch_deprecated')`
Diffstat (limited to 'src/nvim/generators')
-rw-r--r--src/nvim/generators/c_grammar.lua300
-rw-r--r--src/nvim/generators/dump_bin_array.lua17
-rw-r--r--src/nvim/generators/gen_api_dispatch.lua990
-rw-r--r--src/nvim/generators/gen_api_ui_events.lua219
-rw-r--r--src/nvim/generators/gen_char_blob.lua96
-rw-r--r--src/nvim/generators/gen_declarations.lua186
-rw-r--r--src/nvim/generators/gen_eval.lua112
-rw-r--r--src/nvim/generators/gen_events.lua42
-rw-r--r--src/nvim/generators/gen_ex_cmds.lua194
-rw-r--r--src/nvim/generators/gen_options.lua535
-rw-r--r--src/nvim/generators/gen_vimvim.lua156
-rw-r--r--src/nvim/generators/hashy.lua145
-rw-r--r--src/nvim/generators/nvim_version.lua.in9
-rw-r--r--src/nvim/generators/preload.lua13
14 files changed, 0 insertions, 3014 deletions
diff --git a/src/nvim/generators/c_grammar.lua b/src/nvim/generators/c_grammar.lua
deleted file mode 100644
index 890c260843..0000000000
--- a/src/nvim/generators/c_grammar.lua
+++ /dev/null
@@ -1,300 +0,0 @@
--- lpeg grammar for building api metadata from a set of header files. It
--- ignores comments and preprocessor commands and parses a very small subset
--- of C prototypes with a limited set of types
-
---- @class nvim.c_grammar.Proto
---- @field [1] 'proto'
---- @field pos integer
---- @field endpos integer
---- @field fast boolean
---- @field name string
---- @field return_type string
---- @field parameters [string, string][]
---- @field static true?
---- @field inline true?
-
---- @class nvim.c_grammar.Preproc
---- @field [1] 'preproc'
---- @field content string
-
---- @class nvim.c_grammar.Empty
---- @field [1] 'empty'
-
---- @alias nvim.c_grammar.result
---- | nvim.c_grammar.Proto
---- | nvim.c_grammar.Preproc
---- | nvim.c_grammar.Empty
-
---- @class nvim.c_grammar
---- @field match fun(self, input: string): nvim.c_grammar.result[]
-
-local lpeg = vim.lpeg
-
-local P, R, S, V = lpeg.P, lpeg.R, lpeg.S, lpeg.V
-local C, Ct, Cc, Cg, Cp = lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cg, lpeg.Cp
-
---- @param pat vim.lpeg.Pattern
-local function rep(pat)
- return pat ^ 0
-end
-
---- @param pat vim.lpeg.Pattern
-local function rep1(pat)
- return pat ^ 1
-end
-
---- @param pat vim.lpeg.Pattern
-local function opt(pat)
- return pat ^ -1
-end
-
-local any = P(1)
-local letter = R('az', 'AZ') + S('_$')
-local num = R('09')
-local alpha = letter + num
-local nl = P('\r\n') + P('\n')
-local space = S(' \t')
-local str = P('"') * rep((P('\\') * any) + (1 - P('"'))) * P('"')
-local char = P("'") * (any - P("'")) * P("'")
-local ws = space + nl
-local wb = #-alpha -- word boundary
-local id = letter * rep(alpha)
-
-local comment_inline = P('/*') * rep(1 - P('*/')) * P('*/')
-local comment = P('//') * rep(1 - nl) * nl
-local preproc = Ct(Cc('preproc') * P('#') * Cg(rep(1 - nl) * nl, 'content'))
-
-local fill = rep(ws + comment_inline + comment + preproc)
-
---- @param s string
---- @return vim.lpeg.Pattern
-local function word(s)
- return fill * P(s) * wb * fill
-end
-
---- @param x vim.lpeg.Pattern
-local function comma1(x)
- return x * rep(fill * P(',') * fill * x)
-end
-
---- @param v string
-local function Pf(v)
- return fill * P(v) * fill
-end
-
---- @param x vim.lpeg.Pattern
-local function paren(x)
- return P('(') * fill * x * fill * P(')')
-end
-
-local cdoc_comment = P('///') * opt(Ct(Cg(rep(space) * rep(1 - nl), 'comment')))
-
-local braces = P({
- 'S',
- A = comment_inline + comment + preproc + str + char + (any - S('{}')),
- S = P('{') * rep(V('A')) * rep(V('S') + V('A')) * P('}'),
-})
-
--- stylua: ignore start
-local typed_container = P({
- 'S',
- S = (
- (P('Union') * paren(comma1(V('ID'))))
- + (P('ArrayOf') * paren(id * opt(P(',') * fill * rep1(num))))
- + (P('DictOf') * paren(id))
- + (P('LuaRefOf') * paren(
- paren(comma1((V('ID') + str) * rep1(ws) * opt(P('*')) * id))
- * opt(P(',') * fill * opt(P('*')) * V('ID'))
- ))
- + (P('Dict') * paren(id))),
- ID = V('S') + id,
-})
--- stylua: ignore end
-
-local ptr_mod = word('restrict') + word('__restrict') + word('const')
-local opt_ptr = rep(Pf('*') * opt(ptr_mod))
-
---- @param name string
---- @param var string
---- @return vim.lpeg.Pattern
-local function attr(name, var)
- return Cg((P(name) * Cc(true)), var)
-end
-
---- @param name string
---- @param var string
---- @return vim.lpeg.Pattern
-local function attr_num(name, var)
- return Cg((P(name) * paren(C(rep1(num)))), var)
-end
-
-local fattr = (
- attr_num('FUNC_API_SINCE', 'since')
- + attr_num('FUNC_API_DEPRECATED_SINCE', 'deprecated_since')
- + attr('FUNC_API_FAST', 'fast')
- + attr('FUNC_API_RET_ALLOC', 'ret_alloc')
- + attr('FUNC_API_NOEXPORT', 'noexport')
- + attr('FUNC_API_REMOTE_ONLY', 'remote_only')
- + attr('FUNC_API_LUA_ONLY', 'lua_only')
- + attr('FUNC_API_TEXTLOCK_ALLOW_CMDWIN', 'textlock_allow_cmdwin')
- + attr('FUNC_API_TEXTLOCK', 'textlock')
- + attr('FUNC_API_REMOTE_IMPL', 'remote_impl')
- + attr('FUNC_API_COMPOSITOR_IMPL', 'compositor_impl')
- + attr('FUNC_API_CLIENT_IMPL', 'client_impl')
- + attr('FUNC_API_CLIENT_IGNORE', 'client_ignore')
- + (P('FUNC_') * rep(alpha) * opt(fill * paren(rep(1 - P(')') * any))))
-)
-
-local void = P('void') * wb
-
-local api_param_type = (
- (word('Error') * opt_ptr * Cc('error'))
- + (word('Arena') * opt_ptr * Cc('arena'))
- + (word('lua_State') * opt_ptr * Cc('lstate'))
-)
-
-local ctype = C(
- opt(word('const'))
- * (
- typed_container
- -- 'unsigned' is a type modifier, and a type itself
- + (word('unsigned char') + word('unsigned'))
- + (word('struct') * fill * id)
- + id
- )
- * opt(word('const'))
- * opt_ptr
-)
-
-local return_type = (C(void) * fill) + ctype
-
--- stylua: ignore start
-local params = Ct(
- (void * #P(')'))
- + comma1(Ct(
- (api_param_type + ctype)
- * fill
- * C(id)
- * rep(Pf('[') * rep(alpha) * Pf(']'))
- * rep(fill * fattr)
- ))
- * opt(Pf(',') * P('...'))
-)
--- stylua: ignore end
-
-local ignore_line = rep1(1 - nl) * nl
-local empty_line = Ct(Cc('empty') * nl * nl)
-
-local proto_name = opt_ptr * fill * id
-
--- __inline is used in MSVC
-local decl_mod = (
- Cg(word('static') * Cc(true), 'static')
- + Cg((word('inline') + word('__inline')) * Cc(true), 'inline')
-)
-
-local proto = Ct(
- Cg(Cp(), 'pos')
- * Cc('proto')
- * -#P('typedef')
- * #alpha
- * opt(P('DLLEXPORT') * rep1(ws))
- * rep(decl_mod)
- * Cg(return_type, 'return_type')
- * fill
- * Cg(proto_name, 'name')
- * fill
- * paren(Cg(params, 'parameters'))
- * Cg(Cc(false), 'fast')
- * rep(fill * fattr)
- * Cg(Cp(), 'endpos')
- * (fill * (S(';') + braces))
-)
-
-local keyset_field = Ct(
- Cg(ctype, 'type')
- * fill
- * Cg(id, 'name')
- * fill
- * opt(P('DictKey') * paren(Cg(rep1(1 - P(')')), 'dict_key')))
- * Pf(';')
-)
-
-local keyset = Ct(
- P('typedef')
- * word('struct')
- * Pf('{')
- * Cg(Ct(rep1(keyset_field)), 'fields')
- * Pf('}')
- * P('Dict')
- * paren(Cg(id, 'keyset_name'))
- * Pf(';')
-)
-
-local grammar =
- Ct(rep1(empty_line + proto + cdoc_comment + comment + preproc + ws + keyset + ignore_line))
-
-if arg[1] == '--test' then
- for i, t in ipairs({
- 'void multiqueue_put_event(MultiQueue *self, Event event) {} ',
- 'void *xmalloc(size_t size) {} ',
- {
- 'struct tm *os_localtime_r(const time_t *restrict clock,',
- ' struct tm *restrict result) FUNC_ATTR_NONNULL_ALL {}',
- },
- {
- '_Bool',
- '# 163 "src/nvim/event/multiqueue.c"',
- ' multiqueue_empty(MultiQueue *self)',
- '{}',
- },
- 'const char *find_option_end(const char *arg, OptIndex *opt_idxp) {}',
- 'bool semsg(const char *const fmt, ...) {}',
- 'int32_t utf_ptr2CharInfo_impl(uint8_t const *p, uintptr_t const len) {}',
- 'void ex_argdedupe(exarg_T *eap FUNC_ATTR_UNUSED) {}',
- 'static TermKeySym register_c0(TermKey *tk, TermKeySym sym, unsigned char ctrl, const char *name) {}',
- 'unsigned get_bkc_flags(buf_T *buf) {}',
- 'char *xstpcpy(char *restrict dst, const char *restrict src) {}',
- 'bool try_leave(const TryState *const tstate, Error *const err) {}',
- 'void api_set_error(ErrorType errType) {}',
- {
- 'void nvim_subscribe(uint64_t channel_id, String event)',
- 'FUNC_API_SINCE(1) FUNC_API_DEPRECATED_SINCE(13) FUNC_API_REMOTE_ONLY',
- '{}',
- },
-
- -- Do not consume leading preproc statements
- {
- '#line 1 "D:/a/neovim/neovim/src\\nvim/mark.h"',
- 'static __inline int mark_global_index(const char name)',
- ' FUNC_ATTR_CONST',
- '{}',
- },
- {
- '',
- '#line 1 "D:/a/neovim/neovim/src\\nvim/mark.h"',
- 'static __inline int mark_global_index(const char name)',
- '{}',
- },
- {
- 'size_t xstrlcpy(char *__restrict dst, const char *__restrict src, size_t dsize)',
- ' FUNC_ATTR_NONNULL_ALL',
- ' {}',
- },
- }) do
- if type(t) == 'table' then
- t = table.concat(t, '\n') .. '\n'
- end
- t = t:gsub(' +', ' ')
- local r = grammar:match(t)
- if not r then
- print('Test ' .. i .. ' failed')
- print(' |' .. table.concat(vim.split(t, '\n'), '\n |'))
- end
- end
-end
-
-return {
- grammar = grammar --[[@as nvim.c_grammar]],
- typed_container = typed_container,
-}
diff --git a/src/nvim/generators/dump_bin_array.lua b/src/nvim/generators/dump_bin_array.lua
deleted file mode 100644
index c6cda25e73..0000000000
--- a/src/nvim/generators/dump_bin_array.lua
+++ /dev/null
@@ -1,17 +0,0 @@
-local function dump_bin_array(output, name, data)
- output:write([[
- static const uint8_t ]] .. name .. [[[] = {
-]])
-
- for i = 1, #data do
- output:write(string.byte(data, i) .. ', ')
- if i % 10 == 0 then
- output:write('\n ')
- end
- end
- output:write([[
-};
-]])
-end
-
-return dump_bin_array
diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua
deleted file mode 100644
index 378297d86a..0000000000
--- a/src/nvim/generators/gen_api_dispatch.lua
+++ /dev/null
@@ -1,990 +0,0 @@
--- Example (manual) invocation:
---
--- make
--- cp build/nvim_version.lua src/nvim/
--- cd src/nvim
--- nvim -l generators/gen_api_dispatch.lua "../../build/src/nvim/auto/api/private/dispatch_wrappers.generated.h" "../../build/src/nvim/auto/api/private/api_metadata.generated.h" "../../build/funcs_metadata.mpack" "../../build/src/nvim/auto/lua_api_c_bindings.generated.h" "../../build/src/nvim/auto/keysets_defs.generated.h" "../../build/ui_metadata.mpack" "../../build/cmake.config/auto/versiondef_git.h" "./api/autocmd.h" "./api/buffer.h" "./api/command.h" "./api/deprecated.h" "./api/extmark.h" "./api/keysets_defs.h" "./api/options.h" "./api/tabpage.h" "./api/ui.h" "./api/vim.h" "./api/vimscript.h" "./api/win_config.h" "./api/window.h" "../../build/include/api/autocmd.h.generated.h" "../../build/include/api/buffer.h.generated.h" "../../build/include/api/command.h.generated.h" "../../build/include/api/deprecated.h.generated.h" "../../build/include/api/extmark.h.generated.h" "../../build/include/api/options.h.generated.h" "../../build/include/api/tabpage.h.generated.h" "../../build/include/api/ui.h.generated.h" "../../build/include/api/vim.h.generated.h" "../../build/include/api/vimscript.h.generated.h" "../../build/include/api/win_config.h.generated.h" "../../build/include/api/window.h.generated.h"
-
-local mpack = vim.mpack
-
-local hashy = require 'generators.hashy'
-
-local pre_args = 7
-assert(#arg >= pre_args)
--- output h file with generated dispatch functions (dispatch_wrappers.generated.h)
-local dispatch_outputf = arg[1]
--- output h file with packed metadata (api_metadata.generated.h)
-local api_metadata_outputf = arg[2]
--- output metadata mpack file, for use by other build scripts (funcs_metadata.mpack)
-local mpack_outputf = arg[3]
-local lua_c_bindings_outputf = arg[4] -- lua_api_c_bindings.generated.c
-local keysets_outputf = arg[5] -- keysets_defs.generated.h
-local ui_metadata_inputf = arg[6] -- ui events metadata
-local git_version_inputf = arg[7] -- git version header
-
-local functions = {}
-
--- names of all headers relative to the source root (for inclusion in the
--- generated file)
-local headers = {}
-
--- set of function names, used to detect duplicates
-local function_names = {}
-
-local c_grammar = require('generators.c_grammar')
-
-local startswith = vim.startswith
-
-local function add_function(fn)
- local public = startswith(fn.name, 'nvim_') or fn.deprecated_since
- if public and not fn.noexport then
- functions[#functions + 1] = fn
- function_names[fn.name] = true
- if
- #fn.parameters >= 2
- and fn.parameters[2][1] == 'Array'
- and fn.parameters[2][2] == 'uidata'
- then
- -- function receives the "args" as a parameter
- fn.receives_array_args = true
- -- remove the args parameter
- table.remove(fn.parameters, 2)
- end
- if #fn.parameters ~= 0 and fn.parameters[1][2] == 'channel_id' then
- -- this function should receive the channel id
- fn.receives_channel_id = true
- -- remove the parameter since it won't be passed by the api client
- table.remove(fn.parameters, 1)
- end
- if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'error' then
- -- function can fail if the last parameter type is 'Error'
- fn.can_fail = true
- -- remove the error parameter, msgpack has it's own special field
- -- for specifying errors
- fn.parameters[#fn.parameters] = nil
- end
- if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'lstate' then
- fn.has_lua_imp = true
- fn.parameters[#fn.parameters] = nil
- end
- if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'arena' then
- fn.receives_arena = true
- fn.parameters[#fn.parameters] = nil
- end
- end
-end
-
-local keysets = {}
-
-local function add_keyset(val)
- local keys = {}
- local types = {}
- local c_names = {}
- local is_set_name = 'is_set__' .. val.keyset_name .. '_'
- local has_optional = false
- for i, field in ipairs(val.fields) do
- local dict_key = field.dict_key or field.name
- if field.type ~= 'Object' then
- types[dict_key] = field.type
- end
- if field.name ~= is_set_name and field.type ~= 'OptionalKeys' then
- table.insert(keys, dict_key)
- if dict_key ~= field.name then
- c_names[dict_key] = field.name
- end
- else
- if i > 1 then
- error("'is_set__{type}_' must be first if present")
- elseif field.name ~= is_set_name then
- error(val.keyset_name .. ': name of first key should be ' .. is_set_name)
- elseif field.type ~= 'OptionalKeys' then
- error("'" .. is_set_name .. "' must have type 'OptionalKeys'")
- end
- has_optional = true
- end
- end
- table.insert(keysets, {
- name = val.keyset_name,
- keys = keys,
- c_names = c_names,
- types = types,
- has_optional = has_optional,
- })
-end
-
-local ui_options_text = nil
-
--- read each input file, parse and append to the api metadata
-for i = pre_args + 1, #arg do
- local full_path = arg[i]
- local parts = {}
- for part in string.gmatch(full_path, '[^/]+') do
- parts[#parts + 1] = part
- end
- headers[#headers + 1] = parts[#parts - 1] .. '/' .. parts[#parts]
-
- local input = assert(io.open(full_path, 'rb'))
-
- local text = input:read('*all')
- local tmp = c_grammar.grammar:match(text)
- for j = 1, #tmp do
- local val = tmp[j]
- if val.keyset_name then
- add_keyset(val)
- elseif val.name then
- add_function(val)
- end
- end
-
- ui_options_text = ui_options_text or string.match(text, 'ui_ext_names%[][^{]+{([^}]+)}')
- input:close()
-end
-
-local function shallowcopy(orig)
- local copy = {}
- for orig_key, orig_value in pairs(orig) do
- copy[orig_key] = orig_value
- end
- return copy
-end
-
--- Export functions under older deprecated names.
--- These will be removed eventually.
-local deprecated_aliases = require('api.dispatch_deprecated')
-for _, f in ipairs(shallowcopy(functions)) do
- local ismethod = false
- if startswith(f.name, 'nvim_') then
- if startswith(f.name, 'nvim__') or f.name == 'nvim_error_event' then
- f.since = -1
- elseif f.since == nil then
- print('Function ' .. f.name .. ' lacks since field.\n')
- os.exit(1)
- end
- f.since = tonumber(f.since)
- if f.deprecated_since ~= nil then
- f.deprecated_since = tonumber(f.deprecated_since)
- end
-
- if startswith(f.name, 'nvim_buf_') then
- ismethod = true
- elseif startswith(f.name, 'nvim_win_') then
- ismethod = true
- elseif startswith(f.name, 'nvim_tabpage_') then
- ismethod = true
- end
- f.remote = f.remote_only or not f.lua_only
- f.lua = f.lua_only or not f.remote_only
- f.eval = (not f.lua_only) and not f.remote_only
- else
- f.deprecated_since = tonumber(f.deprecated_since)
- assert(f.deprecated_since == 1)
- f.remote = true
- f.since = 0
- end
- f.method = ismethod
- local newname = deprecated_aliases[f.name]
- if newname ~= nil then
- if function_names[newname] then
- -- duplicate
- print(
- 'Function '
- .. f.name
- .. ' has deprecated alias\n'
- .. newname
- .. ' which has a separate implementation.\n'
- .. 'Please remove it from src/nvim/api/dispatch_deprecated.lua'
- )
- os.exit(1)
- end
- local newf = shallowcopy(f)
- newf.name = newname
- if newname == 'ui_try_resize' then
- -- The return type was incorrectly set to Object in 0.1.5.
- -- Keep it that way for clients that rely on this.
- newf.return_type = 'Object'
- end
- newf.impl_name = f.name
- newf.lua = false
- newf.eval = false
- newf.since = 0
- newf.deprecated_since = 1
- functions[#functions + 1] = newf
- end
-end
-
--- don't expose internal attributes like "impl_name" in public metadata
-local exported_attributes = { 'name', 'return_type', 'method', 'since', 'deprecated_since' }
-local exported_functions = {}
-for _, f in ipairs(functions) do
- if not (startswith(f.name, 'nvim__') or f.name == 'nvim_error_event' or f.name == 'redraw') then
- local f_exported = {}
- for _, attr in ipairs(exported_attributes) do
- f_exported[attr] = f[attr]
- end
- f_exported.parameters = {}
- for i, param in ipairs(f.parameters) do
- if param[1] == 'DictOf(LuaRef)' then
- param = { 'Dict', param[2] }
- elseif startswith(param[1], 'Dict(') then
- param = { 'Dict', param[2] }
- end
- f_exported.parameters[i] = param
- end
- if startswith(f.return_type, 'Dict(') then
- f_exported.return_type = 'Dict'
- end
- exported_functions[#exported_functions + 1] = f_exported
- end
-end
-
-local ui_options = { 'rgb' }
-for x in string.gmatch(ui_options_text, '"([a-z][a-z_]+)"') do
- table.insert(ui_options, x)
-end
-
-local version = require 'nvim_version' -- `build/nvim_version.lua` file.
-local git_version = io.open(git_version_inputf):read '*a'
-local version_build = string.match(git_version, '#define NVIM_VERSION_BUILD "([^"]+)"') or vim.NIL
-
--- serialize the API metadata using msgpack and embed into the resulting
--- binary for easy querying by clients
-local api_metadata_output = assert(io.open(api_metadata_outputf, 'wb'))
-local pieces = {}
-
--- Naively using mpack.encode({foo=x, bar=y}) will make the build
--- "non-reproducible". Emit maps directly as FIXDICT(2) "foo" x "bar" y instead
-local function fixdict(num)
- if num > 15 then
- error 'implement more dict codes'
- end
- table.insert(pieces, string.char(128 + num))
-end
-local function put(item, item2)
- table.insert(pieces, mpack.encode(item))
- if item2 ~= nil then
- table.insert(pieces, mpack.encode(item2))
- end
-end
-
-fixdict(6)
-
-put('version')
-fixdict(1 + #version)
-for _, item in ipairs(version) do
- -- NB: all items are mandatory. But any error will be less confusing
- -- with placeholder vim.NIL (than invalid mpack data)
- local val = item[2] == nil and vim.NIL or item[2]
- put(item[1], val)
-end
-put('build', version_build)
-
-put('functions', exported_functions)
-put('ui_events')
-table.insert(pieces, io.open(ui_metadata_inputf, 'rb'):read('*all'))
-put('ui_options', ui_options)
-
-put('error_types')
-fixdict(2)
-put('Exception', { id = 0 })
-put('Validation', { id = 1 })
-
-put('types')
-local types =
- { { 'Buffer', 'nvim_buf_' }, { 'Window', 'nvim_win_' }, { 'Tabpage', 'nvim_tabpage_' } }
-fixdict(#types)
-for i, item in ipairs(types) do
- put(item[1])
- fixdict(2)
- put('id', i - 1)
- put('prefix', item[2])
-end
-
-local packed = table.concat(pieces)
-local dump_bin_array = require('generators.dump_bin_array')
-dump_bin_array(api_metadata_output, 'packed_api_metadata', packed)
-api_metadata_output:close()
-
--- start building the dispatch wrapper output
-local output = assert(io.open(dispatch_outputf, 'wb'))
-
-local keysets_defs = assert(io.open(keysets_outputf, 'wb'))
-
--- ===========================================================================
--- NEW API FILES MUST GO HERE.
---
--- When creating a new API file, you must include it here,
--- so that the dispatcher can find the C functions that you are creating!
--- ===========================================================================
-output:write([[
-#include "nvim/errors.h"
-#include "nvim/ex_docmd.h"
-#include "nvim/ex_getln.h"
-#include "nvim/globals.h"
-#include "nvim/log.h"
-#include "nvim/map_defs.h"
-
-#include "nvim/api/autocmd.h"
-#include "nvim/api/buffer.h"
-#include "nvim/api/command.h"
-#include "nvim/api/deprecated.h"
-#include "nvim/api/extmark.h"
-#include "nvim/api/options.h"
-#include "nvim/api/tabpage.h"
-#include "nvim/api/ui.h"
-#include "nvim/api/vim.h"
-#include "nvim/api/vimscript.h"
-#include "nvim/api/win_config.h"
-#include "nvim/api/window.h"
-#include "nvim/ui_client.h"
-
-]])
-
-keysets_defs:write('// IWYU pragma: private, include "nvim/api/private/dispatch.h"\n\n')
-
-for _, k in ipairs(keysets) do
- local neworder, hashfun = hashy.hashy_hash(k.name, k.keys, function(idx)
- return k.name .. '_table[' .. idx .. '].str'
- end)
-
- keysets_defs:write('extern KeySetLink ' .. k.name .. '_table[' .. (1 + #neworder) .. '];\n')
-
- local function typename(type)
- if type == 'HLGroupID' then
- return 'kObjectTypeInteger'
- elseif not type or vim.startswith(type, 'Union') then
- return 'kObjectTypeNil'
- elseif vim.startswith(type, 'LuaRefOf') then
- return 'kObjectTypeLuaRef'
- elseif type == 'StringArray' then
- return 'kUnpackTypeStringArray'
- elseif vim.startswith(type, 'ArrayOf') then
- return 'kObjectTypeArray'
- else
- return 'kObjectType' .. type
- end
- end
-
- output:write('KeySetLink ' .. k.name .. '_table[] = {\n')
- for i, key in ipairs(neworder) do
- local ind = -1
- if k.has_optional then
- ind = i
- keysets_defs:write('#define KEYSET_OPTIDX_' .. k.name .. '__' .. key .. ' ' .. ind .. '\n')
- end
- output:write(
- ' {"'
- .. key
- .. '", offsetof(KeyDict_'
- .. k.name
- .. ', '
- .. (k.c_names[key] or key)
- .. '), '
- .. typename(k.types[key])
- .. ', '
- .. ind
- .. ', '
- .. (k.types[key] == 'HLGroupID' and 'true' or 'false')
- .. '},\n'
- )
- end
- output:write(' {NULL, 0, kObjectTypeNil, -1, false},\n')
- output:write('};\n\n')
-
- output:write(hashfun)
-
- output:write([[
-KeySetLink *KeyDict_]] .. k.name .. [[_get_field(const char *str, size_t len)
-{
- int hash = ]] .. k.name .. [[_hash(str, len);
- if (hash == -1) {
- return NULL;
- }
- return &]] .. k.name .. [[_table[hash];
-}
-
-]])
-end
-
-local function real_type(type)
- local rv = type
- local rmatch = string.match(type, 'Dict%(([_%w]+)%)')
- if rmatch then
- return 'KeyDict_' .. rmatch
- elseif c_grammar.typed_container:match(rv) then
- if rv:match('Array') then
- rv = 'Array'
- else
- rv = 'Dict'
- end
- end
- return rv
-end
-
-local function attr_name(rt)
- if rt == 'Float' then
- return 'floating'
- else
- return rt:lower()
- end
-end
-
--- start the handler functions. Visit each function metadata to build the
--- handler function with code generated for validating arguments and calling to
--- the real API.
-for i = 1, #functions do
- local fn = functions[i]
- if fn.impl_name == nil and fn.remote then
- local args = {}
-
- output:write(
- 'Object handle_' .. fn.name .. '(uint64_t channel_id, Array args, Arena* arena, Error *error)'
- )
- output:write('\n{')
- output:write('\n#ifdef NVIM_LOG_DEBUG')
- output:write('\n DLOG("RPC: ch %" PRIu64 ": invoke ' .. fn.name .. '", channel_id);')
- output:write('\n#endif')
- output:write('\n Object ret = NIL;')
- -- Declare/initialize variables that will hold converted arguments
- for j = 1, #fn.parameters do
- local param = fn.parameters[j]
- local rt = real_type(param[1])
- local converted = 'arg_' .. j
- output:write('\n ' .. rt .. ' ' .. converted .. ';')
- end
- output:write('\n')
- if not fn.receives_array_args then
- output:write('\n if (args.size != ' .. #fn.parameters .. ') {')
- output:write(
- '\n api_set_error(error, kErrorTypeException, \
- "Wrong number of arguments: expecting '
- .. #fn.parameters
- .. ' but got %zu", args.size);'
- )
- output:write('\n goto cleanup;')
- output:write('\n }\n')
- end
-
- -- Validation/conversion for each argument
- for j = 1, #fn.parameters do
- local converted, param
- param = fn.parameters[j]
- converted = 'arg_' .. j
- local rt = real_type(param[1])
- if rt == 'Object' then
- output:write('\n ' .. converted .. ' = args.items[' .. (j - 1) .. '];\n')
- elseif rt:match('^KeyDict_') then
- converted = '&' .. converted
- output:write('\n if (args.items[' .. (j - 1) .. '].type == kObjectTypeDict) {') --luacheck: ignore 631
- output:write('\n memset(' .. converted .. ', 0, sizeof(*' .. converted .. '));') -- TODO: neeeee
- output:write(
- '\n if (!api_dict_to_keydict('
- .. converted
- .. ', '
- .. rt
- .. '_get_field, args.items['
- .. (j - 1)
- .. '].data.dict, error)) {'
- )
- output:write('\n goto cleanup;')
- output:write('\n }')
- output:write(
- '\n } else if (args.items['
- .. (j - 1)
- .. '].type == kObjectTypeArray && args.items['
- .. (j - 1)
- .. '].data.array.size == 0) {'
- ) --luacheck: ignore 631
- output:write('\n memset(' .. converted .. ', 0, sizeof(*' .. converted .. '));')
-
- output:write('\n } else {')
- output:write(
- '\n api_set_error(error, kErrorTypeException, \
- "Wrong type for argument '
- .. j
- .. ' when calling '
- .. fn.name
- .. ', expecting '
- .. param[1]
- .. '");'
- )
- output:write('\n goto cleanup;')
- output:write('\n }\n')
- else
- if rt:match('^Buffer$') or rt:match('^Window$') or rt:match('^Tabpage$') then
- -- Buffer, Window, and Tabpage have a specific type, but are stored in integer
- output:write(
- '\n if (args.items['
- .. (j - 1)
- .. '].type == kObjectType'
- .. rt
- .. ' && args.items['
- .. (j - 1)
- .. '].data.integer >= 0) {'
- )
- output:write(
- '\n ' .. converted .. ' = (handle_T)args.items[' .. (j - 1) .. '].data.integer;'
- )
- else
- output:write('\n if (args.items[' .. (j - 1) .. '].type == kObjectType' .. rt .. ') {')
- output:write(
- '\n '
- .. converted
- .. ' = args.items['
- .. (j - 1)
- .. '].data.'
- .. attr_name(rt)
- .. ';'
- )
- end
- if
- rt:match('^Buffer$')
- or rt:match('^Window$')
- or rt:match('^Tabpage$')
- or rt:match('^Boolean$')
- then
- -- accept nonnegative integers for Booleans, Buffers, Windows and Tabpages
- output:write(
- '\n } else if (args.items['
- .. (j - 1)
- .. '].type == kObjectTypeInteger && args.items['
- .. (j - 1)
- .. '].data.integer >= 0) {'
- )
- output:write(
- '\n ' .. converted .. ' = (handle_T)args.items[' .. (j - 1) .. '].data.integer;'
- )
- end
- if rt:match('^Float$') then
- -- accept integers for Floats
- output:write('\n } else if (args.items[' .. (j - 1) .. '].type == kObjectTypeInteger) {')
- output:write(
- '\n ' .. converted .. ' = (Float)args.items[' .. (j - 1) .. '].data.integer;'
- )
- end
- -- accept empty lua tables as empty dictionaries
- if rt:match('^Dict') then
- output:write(
- '\n } else if (args.items['
- .. (j - 1)
- .. '].type == kObjectTypeArray && args.items['
- .. (j - 1)
- .. '].data.array.size == 0) {'
- ) --luacheck: ignore 631
- output:write('\n ' .. converted .. ' = (Dict)ARRAY_DICT_INIT;')
- end
- output:write('\n } else {')
- output:write(
- '\n api_set_error(error, kErrorTypeException, \
- "Wrong type for argument '
- .. j
- .. ' when calling '
- .. fn.name
- .. ', expecting '
- .. param[1]
- .. '");'
- )
- output:write('\n goto cleanup;')
- output:write('\n }\n')
- end
- args[#args + 1] = converted
- end
-
- if fn.textlock then
- output:write('\n if (text_locked()) {')
- output:write('\n api_set_error(error, kErrorTypeException, "%s", get_text_locked_msg());')
- output:write('\n goto cleanup;')
- output:write('\n }\n')
- elseif fn.textlock_allow_cmdwin then
- output:write('\n if (textlock != 0 || expr_map_locked()) {')
- output:write('\n api_set_error(error, kErrorTypeException, "%s", e_textlock);')
- output:write('\n goto cleanup;')
- output:write('\n }\n')
- end
-
- -- function call
- output:write('\n ')
- if fn.return_type ~= 'void' then
- -- has a return value, prefix the call with a declaration
- output:write(fn.return_type .. ' rv = ')
- end
-
- -- write the function name and the opening parenthesis
- output:write(fn.name .. '(')
-
- local call_args = {}
- if fn.receives_channel_id then
- table.insert(call_args, 'channel_id')
- end
-
- if fn.receives_array_args then
- table.insert(call_args, 'args')
- end
-
- for _, a in ipairs(args) do
- table.insert(call_args, a)
- end
-
- if fn.receives_arena then
- table.insert(call_args, 'arena')
- end
-
- if fn.has_lua_imp then
- table.insert(call_args, 'NULL')
- end
-
- if fn.can_fail then
- table.insert(call_args, 'error')
- end
-
- output:write(table.concat(call_args, ', '))
- output:write(');\n')
-
- if fn.can_fail then
- -- if the function can fail, also pass a pointer to the local error object
- -- and check for the error
- output:write('\n if (ERROR_SET(error)) {')
- output:write('\n goto cleanup;')
- output:write('\n }\n')
- end
-
- local ret_type = real_type(fn.return_type)
- if string.match(ret_type, '^KeyDict_') then
- local table = string.sub(ret_type, 9) .. '_table'
- output:write(
- '\n ret = DICT_OBJ(api_keydict_to_dict(&rv, '
- .. table
- .. ', ARRAY_SIZE('
- .. table
- .. '), arena));'
- )
- elseif ret_type ~= 'void' then
- output:write('\n ret = ' .. string.upper(real_type(fn.return_type)) .. '_OBJ(rv);')
- end
- output:write('\n\ncleanup:')
-
- output:write('\n return ret;\n}\n\n')
- end
-end
-
-local remote_fns = {}
-for _, fn in ipairs(functions) do
- if fn.remote then
- remote_fns[fn.name] = fn
- end
-end
-remote_fns.redraw = { impl_name = 'ui_client_redraw', fast = true }
-
-local names = vim.tbl_keys(remote_fns)
-table.sort(names)
-local hashorder, hashfun = hashy.hashy_hash('msgpack_rpc_get_handler_for', names, function(idx)
- return 'method_handlers[' .. idx .. '].name'
-end)
-
-output:write('const MsgpackRpcRequestHandler method_handlers[] = {\n')
-for n, name in ipairs(hashorder) do
- local fn = remote_fns[name]
- fn.handler_id = n - 1
- output:write(
- ' { .name = "'
- .. name
- .. '", .fn = handle_'
- .. (fn.impl_name or fn.name)
- .. ', .fast = '
- .. tostring(fn.fast)
- .. ', .ret_alloc = '
- .. tostring(not not fn.ret_alloc)
- .. '},\n'
- )
-end
-output:write('};\n\n')
-output:write(hashfun)
-
-output:close()
-
-functions.keysets = keysets
-local mpack_output = assert(io.open(mpack_outputf, 'wb'))
-mpack_output:write(mpack.encode(functions))
-mpack_output:close()
-
-local function include_headers(output_handle, headers_to_include)
- for i = 1, #headers_to_include do
- if headers_to_include[i]:sub(-12) ~= '.generated.h' then
- output_handle:write('\n#include "nvim/' .. headers_to_include[i] .. '"')
- end
- end
-end
-
-local function write_shifted_output(str, ...)
- str = str:gsub('\n ', '\n')
- str = str:gsub('^ ', '')
- str = str:gsub(' +$', '')
- output:write(string.format(str, ...))
-end
-
--- start building lua output
-output = assert(io.open(lua_c_bindings_outputf, 'wb'))
-
-include_headers(output, headers)
-output:write('\n')
-
-local lua_c_functions = {}
-
-local function process_function(fn)
- local lua_c_function_name = ('nlua_api_%s'):format(fn.name)
- write_shifted_output(
- [[
-
- static int %s(lua_State *lstate)
- {
- Error err = ERROR_INIT;
- Arena arena = ARENA_EMPTY;
- char *err_param = 0;
- if (lua_gettop(lstate) != %i) {
- api_set_error(&err, kErrorTypeValidation, "Expected %i argument%s");
- goto exit_0;
- }
- ]],
- lua_c_function_name,
- #fn.parameters,
- #fn.parameters,
- (#fn.parameters == 1) and '' or 's'
- )
- lua_c_functions[#lua_c_functions + 1] = {
- binding = lua_c_function_name,
- api = fn.name,
- }
-
- if not fn.fast then
- write_shifted_output(
- [[
- if (!nlua_is_deferred_safe()) {
- return luaL_error(lstate, e_fast_api_disabled, "%s");
- }
- ]],
- fn.name
- )
- end
-
- if fn.textlock then
- write_shifted_output([[
- if (text_locked()) {
- api_set_error(&err, kErrorTypeException, "%%s", get_text_locked_msg());
- goto exit_0;
- }
- ]])
- elseif fn.textlock_allow_cmdwin then
- write_shifted_output([[
- if (textlock != 0 || expr_map_locked()) {
- api_set_error(&err, kErrorTypeException, "%%s", e_textlock);
- goto exit_0;
- }
- ]])
- end
-
- local cparams = ''
- local free_code = {}
- for j = #fn.parameters, 1, -1 do
- local param = fn.parameters[j]
- local cparam = string.format('arg%u', j)
- local param_type = real_type(param[1])
- local extra = param_type == 'Dict' and 'false, ' or ''
- local arg_free_code = ''
- if param[1] == 'Object' then
- extra = 'true, '
- arg_free_code = ' api_luarefs_free_object(' .. cparam .. ');'
- elseif param[1] == 'DictOf(LuaRef)' then
- extra = 'true, '
- arg_free_code = ' api_luarefs_free_dict(' .. cparam .. ');'
- elseif param[1] == 'LuaRef' then
- arg_free_code = ' api_free_luaref(' .. cparam .. ');'
- end
- local errshift = 0
- local seterr = ''
- if string.match(param_type, '^KeyDict_') then
- write_shifted_output(
- [[
- %s %s = KEYDICT_INIT;
- nlua_pop_keydict(lstate, &%s, %s_get_field, &err_param, &arena, &err);
- ]],
- param_type,
- cparam,
- cparam,
- param_type
- )
- cparam = '&' .. cparam
- errshift = 1 -- free incomplete dict on error
- arg_free_code = ' api_luarefs_free_keydict('
- .. cparam
- .. ', '
- .. string.sub(param_type, 9)
- .. '_table);'
- else
- write_shifted_output(
- [[
- const %s %s = nlua_pop_%s(lstate, %s&arena, &err);]],
- param[1],
- cparam,
- param_type,
- extra
- )
- seterr = '\n err_param = "' .. param[2] .. '";'
- end
-
- write_shifted_output([[
-
- if (ERROR_SET(&err)) {]] .. seterr .. [[
-
- goto exit_%u;
- }
-
- ]], #fn.parameters - j + errshift)
- free_code[#free_code + 1] = arg_free_code
- cparams = cparam .. ', ' .. cparams
- end
- if fn.receives_channel_id then
- cparams = 'LUA_INTERNAL_CALL, ' .. cparams
- end
- if fn.receives_arena then
- cparams = cparams .. '&arena, '
- end
-
- if fn.has_lua_imp then
- cparams = cparams .. 'lstate, '
- end
-
- if fn.can_fail then
- cparams = cparams .. '&err'
- else
- cparams = cparams:gsub(', $', '')
- end
- local free_at_exit_code = ''
- for i = 1, #free_code do
- local rev_i = #free_code - i + 1
- local code = free_code[rev_i]
- if i == 1 and not string.match(real_type(fn.parameters[1][1]), '^KeyDict_') then
- free_at_exit_code = free_at_exit_code .. ('\n%s'):format(code)
- else
- free_at_exit_code = free_at_exit_code .. ('\nexit_%u:\n%s'):format(rev_i, code)
- end
- end
- local err_throw_code = [[
-
-exit_0:
- arena_mem_free(arena_finish(&arena));
- if (ERROR_SET(&err)) {
- luaL_where(lstate, 1);
- if (err_param) {
- lua_pushstring(lstate, "Invalid '");
- lua_pushstring(lstate, err_param);
- lua_pushstring(lstate, "': ");
- }
- lua_pushstring(lstate, err.msg);
- api_clear_error(&err);
- lua_concat(lstate, err_param ? 5 : 2);
- return lua_error(lstate);
- }
-]]
- local return_type
- if fn.return_type ~= 'void' then
- if fn.return_type:match('^ArrayOf') then
- return_type = 'Array'
- else
- return_type = fn.return_type
- end
- local free_retval = ''
- if fn.ret_alloc then
- free_retval = ' api_free_' .. return_type:lower() .. '(ret);'
- end
- write_shifted_output(' %s ret = %s(%s);\n', fn.return_type, fn.name, cparams)
-
- local ret_type = real_type(fn.return_type)
- local ret_mode = (ret_type == 'Object') and '&' or ''
- if fn.has_lua_imp then
- -- only push onto the Lua stack if we haven't already
- write_shifted_output(
- [[
- if (lua_gettop(lstate) == 0) {
- nlua_push_%s(lstate, %sret, kNluaPushSpecial | kNluaPushFreeRefs);
- }
- ]],
- return_type,
- ret_mode
- )
- elseif string.match(ret_type, '^KeyDict_') then
- write_shifted_output(
- ' nlua_push_keydict(lstate, &ret, %s_table);\n',
- string.sub(ret_type, 9)
- )
- else
- local special = (fn.since ~= nil and fn.since < 11)
- write_shifted_output(
- ' nlua_push_%s(lstate, %sret, %s | kNluaPushFreeRefs);\n',
- return_type,
- ret_mode,
- special and 'kNluaPushSpecial' or '0'
- )
- end
-
- -- NOTE: we currently assume err_throw needs nothing from arena
- write_shifted_output(
- [[
- %s
- %s
- %s
- return 1;
- ]],
- free_retval,
- free_at_exit_code,
- err_throw_code
- )
- else
- write_shifted_output(
- [[
- %s(%s);
- %s
- %s
- return 0;
- ]],
- fn.name,
- cparams,
- free_at_exit_code,
- err_throw_code
- )
- end
- write_shifted_output([[
- }
- ]])
-end
-
-for _, fn in ipairs(functions) do
- if fn.lua or fn.name:sub(1, 4) == '_vim' then
- process_function(fn)
- end
-end
-
-output:write(string.format(
- [[
-void nlua_add_api_functions(lua_State *lstate)
-{
- lua_createtable(lstate, 0, %u);
-]],
- #lua_c_functions
-))
-for _, func in ipairs(lua_c_functions) do
- output:write(string.format(
- [[
-
- lua_pushcfunction(lstate, &%s);
- lua_setfield(lstate, -2, "%s");]],
- func.binding,
- func.api
- ))
-end
-output:write([[
-
- lua_setfield(lstate, -2, "api");
-}
-]])
-
-output:close()
-keysets_defs:close()
diff --git a/src/nvim/generators/gen_api_ui_events.lua b/src/nvim/generators/gen_api_ui_events.lua
deleted file mode 100644
index a3bb76cb91..0000000000
--- a/src/nvim/generators/gen_api_ui_events.lua
+++ /dev/null
@@ -1,219 +0,0 @@
-local mpack = vim.mpack
-
-assert(#arg == 5)
-local input = io.open(arg[1], 'rb')
-local call_output = io.open(arg[2], 'wb')
-local remote_output = io.open(arg[3], 'wb')
-local metadata_output = io.open(arg[4], 'wb')
-local client_output = io.open(arg[5], 'wb')
-
-local c_grammar = require('generators.c_grammar')
-local events = c_grammar.grammar:match(input:read('*all'))
-
-local hashy = require 'generators.hashy'
-
-local function write_signature(output, ev, prefix, notype)
- output:write('(' .. prefix)
- if prefix == '' and #ev.parameters == 0 then
- output:write('void')
- end
- for j = 1, #ev.parameters do
- if j > 1 or prefix ~= '' then
- output:write(', ')
- end
- local param = ev.parameters[j]
- if not notype then
- output:write(param[1] .. ' ')
- end
- output:write(param[2])
- end
- output:write(')')
-end
-
-local function write_arglist(output, ev)
- if #ev.parameters == 0 then
- return
- end
- output:write(' MAXSIZE_TEMP_ARRAY(args, ' .. #ev.parameters .. ');\n')
- for j = 1, #ev.parameters do
- local param = ev.parameters[j]
- local kind = string.upper(param[1])
- output:write(' ADD_C(args, ')
- output:write(kind .. '_OBJ(' .. param[2] .. ')')
- output:write(');\n')
- end
-end
-
-local function call_ui_event_method(output, ev)
- output:write('void ui_client_event_' .. ev.name .. '(Array args)\n{\n')
-
- local hlattrs_args_count = 0
- if #ev.parameters > 0 then
- output:write(' if (args.size < ' .. #ev.parameters)
- for j = 1, #ev.parameters do
- local kind = ev.parameters[j][1]
- if kind ~= 'Object' then
- if kind == 'HlAttrs' then
- kind = 'Dict'
- end
- output:write('\n || args.items[' .. (j - 1) .. '].type != kObjectType' .. kind .. '')
- end
- end
- output:write(') {\n')
- output:write(' ELOG("Error handling ui event \'' .. ev.name .. '\'");\n')
- output:write(' return;\n')
- output:write(' }\n')
- end
-
- for j = 1, #ev.parameters do
- local param = ev.parameters[j]
- local kind = param[1]
- output:write(' ' .. kind .. ' arg_' .. j .. ' = ')
- if kind == 'HlAttrs' then
- -- The first HlAttrs argument is rgb_attrs and second is cterm_attrs
- output:write(
- 'ui_client_dict2hlattrs(args.items['
- .. (j - 1)
- .. '].data.dict, '
- .. (hlattrs_args_count == 0 and 'true' or 'false')
- .. ');\n'
- )
- hlattrs_args_count = hlattrs_args_count + 1
- elseif kind == 'Object' then
- output:write('args.items[' .. (j - 1) .. '];\n')
- elseif kind == 'Window' then
- output:write('(Window)args.items[' .. (j - 1) .. '].data.integer;\n')
- else
- output:write('args.items[' .. (j - 1) .. '].data.' .. string.lower(kind) .. ';\n')
- end
- end
-
- output:write(' tui_' .. ev.name .. '(tui')
- for j = 1, #ev.parameters do
- output:write(', arg_' .. j)
- end
- output:write(');\n')
-
- output:write('}\n\n')
-end
-
-events = vim.tbl_filter(function(ev)
- return ev[1] ~= 'empty' and ev[1] ~= 'preproc'
-end, events)
-
-for i = 1, #events do
- local ev = events[i]
- assert(ev.return_type == 'void')
-
- if ev.since == nil and not ev.noexport then
- print('Ui event ' .. ev.name .. ' lacks since field.\n')
- os.exit(1)
- end
- ev.since = tonumber(ev.since)
-
- local args = #ev.parameters > 0 and 'args' or 'noargs'
- if not ev.remote_only then
- if not ev.remote_impl and not ev.noexport then
- remote_output:write('void remote_ui_' .. ev.name)
- write_signature(remote_output, ev, 'RemoteUI *ui')
- remote_output:write('\n{\n')
- write_arglist(remote_output, ev)
- remote_output:write(' push_call(ui, "' .. ev.name .. '", ' .. args .. ');\n')
- remote_output:write('}\n\n')
- end
- end
-
- if not (ev.remote_only and ev.remote_impl) then
- call_output:write('void ui_call_' .. ev.name)
- write_signature(call_output, ev, '')
- call_output:write('\n{\n')
- if ev.remote_only then
- -- Lua callbacks may emit other events or the same event again. Avoid the latter
- -- by adding a recursion guard to each generated function that may call a Lua callback.
- call_output:write(' static bool entered = false;\n')
- call_output:write(' if (entered) {\n')
- call_output:write(' return;\n')
- call_output:write(' }\n')
- call_output:write(' entered = true;\n')
- write_arglist(call_output, ev)
- call_output:write((' ui_call_event("%s", %s, %s)'):format(ev.name, tostring(ev.fast), args))
- call_output:write(';\n entered = false;\n')
- elseif ev.compositor_impl then
- call_output:write(' ui_comp_' .. ev.name)
- write_signature(call_output, ev, '', true)
- call_output:write(';\n')
- call_output:write(' UI_CALL')
- write_signature(call_output, ev, '!ui->composed, ' .. ev.name .. ', ui', true)
- call_output:write(';\n')
- else
- call_output:write(' UI_CALL')
- write_signature(call_output, ev, 'true, ' .. ev.name .. ', ui', true)
- call_output:write(';\n')
- end
- call_output:write('}\n\n')
- end
-
- if ev.compositor_impl then
- call_output:write('void ui_composed_call_' .. ev.name)
- write_signature(call_output, ev, '')
- call_output:write('\n{\n')
- call_output:write(' UI_CALL')
- write_signature(call_output, ev, 'ui->composed, ' .. ev.name .. ', ui', true)
- call_output:write(';\n')
- call_output:write('}\n\n')
- end
-
- if (not ev.remote_only) and not ev.noexport and not ev.client_impl and not ev.client_ignore then
- call_ui_event_method(client_output, ev)
- end
-end
-
-local client_events = {}
-for _, ev in ipairs(events) do
- if (not ev.noexport) and ((not ev.remote_only) or ev.client_impl) and not ev.client_ignore then
- client_events[ev.name] = ev
- end
-end
-
-local hashorder, hashfun = hashy.hashy_hash(
- 'ui_client_handler',
- vim.tbl_keys(client_events),
- function(idx)
- return 'event_handlers[' .. idx .. '].name'
- end
-)
-
-client_output:write('static const UIClientHandler event_handlers[] = {\n')
-
-for _, name in ipairs(hashorder) do
- client_output:write(' { .name = "' .. name .. '", .fn = ui_client_event_' .. name .. '},\n')
-end
-
-client_output:write('\n};\n\n')
-client_output:write(hashfun)
-
-call_output:close()
-remote_output:close()
-client_output:close()
-
--- don't expose internal attributes like "impl_name" in public metadata
-local exported_attributes = { 'name', 'parameters', 'since', 'deprecated_since' }
-local exported_events = {}
-for _, ev in ipairs(events) do
- local ev_exported = {}
- for _, attr in ipairs(exported_attributes) do
- ev_exported[attr] = ev[attr]
- end
- for _, p in ipairs(ev_exported.parameters) do
- if p[1] == 'HlAttrs' or p[1] == 'Dict' then
- -- TODO(justinmk): for back-compat, but do clients actually look at this?
- p[1] = 'Dictionary'
- end
- end
- if not ev.noexport then
- exported_events[#exported_events + 1] = ev_exported
- end
-end
-
-metadata_output:write(mpack.encode(exported_events))
-metadata_output:close()
diff --git a/src/nvim/generators/gen_char_blob.lua b/src/nvim/generators/gen_char_blob.lua
deleted file mode 100644
index c40e0d6e82..0000000000
--- a/src/nvim/generators/gen_char_blob.lua
+++ /dev/null
@@ -1,96 +0,0 @@
-if arg[1] == '--help' then
- print('Usage:')
- print(' ' .. arg[0] .. ' [-c] target source varname [source varname]...')
- print('')
- print('Generates C file with big uint8_t blob.')
- print('Blob will be stored in a static const array named varname.')
- os.exit()
-end
-
--- Recognized options:
--- -c compile Lua bytecode
-local options = {}
-
-while true do
- local opt = string.match(arg[1], '^-(%w)')
- if not opt then
- break
- end
-
- options[opt] = true
- table.remove(arg, 1)
-end
-
-assert(#arg >= 3 and (#arg - 1) % 2 == 0)
-
-local target_file = arg[1] or error('Need a target file')
-local target = io.open(target_file, 'w')
-
-target:write('#include <stdint.h>\n\n')
-
-local index_items = {}
-
-local warn_on_missing_compiler = true
-local modnames = {}
-for argi = 2, #arg, 2 do
- local source_file = arg[argi]
- local modname = arg[argi + 1]
- if modnames[modname] then
- error(string.format('modname %q is already specified for file %q', modname, modnames[modname]))
- end
- modnames[modname] = source_file
-
- local varname = string.gsub(modname, '%.', '_dot_') .. '_module'
- target:write(('static const uint8_t %s[] = {\n'):format(varname))
-
- local output
- if options.c then
- local luac = os.getenv('LUAC_PRG')
- if luac and luac ~= '' then
- output = io.popen(luac:format(source_file), 'r'):read('*a')
- elseif warn_on_missing_compiler then
- print('LUAC_PRG is missing, embedding raw source')
- warn_on_missing_compiler = false
- end
- end
-
- if not output then
- local source = io.open(source_file, 'r')
- or error(string.format("source_file %q doesn't exist", source_file))
- output = source:read('*a')
- source:close()
- end
-
- local num_bytes = 0
- local MAX_NUM_BYTES = 15 -- 78 / 5: maximum number of bytes on one line
- target:write(' ')
-
- local increase_num_bytes
- increase_num_bytes = function()
- num_bytes = num_bytes + 1
- if num_bytes == MAX_NUM_BYTES then
- num_bytes = 0
- target:write('\n ')
- end
- end
-
- for i = 1, string.len(output) do
- local byte = output:byte(i)
- target:write(string.format(' %3u,', byte))
- increase_num_bytes()
- end
-
- target:write(' 0};\n')
- if modname ~= '_' then
- table.insert(
- index_items,
- ' { "' .. modname .. '", ' .. varname .. ', sizeof ' .. varname .. ' },\n\n'
- )
- end
-end
-
-target:write('static ModuleDef builtin_modules[] = {\n')
-target:write(table.concat(index_items))
-target:write('};\n')
-
-target:close()
diff --git a/src/nvim/generators/gen_declarations.lua b/src/nvim/generators/gen_declarations.lua
deleted file mode 100644
index 6e1ea92572..0000000000
--- a/src/nvim/generators/gen_declarations.lua
+++ /dev/null
@@ -1,186 +0,0 @@
-local grammar = require('generators.c_grammar').grammar
-
---- @param fname string
---- @return string?
-local function read_file(fname)
- local f = io.open(fname, 'r')
- if not f then
- return
- end
- local contents = f:read('*a')
- f:close()
- return contents
-end
-
---- @param fname string
---- @param contents string[]
-local function write_file(fname, contents)
- local contents_s = table.concat(contents, '\n') .. '\n'
- local fcontents = read_file(fname)
- if fcontents == contents_s then
- return
- end
- local f = assert(io.open(fname, 'w'))
- f:write(contents_s)
- f:close()
-end
-
---- @param fname string
---- @param non_static_fname string
---- @return string? non_static
-local function add_iwyu_non_static(fname, non_static_fname)
- if fname:find('.*/src/nvim/.*%.c$') then
- -- Add an IWYU pragma comment if the corresponding .h file exists.
- local header_fname = fname:sub(1, -3) .. '.h'
- local header_f = io.open(header_fname, 'r')
- if header_f then
- header_f:close()
- return (header_fname:gsub('.*/src/nvim/', 'nvim/'))
- end
- elseif non_static_fname:find('/include/api/private/dispatch_wrappers%.h%.generated%.h$') then
- return 'nvim/api/private/dispatch.h'
- elseif non_static_fname:find('/include/ui_events_call%.h%.generated%.h$') then
- return 'nvim/ui.h'
- elseif non_static_fname:find('/include/ui_events_client%.h%.generated%.h$') then
- return 'nvim/ui_client.h'
- elseif non_static_fname:find('/include/ui_events_remote%.h%.generated%.h$') then
- return 'nvim/api/ui.h'
- end
-end
-
---- @param d string
-local function process_decl(d)
- -- Comments are really handled by preprocessor, so the following is not
- -- needed
- d = d:gsub('/%*.-%*/', '')
- d = d:gsub('//.-\n', '\n')
- d = d:gsub('# .-\n', '')
- d = d:gsub('\n', ' ')
- d = d:gsub('%s+', ' ')
- d = d:gsub(' ?%( ?', '(')
- d = d:gsub(' ?, ?', ', ')
- d = d:gsub(' ?(%*+) ?', ' %1')
- d = d:gsub(' ?(FUNC_ATTR_)', ' %1')
- d = d:gsub(' $', '')
- d = d:gsub('^ ', '')
- return d .. ';'
-end
-
---- @param fname string
---- @param text string
---- @return string[] static
---- @return string[] non_static
---- @return boolean any_static
-local function gen_declarations(fname, text)
- local non_static = {} --- @type string[]
- local static = {} --- @type string[]
-
- local neededfile = fname:match('[^/]+$')
- local curfile = nil
- local any_static = false
- for _, node in ipairs(grammar:match(text)) do
- if node[1] == 'preproc' then
- curfile = node.content:match('^%a* %d+ "[^"]-/?([^"/]+)"') or curfile
- elseif node[1] == 'proto' and curfile == neededfile then
- local node_text = text:sub(node.pos, node.endpos - 1)
- local declaration = process_decl(node_text)
-
- if node.static then
- if not any_static and declaration:find('FUNC_ATTR_') then
- any_static = true
- end
- static[#static + 1] = declaration
- else
- non_static[#non_static + 1] = 'DLLEXPORT ' .. declaration
- end
- end
- end
-
- return static, non_static, any_static
-end
-
-local usage = [[
-Usage:
-
- gen_declarations.lua definitions.c static.h non-static.h definitions.i
-
-Generates declarations for a C file definitions.c, putting declarations for
-static functions into static.h and declarations for non-static functions into
-non-static.h. File `definitions.i' should contain an already preprocessed
-version of definitions.c and it is the only one which is actually parsed,
-definitions.c is needed only to determine functions from which file out of all
-functions found in definitions.i are needed and to generate an IWYU comment.
-]]
-
-local function main()
- local fname = arg[1]
- local static_fname = arg[2]
- local non_static_fname = arg[3]
- local preproc_fname = arg[4]
- local static_basename = arg[5]
-
- if fname == '--help' or #arg < 5 then
- print(usage)
- os.exit()
- end
-
- local text = assert(read_file(preproc_fname))
-
- local static_decls, non_static_decls, any_static = gen_declarations(fname, text)
-
- local static = {} --- @type string[]
- if fname:find('.*/src/nvim/.*%.h$') then
- static[#static + 1] = ('// IWYU pragma: private, include "%s"'):format(
- fname:gsub('.*/src/nvim/', 'nvim/')
- )
- end
- vim.list_extend(static, {
- '#define DEFINE_FUNC_ATTRIBUTES',
- '#include "nvim/func_attr.h"',
- '#undef DEFINE_FUNC_ATTRIBUTES',
- })
- vim.list_extend(static, static_decls)
- vim.list_extend(static, {
- '#define DEFINE_EMPTY_ATTRIBUTES',
- '#include "nvim/func_attr.h" // IWYU pragma: export',
- '',
- })
-
- write_file(static_fname, static)
-
- if any_static then
- local orig_text = assert(read_file(fname))
- local pat = '\n#%s?include%s+"' .. static_basename .. '"\n'
- local pat_comment = '\n#%s?include%s+"' .. static_basename .. '"%s*//'
- if not orig_text:find(pat) and not orig_text:find(pat_comment) then
- error(('fail: missing include for %s in %s'):format(static_basename, fname))
- end
- end
-
- if non_static_fname ~= 'SKIP' then
- local non_static = {} --- @type string[]
- local iwyu_non_static = add_iwyu_non_static(fname, non_static_fname)
- if iwyu_non_static then
- non_static[#non_static + 1] = ('// IWYU pragma: private, include "%s"'):format(
- iwyu_non_static
- )
- end
- vim.list_extend(non_static, {
- '#define DEFINE_FUNC_ATTRIBUTES',
- '#include "nvim/func_attr.h"',
- '#undef DEFINE_FUNC_ATTRIBUTES',
- '#ifndef DLLEXPORT',
- '# ifdef MSWIN',
- '# define DLLEXPORT __declspec(dllexport)',
- '# else',
- '# define DLLEXPORT',
- '# endif',
- '#endif',
- })
- vim.list_extend(non_static, non_static_decls)
- non_static[#non_static + 1] = '#include "nvim/func_attr.h"'
- write_file(non_static_fname, non_static)
- end
-end
-
-return main()
diff --git a/src/nvim/generators/gen_eval.lua b/src/nvim/generators/gen_eval.lua
deleted file mode 100644
index 0b6ee6cb24..0000000000
--- a/src/nvim/generators/gen_eval.lua
+++ /dev/null
@@ -1,112 +0,0 @@
-local mpack = vim.mpack
-
-local autodir = arg[1]
-local metadata_file = arg[2]
-local funcs_file = arg[3]
-
-local funcsfname = autodir .. '/funcs.generated.h'
-
---Will generate funcs.generated.h with definition of functions static const array.
-
-local hashy = require 'generators.hashy'
-
-local hashpipe = assert(io.open(funcsfname, 'wb'))
-
-hashpipe:write([[
-#include "nvim/arglist.h"
-#include "nvim/cmdexpand.h"
-#include "nvim/cmdhist.h"
-#include "nvim/digraph.h"
-#include "nvim/eval.h"
-#include "nvim/eval/buffer.h"
-#include "nvim/eval/deprecated.h"
-#include "nvim/eval/fs.h"
-#include "nvim/eval/funcs.h"
-#include "nvim/eval/typval.h"
-#include "nvim/eval/vars.h"
-#include "nvim/eval/window.h"
-#include "nvim/ex_docmd.h"
-#include "nvim/ex_getln.h"
-#include "nvim/fold.h"
-#include "nvim/getchar.h"
-#include "nvim/insexpand.h"
-#include "nvim/mapping.h"
-#include "nvim/match.h"
-#include "nvim/mbyte.h"
-#include "nvim/menu.h"
-#include "nvim/mouse.h"
-#include "nvim/move.h"
-#include "nvim/quickfix.h"
-#include "nvim/runtime.h"
-#include "nvim/search.h"
-#include "nvim/state.h"
-#include "nvim/strings.h"
-#include "nvim/sign.h"
-#include "nvim/testing.h"
-#include "nvim/undo.h"
-
-]])
-
-local funcs = require('eval').funcs
-for _, func in pairs(funcs) do
- if func.float_func then
- func.func = 'float_op_wrapper'
- func.data = '{ .float_func = &' .. func.float_func .. ' }'
- end
-end
-
-local metadata = mpack.decode(io.open(metadata_file, 'rb'):read('*all'))
-for _, fun in ipairs(metadata) do
- if fun.eval then
- funcs[fun.name] = {
- args = #fun.parameters,
- func = 'api_wrapper',
- data = '{ .api_handler = &method_handlers[' .. fun.handler_id .. '] }',
- }
- end
-end
-
-local func_names = vim.tbl_filter(function(name)
- return name:match('__%d*$') == nil
-end, vim.tbl_keys(funcs))
-
-table.sort(func_names)
-
-local funcsdata = assert(io.open(funcs_file, 'w'))
-funcsdata:write(mpack.encode(func_names))
-funcsdata:close()
-
-local neworder, hashfun = hashy.hashy_hash('find_internal_func', func_names, function(idx)
- return 'functions[' .. idx .. '].name'
-end)
-
-hashpipe:write('static const EvalFuncDef functions[] = {\n')
-
-for _, name in ipairs(neworder) do
- local def = funcs[name]
- local args = def.args or 0
- if type(args) == 'number' then
- args = { args, args }
- elseif #args == 1 then
- args[2] = 'MAX_FUNC_ARGS'
- end
- local base = def.base or 'BASE_NONE'
- local func = def.func or ('f_' .. name)
- local data = def.data or '{ .null = NULL }'
- local fast = def.fast and 'true' or 'false'
- hashpipe:write(
- (' { "%s", %s, %s, %s, %s, &%s, %s },\n'):format(
- name,
- args[1],
- args[2],
- base,
- fast,
- func,
- data
- )
- )
-end
-hashpipe:write(' { NULL, 0, 0, BASE_NONE, false, NULL, { .null = NULL } },\n')
-hashpipe:write('};\n\n')
-hashpipe:write(hashfun)
-hashpipe:close()
diff --git a/src/nvim/generators/gen_events.lua b/src/nvim/generators/gen_events.lua
deleted file mode 100644
index 8c87815a74..0000000000
--- a/src/nvim/generators/gen_events.lua
+++ /dev/null
@@ -1,42 +0,0 @@
-local fileio_enum_file = arg[1]
-local names_file = arg[2]
-
-local auevents = require('auevents')
-local events = auevents.events
-
-local enum_tgt = io.open(fileio_enum_file, 'w')
-local names_tgt = io.open(names_file, 'w')
-
-enum_tgt:write([[
-// IWYU pragma: private, include "nvim/autocmd_defs.h"
-
-typedef enum auto_event {]])
-names_tgt:write([[
-static const struct event_name {
- size_t len;
- char *name;
- int event;
-} event_names[] = {]])
-
-local aliases = 0
-for i, event in ipairs(events) do
- enum_tgt:write(('\n EVENT_%s = %u,'):format(event[1]:upper(), i + aliases - 1))
- -- Events with positive keys aren't allowed in 'eventignorewin'.
- local event_int = ('%sEVENT_%s'):format(event[3] and '-' or '', event[1]:upper())
- names_tgt:write(('\n {%u, "%s", %s},'):format(#event[1], event[1], event_int))
- for _, alias in ipairs(event[2]) do
- aliases = aliases + 1
- names_tgt:write(('\n {%u, "%s", %s},'):format(#alias, alias, event_int))
- enum_tgt:write(('\n EVENT_%s = %u,'):format(alias:upper(), i + aliases - 1))
- end
- if i == #events then -- Last item.
- enum_tgt:write(('\n NUM_EVENTS = %u,'):format(i + aliases))
- end
-end
-
-names_tgt:write('\n {0, NULL, (event_T)0},\n};\n')
-names_tgt:write('\nstatic AutoCmdVec autocmds[NUM_EVENTS] = { 0 };\n')
-names_tgt:close()
-
-enum_tgt:write('\n} event_T;\n')
-enum_tgt:close()
diff --git a/src/nvim/generators/gen_ex_cmds.lua b/src/nvim/generators/gen_ex_cmds.lua
deleted file mode 100644
index e8d1aac182..0000000000
--- a/src/nvim/generators/gen_ex_cmds.lua
+++ /dev/null
@@ -1,194 +0,0 @@
-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('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
-))
diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua
deleted file mode 100644
index e5dba90925..0000000000
--- a/src/nvim/generators/gen_options.lua
+++ /dev/null
@@ -1,535 +0,0 @@
---- @module 'nvim.options'
-local options = require('options')
-local options_meta = options.options
-local cstr = options.cstr
-local valid_scopes = options.valid_scopes
-
---- @param o vim.option_meta
---- @return string
-local function get_values_var(o)
- return ('opt_%s_values'):format(o.abbreviation or o.full_name)
-end
-
---- @param s string
---- @return string
-local function lowercase_to_titlecase(s)
- return table.concat(vim.tbl_map(function(word) --- @param word string
- return word:sub(1, 1):upper() .. word:sub(2)
- end, vim.split(s, '[-_]')))
-end
-
---- @param scope string
---- @param option_name string
---- @return string
-local function get_scope_option(scope, option_name)
- return ('k%sOpt%s'):format(lowercase_to_titlecase(scope), lowercase_to_titlecase(option_name))
-end
-
-local redraw_flags = {
- ui_option = 'kOptFlagUIOption',
- tabline = 'kOptFlagRedrTabl',
- statuslines = 'kOptFlagRedrStat',
- current_window = 'kOptFlagRedrWin',
- current_buffer = 'kOptFlagRedrBuf',
- all_windows = 'kOptFlagRedrAll',
- curswant = 'kOptFlagCurswant',
- highlight_only = 'kOptFlagHLOnly',
-}
-
-local list_flags = {
- comma = 'kOptFlagComma',
- onecomma = 'kOptFlagOneComma',
- commacolon = 'kOptFlagComma|kOptFlagColon',
- onecommacolon = 'kOptFlagOneComma|kOptFlagColon',
- flags = 'kOptFlagFlagList',
- flagscomma = 'kOptFlagComma|kOptFlagFlagList',
-}
-
---- @param o vim.option_meta
---- @return string
-local function get_flags(o)
- --- @type string[]
- local flags = { '0' }
-
- --- @param f string
- local function add_flag(f)
- table.insert(flags, f)
- end
-
- if o.list then
- add_flag(list_flags[o.list])
- end
-
- for _, r_flag in ipairs(o.redraw or {}) do
- add_flag(redraw_flags[r_flag])
- end
-
- if o.expand then
- add_flag('kOptFlagExpand')
- if o.expand == 'nodefault' then
- add_flag('kOptFlagNoDefExp')
- end
- end
-
- for _, flag_desc in ipairs({
- { 'nodefault', 'NoDefault' },
- { 'no_mkrc', 'NoMkrc' },
- { 'secure' },
- { 'gettext' },
- { 'noglob', 'NoGlob' },
- { 'normal_fname_chars', 'NFname' },
- { 'normal_dname_chars', 'NDname' },
- { 'pri_mkrc', 'PriMkrc' },
- { 'deny_in_modelines', 'NoML' },
- { 'deny_duplicates', 'NoDup' },
- { 'modelineexpr', 'MLE' },
- { 'func' },
- }) do
- local key_name, flag_suffix = flag_desc[1], flag_desc[2]
- if o[key_name] then
- local def_name = 'kOptFlag' .. (flag_suffix or lowercase_to_titlecase(key_name))
- add_flag(def_name)
- end
- end
-
- return table.concat(flags, '|')
-end
-
---- @param opt_type vim.option_type
---- @return string
-local function opt_type_enum(opt_type)
- return ('kOptValType%s'):format(lowercase_to_titlecase(opt_type))
-end
-
---- @param scope vim.option_scope
---- @return string
-local function opt_scope_enum(scope)
- return ('kOptScope%s'):format(lowercase_to_titlecase(scope))
-end
-
---- @param o vim.option_meta
---- @return string
-local function get_scope_flags(o)
- local scope_flags = '0'
-
- for _, scope in ipairs(o.scope) do
- scope_flags = ('%s | (1 << %s)'):format(scope_flags, opt_scope_enum(scope))
- end
-
- return scope_flags
-end
-
---- @param o vim.option_meta
---- @return string
-local function get_scope_idx(o)
- --- @type string[]
- local strs = {}
-
- for _, scope in pairs(valid_scopes) do
- local has_scope = vim.tbl_contains(o.scope, scope)
- strs[#strs + 1] = (' [%s] = %s'):format(
- opt_scope_enum(scope),
- get_scope_option(scope, has_scope and o.full_name or 'Invalid')
- )
- end
-
- return ('{\n%s\n }'):format(table.concat(strs, ',\n'))
-end
-
---- @param s string
---- @return string
-local function static_cstr_as_string(s)
- return ('{ .data = %s, .size = sizeof(%s) - 1 }'):format(s, s)
-end
-
---- @param v vim.option_value|function
---- @return string
-local function get_opt_val(v)
- --- @type vim.option_type
- local v_type
-
- if type(v) == 'function' then
- v, v_type = v() --[[ @as string, vim.option_type ]]
-
- if v_type == 'string' then
- v = static_cstr_as_string(v)
- end
- else
- v_type = type(v) --[[ @as vim.option_type ]]
-
- if v_type == 'boolean' then
- v = v and 'true' or 'false'
- elseif v_type == 'number' then
- v = ('%iL'):format(v)
- elseif v_type == 'string' then
- --- @cast v string
- v = static_cstr_as_string(cstr(v))
- end
- end
-
- return ('{ .type = %s, .data.%s = %s }'):format(opt_type_enum(v_type), v_type, v)
-end
-
---- @param d vim.option_value|function
---- @param n string
---- @return string
-local function get_defaults(d, n)
- if d == nil then
- error("option '" .. n .. "' should have a default value")
- end
- return get_opt_val(d)
-end
-
---- @param i integer
---- @param o vim.option_meta
---- @param write fun(...: string)
-local function dump_option(i, o, write)
- write(' [', ('%u'):format(i - 1) .. ']={')
- write(' .fullname=', cstr(o.full_name))
- if o.abbreviation then
- write(' .shortname=', cstr(o.abbreviation))
- end
- write(' .type=', opt_type_enum(o.type))
- write(' .flags=', get_flags(o))
- write(' .scope_flags=', get_scope_flags(o))
- write(' .scope_idx=', get_scope_idx(o))
- write(' .values=', (o.values and get_values_var(o) or 'NULL'))
- write(' .values_len=', (o.values and #o.values or '0'))
- write(' .flags_var=', (o.flags_varname and ('&%s'):format(o.flags_varname) or 'NULL'))
- if o.enable_if then
- write(('#if defined(%s)'):format(o.enable_if))
- end
-
- local is_window_local = #o.scope == 1 and o.scope[1] == 'win'
-
- if is_window_local then
- write(' .var=NULL')
- elseif o.varname then
- write(' .var=&', o.varname)
- elseif o.immutable then
- -- Immutable options can directly point to the default value.
- write((' .var=&options[%u].def_val.data'):format(i - 1))
- else
- error('Option must be immutable or have a variable.')
- end
-
- write(' .immutable=', (o.immutable and 'true' or 'false'))
- write(' .opt_did_set_cb=', o.cb or 'NULL')
- write(' .opt_expand_cb=', o.expand_cb or 'NULL')
-
- if o.enable_if then
- write('#else')
- -- Hidden option directly points to default value.
- write((' .var=&options[%u].def_val.data'):format(i - 1))
- -- Option is always immutable on the false branch of `enable_if`.
- write(' .immutable=true')
- write('#endif')
- end
-
- if not o.defaults then
- write(' .def_val=NIL_OPTVAL')
- elseif o.defaults.condition then
- write(('#if defined(%s)'):format(o.defaults.condition))
- write(' .def_val=', get_defaults(o.defaults.if_true, o.full_name))
- if o.defaults.if_false then
- write('#else')
- write(' .def_val=', get_defaults(o.defaults.if_false, o.full_name))
- end
- write('#endif')
- else
- write(' .def_val=', get_defaults(o.defaults.if_true, o.full_name))
- end
-
- write(' },')
-end
-
---- @param prefix string
---- @param values vim.option_valid_values
-local function preorder_traversal(prefix, values)
- local out = {} --- @type string[]
-
- local function add(s)
- table.insert(out, s)
- end
-
- add('')
- add(('EXTERN const char *(%s_values[%s]) INIT( = {'):format(prefix, #vim.tbl_keys(values) + 1))
-
- --- @type [string,vim.option_valid_values][]
- local children = {}
-
- for _, value in ipairs(values) do
- if type(value) == 'string' then
- add((' "%s",'):format(value))
- else
- assert(type(value) == 'table' and type(value[1]) == 'string' and type(value[2]) == 'table')
- add((' "%s",'):format(value[1]))
- table.insert(children, value)
- end
- end
-
- add(' NULL')
- add('});')
-
- for _, value in pairs(children) do
- -- Remove trailing colon from the added prefix to prevent syntax errors.
- add(preorder_traversal(prefix .. '_' .. value[1]:gsub(':$', ''), value[2]))
- end
-
- return table.concat(out, '\n')
-end
-
---- @param o vim.option_meta
---- @return string
-local function gen_opt_enum(o)
- local out = {} --- @type string[]
-
- local function add(s)
- table.insert(out, s)
- end
-
- add('')
- add('typedef enum {')
-
- local opt_name = lowercase_to_titlecase(o.abbreviation or o.full_name)
- --- @type table<string,integer>
- local enum_values
-
- if type(o.flags) == 'table' then
- enum_values = o.flags --[[ @as table<string,integer> ]]
- else
- enum_values = {}
- for i, flag_name in ipairs(o.values) do
- assert(type(flag_name) == 'string')
- enum_values[flag_name] = math.pow(2, i - 1)
- end
- end
-
- -- Sort the keys by the flag value so that the enum can be generated in order.
- --- @type string[]
- local flag_names = vim.tbl_keys(enum_values)
- table.sort(flag_names, function(a, b)
- return enum_values[a] < enum_values[b]
- end)
-
- for _, flag_name in pairs(flag_names) do
- add(
- (' kOpt%sFlag%s = 0x%02x,'):format(
- opt_name,
- lowercase_to_titlecase(flag_name:gsub(':$', '')),
- enum_values[flag_name]
- )
- )
- end
-
- add(('} Opt%sFlags;'):format(opt_name))
-
- return table.concat(out, '\n')
-end
-
---- @param output_file string
---- @return table<string,string> options_index Map of option name to option index
-local function gen_enums(output_file)
- --- Options for each scope.
- --- @type table<string, vim.option_meta[]>
- local scope_options = {}
- for _, scope in ipairs(valid_scopes) do
- scope_options[scope] = {}
- end
-
- local fd = assert(io.open(output_file, 'w'))
-
- --- @param s string
- local function write(s)
- fd:write(s)
- fd:write('\n')
- end
-
- -- Generate options enum file
- write('// IWYU pragma: private, include "nvim/option_defs.h"')
- write('')
-
- --- Map of option name to option index
- --- @type table<string, string>
- local option_index = {}
-
- -- Generate option index enum and populate the `option_index` and `scope_option` dicts.
- write('typedef enum {')
- write(' kOptInvalid = -1,')
-
- for i, o in ipairs(options_meta) do
- local enum_val_name = 'kOpt' .. lowercase_to_titlecase(o.full_name)
- write((' %s = %u,'):format(enum_val_name, i - 1))
-
- option_index[o.full_name] = enum_val_name
-
- if o.abbreviation then
- option_index[o.abbreviation] = enum_val_name
- end
-
- local alias = o.alias or {} --[[@as string[] ]]
- for _, v in ipairs(alias) do
- option_index[v] = enum_val_name
- end
-
- for _, scope in ipairs(o.scope) do
- table.insert(scope_options[scope], o)
- end
- end
-
- write(' // Option count')
- write('#define kOptCount ' .. tostring(#options_meta))
- write('} OptIndex;')
-
- -- Generate option index enum for each scope
- for _, scope in ipairs(valid_scopes) do
- write('')
-
- local scope_name = lowercase_to_titlecase(scope)
- write('typedef enum {')
- write((' %s = -1,'):format(get_scope_option(scope, 'Invalid')))
-
- for idx, option in ipairs(scope_options[scope]) do
- write((' %s = %u,'):format(get_scope_option(scope, option.full_name), idx - 1))
- end
-
- write((' // %s option count'):format(scope_name))
- write(('#define %s %d'):format(get_scope_option(scope, 'Count'), #scope_options[scope]))
- write(('} %sOptIndex;'):format(scope_name))
- end
-
- -- Generate reverse lookup from option scope index to option index for each scope.
- for _, scope in ipairs(valid_scopes) do
- write('')
- write(('EXTERN const OptIndex %s_opt_idx[] INIT( = {'):format(scope))
- for _, option in ipairs(scope_options[scope]) do
- local idx = option_index[option.full_name]
- write((' [%s] = %s,'):format(get_scope_option(scope, option.full_name), idx))
- end
- write('});')
- end
-
- fd:close()
-
- return option_index
-end
-
---- @param output_file string
---- @param option_index table<string,string>
-local function gen_map(output_file, option_index)
- -- Generate option index map.
- local hashy = require('generators.hashy')
-
- local neworder, hashfun = hashy.hashy_hash(
- 'find_option',
- vim.tbl_keys(option_index),
- function(idx)
- return ('option_hash_elems[%s].name'):format(idx)
- end
- )
-
- local fd = assert(io.open(output_file, 'w'))
-
- --- @param s string
- local function write(s)
- fd:write(s)
- fd:write('\n')
- end
-
- write('static const struct { const char *name; OptIndex opt_idx; } option_hash_elems[] = {')
-
- for _, name in ipairs(neworder) do
- assert(option_index[name] ~= nil)
- write((' { .name = "%s", .opt_idx = %s },'):format(name, option_index[name]))
- end
-
- write('};')
- write('')
- write('static ' .. hashfun)
-
- fd:close()
-end
-
---- @param output_file string
-local function gen_vars(output_file)
- local fd = assert(io.open(output_file, 'w'))
-
- --- @param s string
- local function write(s)
- fd:write(s)
- fd:write('\n')
- end
-
- write('// IWYU pragma: private, include "nvim/option_vars.h"')
-
- -- Generate enums for option flags.
- for _, o in ipairs(options_meta) do
- if o.flags and (type(o.flags) == 'table' or o.values) then
- write(gen_opt_enum(o))
- end
- end
-
- -- Generate valid values for each option.
- for _, option in ipairs(options_meta) do
- -- Since option values can be nested, we need to do preorder traversal to generate the values.
- if option.values then
- local values_var = ('opt_%s'):format(option.abbreviation or option.full_name)
- write(preorder_traversal(values_var, option.values))
- end
- end
-
- fd:close()
-end
-
---- @param output_file string
-local function gen_options(output_file)
- local fd = assert(io.open(output_file, 'w'))
-
- --- @param ... string
- local function write(...)
- local s = table.concat({ ... }, '')
- fd:write(s)
- if s:match('^ %.') then
- fd:write(',')
- end
- fd:write('\n')
- end
-
- -- Generate options[] array.
- write([[
- #include "nvim/ex_docmd.h"
- #include "nvim/ex_getln.h"
- #include "nvim/insexpand.h"
- #include "nvim/mapping.h"
- #include "nvim/ops.h"
- #include "nvim/option.h"
- #include "nvim/optionstr.h"
- #include "nvim/quickfix.h"
- #include "nvim/runtime.h"
- #include "nvim/tag.h"
- #include "nvim/window.h"
-
- static vimoption_T options[] = {]])
-
- for i, o in ipairs(options_meta) do
- dump_option(i, o, write)
- end
-
- write('};')
-
- fd:close()
-end
-
-local function main()
- local options_file = arg[1]
- local options_enum_file = arg[2]
- local options_map_file = arg[3]
- local option_vars_file = arg[4]
-
- local option_index = gen_enums(options_enum_file)
- gen_map(options_map_file, option_index)
- gen_vars(option_vars_file)
- gen_options(options_file)
-end
-
-main()
diff --git a/src/nvim/generators/gen_vimvim.lua b/src/nvim/generators/gen_vimvim.lua
deleted file mode 100644
index 3817735a55..0000000000
--- a/src/nvim/generators/gen_vimvim.lua
+++ /dev/null
@@ -1,156 +0,0 @@
-local mpack = vim.mpack
-
-local syntax_file = arg[1]
-local funcs_file = arg[2]
-
-local lld = {}
-local syn_fd = io.open(syntax_file, 'w')
-lld.line_length = 0
-local function w(s)
- syn_fd:write(s)
- if s:find('\n') then
- lld.line_length = #(s:gsub('.*\n', ''))
- else
- lld.line_length = lld.line_length + #s
- end
-end
-
-local options = require('options')
-local auevents = require('auevents')
-local ex_cmds = require('ex_cmds')
-
-local function cmd_kw(prev_cmd, cmd)
- if not prev_cmd then
- return cmd:sub(1, 1) .. '[' .. cmd:sub(2) .. ']'
- else
- local shift = 1
- while cmd:sub(shift, shift) == prev_cmd:sub(shift, shift) do
- shift = shift + 1
- end
- if cmd:sub(1, shift) == 'def' then
- shift = shift + 1
- end
- if shift >= #cmd then
- return cmd
- else
- return cmd:sub(1, shift) .. '[' .. cmd:sub(shift + 1) .. ']'
- end
- end
-end
-
--- Exclude these from the vimCommand keyword list, they are handled specially
--- in syntax/vim.vim (vimAugroupKey, vimAutoCmd, vimGlobal, vimSubst). #9327
-local function is_special_cased_cmd(cmd)
- return (
- cmd == 'augroup'
- or cmd == 'autocmd'
- or cmd == 'doautocmd'
- or cmd == 'doautoall'
- or cmd == 'global'
- or cmd == 'substitute'
- )
-end
-
-local vimcmd_start = 'syn keyword vimCommand contained '
-local vimcmd_end = ' nextgroup=vimBang'
-w(vimcmd_start)
-
-local prev_cmd = nil
-for _, cmd_desc in ipairs(ex_cmds.cmds) do
- if lld.line_length > 850 then
- w(vimcmd_end .. '\n' .. vimcmd_start)
- end
- local cmd = cmd_desc.command
- if cmd:match('%w') and cmd ~= 'z' and not is_special_cased_cmd(cmd) then
- w(' ' .. cmd_kw(prev_cmd, cmd))
- end
- if cmd == 'delete' then
- -- Add special abbreviations of :delete
- w(' ' .. cmd_kw('d', 'dl'))
- w(' ' .. cmd_kw('del', 'dell'))
- w(' ' .. cmd_kw('dele', 'delel'))
- w(' ' .. cmd_kw('delet', 'deletl'))
- w(' ' .. cmd_kw('delete', 'deletel'))
- w(' ' .. cmd_kw('d', 'dp'))
- w(' ' .. cmd_kw('de', 'dep'))
- w(' ' .. cmd_kw('del', 'delp'))
- w(' ' .. cmd_kw('dele', 'delep'))
- w(' ' .. cmd_kw('delet', 'deletp'))
- w(' ' .. cmd_kw('delete', 'deletep'))
- end
- prev_cmd = cmd
-end
-
-w(vimcmd_end .. '\n')
-
-local vimopt_start = 'syn keyword vimOption contained '
-local vimopt_end = ' skipwhite nextgroup=vimSetEqual,vimSetMod'
-w('\n' .. vimopt_start)
-
-for _, opt_desc in ipairs(options.options) do
- if not opt_desc.immutable then
- if lld.line_length > 850 then
- w(vimopt_end .. '\n' .. vimopt_start)
- end
- w(' ' .. opt_desc.full_name)
- if opt_desc.abbreviation then
- w(' ' .. opt_desc.abbreviation)
- end
- if opt_desc.type == 'boolean' then
- w(' inv' .. opt_desc.full_name)
- w(' no' .. opt_desc.full_name)
- if opt_desc.abbreviation then
- w(' inv' .. opt_desc.abbreviation)
- w(' no' .. opt_desc.abbreviation)
- end
- end
- end
-end
-
-w(vimopt_end .. '\n')
-
-w('\nsyn case ignore')
-local vimau_start = 'syn keyword vimAutoEvent contained '
-w('\n\n' .. vimau_start)
-
-for _, au in ipairs(auevents.events) do
- if not auevents.nvim_specific[au[1]] then
- if lld.line_length > 850 then
- w('\n' .. vimau_start)
- end
- w(' ' .. au[1])
- for _, alias in ipairs(au[2]) do
- if lld.line_length > 850 then
- w('\n' .. vimau_start)
- end
- -- au[1] is aliased to alias
- w(' ' .. alias)
- end
- end
-end
-
-local nvimau_start = 'syn keyword nvimAutoEvent contained '
-w('\n\n' .. nvimau_start)
-
-for au, _ in vim.spairs(auevents.nvim_specific) do
- if lld.line_length > 850 then
- w('\n' .. nvimau_start)
- end
- w(' ' .. au)
-end
-
-w('\n\nsyn case match')
-local vimfun_start = 'syn keyword vimFuncName contained '
-w('\n\n' .. vimfun_start)
-local funcs = mpack.decode(io.open(funcs_file, 'rb'):read('*all'))
-for _, name in ipairs(funcs) do
- if name then
- if lld.line_length > 850 then
- w('\n' .. vimfun_start)
- end
- w(' ' .. name)
- end
-end
-
-w('\n')
-syn_fd:close()
diff --git a/src/nvim/generators/hashy.lua b/src/nvim/generators/hashy.lua
deleted file mode 100644
index 74b7655324..0000000000
--- a/src/nvim/generators/hashy.lua
+++ /dev/null
@@ -1,145 +0,0 @@
--- HASHY McHASHFACE
-
-local M = {}
-_G.d = M
-
-local function setdefault(table, key)
- local val = table[key]
- if val == nil then
- val = {}
- table[key] = val
- end
- return val
-end
-
-function M.build_pos_hash(strings)
- local len_buckets = {}
- local maxlen = 0
- for _, s in ipairs(strings) do
- table.insert(setdefault(len_buckets, #s), s)
- if #s > maxlen then
- maxlen = #s
- end
- end
-
- local len_pos_buckets = {}
- local worst_buck_size = 0
-
- for len = 1, maxlen do
- local strs = len_buckets[len]
- if strs then
- -- the best position so far generates `best_bucket`
- -- with `minsize` worst case collisions
- local bestpos, minsize, best_bucket = nil, #strs * 2, nil
- for pos = 1, len do
- local try_bucket = {}
- for _, str in ipairs(strs) do
- local poschar = string.sub(str, pos, pos)
- table.insert(setdefault(try_bucket, poschar), str)
- end
- local maxsize = 1
- for _, pos_strs in pairs(try_bucket) do
- maxsize = math.max(maxsize, #pos_strs)
- end
- if maxsize < minsize then
- bestpos = pos
- minsize = maxsize
- best_bucket = try_bucket
- end
- end
- len_pos_buckets[len] = { bestpos, best_bucket }
- worst_buck_size = math.max(worst_buck_size, minsize)
- end
- end
- return len_pos_buckets, maxlen, worst_buck_size
-end
-
-function M.switcher(put, tab, maxlen, worst_buck_size)
- local neworder = {} --- @type string[]
- put ' switch (len) {\n'
- local bucky = worst_buck_size > 1
- for len = 1, maxlen do
- local vals = tab[len]
- if vals then
- put(' case ' .. len .. ': ')
- local pos, posbuck = unpack(vals)
- local keys = vim.tbl_keys(posbuck)
- if #keys > 1 then
- table.sort(keys)
- put('switch (str[' .. (pos - 1) .. ']) {\n')
- for _, c in ipairs(keys) do
- local buck = posbuck[c]
- local startidx = #neworder
- vim.list_extend(neworder, buck)
- local endidx = #neworder
- put(" case '" .. c .. "': ")
- if len == 1 then
- put('return ' .. startidx .. ';\n')
- else
- put('low = ' .. startidx .. '; ')
- if bucky then
- put('high = ' .. endidx .. '; ')
- end
- put 'break;\n'
- end
- end
- put ' default: break;\n'
- put ' }\n '
- else
- local startidx = #neworder
- table.insert(neworder, posbuck[keys[1]][1])
- local endidx = #neworder
- put('low = ' .. startidx .. '; ')
- if bucky then
- put('high = ' .. endidx .. '; ')
- end
- end
- put 'break;\n'
- end
- end
- put ' default: break;\n'
- put ' }\n'
- return neworder
-end
-
-function M.hashy_hash(name, strings, access)
- local stats = {}
- local put = function(str)
- table.insert(stats, str)
- end
- local len_pos_buckets, maxlen, worst_buck_size = M.build_pos_hash(strings)
- put('int ' .. name .. '_hash(const char *str, size_t len)\n{\n')
- if maxlen == 1 then
- put('\n') -- nothing
- elseif worst_buck_size > 1 then
- put(' int low = 0, high = 0;\n')
- else
- put(' int low = -1;\n')
- end
- local neworder = M.switcher(put, len_pos_buckets, maxlen, worst_buck_size)
- if maxlen == 1 then
- put([[
- return -1;
-]])
- elseif worst_buck_size > 1 then
- put([[
- for (int i = low; i < high; i++) {
- if (!memcmp(str, ]] .. access('i') .. [[, len)) {
- return i;
- }
- }
- return -1;
-]])
- else
- put([[
- if (low < 0 || memcmp(str, ]] .. access('low') .. [[, len)) {
- return -1;
- }
- return low;
-]])
- end
- put '}\n\n'
- return neworder, table.concat(stats)
-end
-
-return M
diff --git a/src/nvim/generators/nvim_version.lua.in b/src/nvim/generators/nvim_version.lua.in
deleted file mode 100644
index c29141fc68..0000000000
--- a/src/nvim/generators/nvim_version.lua.in
+++ /dev/null
@@ -1,9 +0,0 @@
-return {
- {"major", ${NVIM_VERSION_MAJOR}},
- {"minor", ${NVIM_VERSION_MINOR}},
- {"patch", ${NVIM_VERSION_PATCH}},
- {"prerelease", "${NVIM_VERSION_PRERELEASE}" ~= ""},
- {"api_level", ${NVIM_API_LEVEL}},
- {"api_compatible", ${NVIM_API_LEVEL_COMPAT}},
- {"api_prerelease", ${NVIM_API_PRERELEASE}},
-}
diff --git a/src/nvim/generators/preload.lua b/src/nvim/generators/preload.lua
deleted file mode 100644
index e14671074c..0000000000
--- a/src/nvim/generators/preload.lua
+++ /dev/null
@@ -1,13 +0,0 @@
-local srcdir = table.remove(arg, 1)
-local nlualib = table.remove(arg, 1)
-local gendir = table.remove(arg, 1)
-package.path = srcdir .. '/src/nvim/?.lua;' .. srcdir .. '/runtime/lua/?.lua;' .. package.path
-package.path = gendir .. '/?.lua;' .. package.path
-_G.vim = require 'vim.shared'
-_G.vim.inspect = require 'vim.inspect'
-package.cpath = package.cpath .. ';' .. nlualib
-require 'nlua0'
-vim.NIL = vim.mpack.NIL -- WOW BOB WOW
-
-arg[0] = table.remove(arg, 1)
-return loadfile(arg[0])()