aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/generators
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/generators')
-rw-r--r--src/nvim/generators/c_grammar.lua131
-rw-r--r--src/nvim/generators/dump_bin_array.lua4
-rw-r--r--src/nvim/generators/gen_api_dispatch.lua714
-rw-r--r--src/nvim/generators/gen_api_ui_events.lua121
-rw-r--r--src/nvim/generators/gen_char_blob.lua31
-rw-r--r--src/nvim/generators/gen_declarations.lua200
-rw-r--r--src/nvim/generators/gen_eval.lua43
-rw-r--r--src/nvim/generators/gen_events.lua10
-rw-r--r--src/nvim/generators/gen_ex_cmds.lua81
-rw-r--r--src/nvim/generators/gen_options.lua156
-rw-r--r--src/nvim/generators/gen_options_enum.lua129
-rw-r--r--src/nvim/generators/gen_unicode_tables.lua33
-rw-r--r--src/nvim/generators/gen_vimvim.lua20
-rw-r--r--src/nvim/generators/hashy.lua83
-rw-r--r--src/nvim/generators/nvim_version.lua.in9
-rw-r--r--src/nvim/generators/preload.lua7
16 files changed, 1130 insertions, 642 deletions
diff --git a/src/nvim/generators/c_grammar.lua b/src/nvim/generators/c_grammar.lua
index f33da452ff..9ce9f3d7a6 100644
--- a/src/nvim/generators/c_grammar.lua
+++ b/src/nvim/generators/c_grammar.lua
@@ -6,61 +6,112 @@ local lpeg = vim.lpeg
local P, R, S = lpeg.P, lpeg.R, lpeg.S
local C, Ct, Cc, Cg = lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cg
+--- @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) -- (consume one character)
local letter = R('az', 'AZ') + S('_$')
local num = R('09')
local alpha = letter + num
local nl = P('\r\n') + P('\n')
local not_nl = any - nl
-local ws = S(' \t') + nl
-local fill = ws ^ 0
-local c_comment = P('//') * (not_nl ^ 0)
-local c_preproc = P('#') * (not_nl ^ 0)
-local dllexport = P('DLLEXPORT') * (ws ^ 1)
-local typed_container =
- (P('ArrayOf(') + P('DictionaryOf(') + P('Dict(')) * ((any - P(')')) ^ 1) * P(')')
-local c_id = (
- typed_container +
- (letter * (alpha ^ 0))
+local space = S(' \t')
+local ws = space + nl
+local fill = rep(ws)
+local c_comment = P('//') * rep(not_nl)
+local cdoc_comment = P('///') * opt(Ct(Cg(rep(space) * rep(not_nl), 'comment')))
+local c_preproc = P('#') * rep(not_nl)
+local dllexport = P('DLLEXPORT') * rep1(ws)
+
+local typed_container = (
+ (P('ArrayOf(') + P('DictionaryOf(') + P('Dict('))
+ * rep1(any - P(')'))
+ * P(')')
)
+
+local c_id = (typed_container + (letter * rep(alpha)))
local c_void = P('void')
+
local c_param_type = (
- ((P('Error') * fill * P('*') * fill) * Cc('error')) +
- ((P('Arena') * fill * P('*') * fill) * Cc('arena')) +
- ((P('lua_State') * fill * P('*') * fill) * Cc('lstate')) +
- C((P('const ') ^ -1) * (c_id) * (ws ^ 1) * P('*')) +
- (C(c_id) * (ws ^ 1))
- )
+ ((P('Error') * fill * P('*') * fill) * Cc('error'))
+ + ((P('Arena') * fill * P('*') * fill) * Cc('arena'))
+ + ((P('lua_State') * fill * P('*') * fill) * Cc('lstate'))
+ + C(opt(P('const ')) * c_id * rep1(ws) * rep1(P('*')))
+ + (C(c_id) * rep1(ws))
+)
+
local c_type = (C(c_void) * (ws ^ 1)) + c_param_type
local c_param = Ct(c_param_type * C(c_id))
local c_param_list = c_param * (fill * (P(',') * fill * c_param) ^ 0)
local c_params = Ct(c_void + c_param_list)
+
+local impl_line = (any - P('}')) * opt(rep(not_nl)) * nl
+
+local ignore_line = rep1(not_nl) * nl
+
+local empty_line = Ct(Cc('empty') * nl * nl)
+
local c_proto = Ct(
- (dllexport ^ -1) *
- Cg(c_type, 'return_type') * Cg(c_id, 'name') *
- fill * P('(') * fill * Cg(c_params, 'parameters') * fill * P(')') *
- Cg(Cc(false), 'fast') *
- (fill * Cg((P('FUNC_API_SINCE(') * C(num ^ 1)) * P(')'), 'since') ^ -1) *
- (fill * Cg((P('FUNC_API_DEPRECATED_SINCE(') * C(num ^ 1)) * P(')'),
- 'deprecated_since') ^ -1) *
- (fill * Cg((P('FUNC_API_FAST') * Cc(true)), 'fast') ^ -1) *
- (fill * Cg((P('FUNC_API_NOEXPORT') * Cc(true)), 'noexport') ^ -1) *
- (fill * Cg((P('FUNC_API_REMOTE_ONLY') * Cc(true)), 'remote_only') ^ -1) *
- (fill * Cg((P('FUNC_API_LUA_ONLY') * Cc(true)), 'lua_only') ^ -1) *
- (fill * (Cg(P('FUNC_API_TEXTLOCK_ALLOW_CMDWIN') * Cc(true), 'textlock_allow_cmdwin') +
- Cg(P('FUNC_API_TEXTLOCK') * Cc(true), 'textlock')) ^ -1) *
- (fill * Cg((P('FUNC_API_REMOTE_IMPL') * Cc(true)), 'remote_impl') ^ -1) *
- (fill * Cg((P('FUNC_API_COMPOSITOR_IMPL') * Cc(true)), 'compositor_impl') ^ -1) *
- (fill * Cg((P('FUNC_API_CLIENT_IMPL') * Cc(true)), 'client_impl') ^ -1) *
- (fill * Cg((P('FUNC_API_CLIENT_IGNORE') * Cc(true)), 'client_ignore') ^ -1) *
- fill * P(';')
- )
+ Cc('proto')
+ * opt(dllexport)
+ * opt(Cg(P('static') * fill * Cc(true), 'static'))
+ * Cg(c_type, 'return_type')
+ * Cg(c_id, 'name')
+ * fill
+ * (P('(') * fill * Cg(c_params, 'parameters') * fill * P(')'))
+ * Cg(Cc(false), 'fast')
+ * (fill * Cg((P('FUNC_API_SINCE(') * C(rep1(num))) * P(')'), 'since') ^ -1)
+ * (fill * Cg((P('FUNC_API_DEPRECATED_SINCE(') * C(rep1(num))) * P(')'), 'deprecated_since') ^ -1)
+ * (fill * Cg((P('FUNC_API_FAST') * Cc(true)), 'fast') ^ -1)
+ * (fill * Cg((P('FUNC_API_RET_ALLOC') * Cc(true)), 'ret_alloc') ^ -1)
+ * (fill * Cg((P('FUNC_API_NOEXPORT') * Cc(true)), 'noexport') ^ -1)
+ * (fill * Cg((P('FUNC_API_REMOTE_ONLY') * Cc(true)), 'remote_only') ^ -1)
+ * (fill * Cg((P('FUNC_API_LUA_ONLY') * Cc(true)), 'lua_only') ^ -1)
+ * (fill * (Cg(P('FUNC_API_TEXTLOCK_ALLOW_CMDWIN') * Cc(true), 'textlock_allow_cmdwin') + Cg(
+ P('FUNC_API_TEXTLOCK') * Cc(true),
+ 'textlock'
+ )) ^ -1)
+ * (fill * Cg((P('FUNC_API_REMOTE_IMPL') * Cc(true)), 'remote_impl') ^ -1)
+ * (fill * Cg((P('FUNC_API_COMPOSITOR_IMPL') * Cc(true)), 'compositor_impl') ^ -1)
+ * (fill * Cg((P('FUNC_API_CLIENT_IMPL') * Cc(true)), 'client_impl') ^ -1)
+ * (fill * Cg((P('FUNC_API_CLIENT_IGNORE') * Cc(true)), 'client_ignore') ^ -1)
+ * fill
+ * (P(';') + (P('{') * nl + (impl_line ^ 0) * P('}')))
+)
local c_field = Ct(Cg(c_id, 'type') * ws * Cg(c_id, 'name') * fill * P(';') * fill)
local c_keyset = Ct(
- P('typedef') * ws * P('struct') * fill * P('{') * fill *
- Cg(Ct(c_field ^ 1), 'fields') *
- P('}') * fill * P('Dict') * fill * P('(') * Cg(c_id, 'keyset_name') * fill * P(')') * P(';'))
+ P('typedef')
+ * ws
+ * P('struct')
+ * fill
+ * P('{')
+ * fill
+ * Cg(Ct(c_field ^ 1), 'fields')
+ * P('}')
+ * fill
+ * P('Dict')
+ * fill
+ * P('(')
+ * Cg(c_id, 'keyset_name')
+ * fill
+ * P(')')
+ * P(';')
+)
-local grammar = Ct((c_proto + c_comment + c_preproc + ws + c_keyset) ^ 1)
-return {grammar=grammar, typed_container=typed_container}
+local grammar = Ct(
+ rep1(empty_line + c_proto + cdoc_comment + c_comment + c_preproc + ws + c_keyset + ignore_line)
+)
+return { grammar = grammar, typed_container = typed_container }
diff --git a/src/nvim/generators/dump_bin_array.lua b/src/nvim/generators/dump_bin_array.lua
index bee5aba73f..c6cda25e73 100644
--- a/src/nvim/generators/dump_bin_array.lua
+++ b/src/nvim/generators/dump_bin_array.lua
@@ -1,10 +1,10 @@
local function dump_bin_array(output, name, data)
output:write([[
- static const uint8_t ]]..name..[[[] = {
+ static const uint8_t ]] .. name .. [[[] = {
]])
for i = 1, #data do
- output:write(string.byte(data, i)..', ')
+ output:write(string.byte(data, i) .. ', ')
if i % 10 == 0 then
output:write('\n ')
end
diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua
index 9720cca477..04b4363e42 100644
--- a/src/nvim/generators/gen_api_dispatch.lua
+++ b/src/nvim/generators/gen_api_dispatch.lua
@@ -1,16 +1,19 @@
local mpack = vim.mpack
-local hashy = require'generators.hashy'
+local hashy = require 'generators.hashy'
-assert(#arg >= 5)
+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 (funcs_metadata.generated.h)
-local funcs_metadata_outputf = arg[2]
+-- 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 (api_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 = {}
@@ -23,16 +26,18 @@ local function_names = {}
local c_grammar = require('generators.c_grammar')
-local function startswith(String,Start)
- return string.sub(String,1,string.len(Start))==Start
-end
+local startswith = vim.startswith
local function add_function(fn)
- local public = startswith(fn.name, "nvim_") or fn.deprecated_since
+ 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
+ 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
@@ -51,15 +56,14 @@ local function add_function(fn)
-- for specifying errors
fn.parameters[#fn.parameters] = nil
end
- if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'arena' then
- -- return value is allocated in an arena
- fn.arena_return = true
- 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
@@ -70,7 +74,7 @@ local function add_keyset(val)
local types = {}
local is_set_name = 'is_set__' .. val.keyset_name .. '_'
local has_optional = false
- for i,field in ipairs(val.fields) do
+ for i, field in ipairs(val.fields) do
if field.type ~= 'Object' then
types[field.name] = field.type
end
@@ -80,36 +84,46 @@ local function add_keyset(val)
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)
+ 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'")
+ error("'" .. is_set_name .. "' must have type 'OptionalKeys'")
end
has_optional = true
end
end
- table.insert(keysets, {name=val.keyset_name, keys=keys, types=types, has_optional=has_optional})
+ table.insert(keysets, {
+ name = val.keyset_name,
+ keys = keys,
+ 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 = 6, #arg do
+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]
+ headers[#headers + 1] = parts[#parts - 1] .. '/' .. parts[#parts]
- local input = io.open(full_path, 'rb')
+ local input = assert(io.open(full_path, 'rb'))
- local tmp = c_grammar.grammar:match(input:read('*all'))
+ 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)
- else
+ 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
@@ -123,14 +137,14 @@ 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 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
+ 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")
+ print('Function ' .. f.name .. ' lacks since field.\n')
os.exit(1)
end
f.since = tonumber(f.since)
@@ -138,16 +152,16 @@ for _,f in ipairs(shallowcopy(functions)) do
f.deprecated_since = tonumber(f.deprecated_since)
end
- if startswith(f.name, "nvim_buf_") then
+ if startswith(f.name, 'nvim_buf_') then
ismethod = true
- elseif startswith(f.name, "nvim_win_") then
+ elseif startswith(f.name, 'nvim_win_') then
ismethod = true
- elseif startswith(f.name, "nvim_tabpage_") then
+ 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)
+ f.eval = (not f.lua_only) and not f.remote_only
else
f.deprecated_since = tonumber(f.deprecated_since)
assert(f.deprecated_since == 1)
@@ -159,63 +173,127 @@ for _,f in ipairs(shallowcopy(functions)) do
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")
+ 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
+ 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"
+ 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
+ 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_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
+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
+ 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] == "DictionaryOf(LuaRef)" then
- param = {"Dictionary", param[2]}
- elseif startswith(param[1], "Dict(") then
- param = {"Dictionary", param[2]}
+ for i, param in ipairs(f.parameters) do
+ if param[1] == 'DictionaryOf(LuaRef)' then
+ param = { 'Dictionary', param[2] }
+ elseif startswith(param[1], 'Dict(') then
+ param = { 'Dictionary', param[2] }
end
f_exported.parameters[i] = param
end
- exported_functions[#exported_functions+1] = f_exported
+ if startswith(f.return_type, 'Dict(') then
+ f_exported.return_type = 'Dictionary'
+ 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'
+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 funcs_metadata_output = io.open(funcs_metadata_outputf, 'wb')
-local packed = mpack.encode(exported_functions)
-local dump_bin_array = require("generators.dump_bin_array")
-dump_bin_array(funcs_metadata_output, 'funcs_metadata', packed)
-funcs_metadata_output:close()
+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 placholder vim.NIL (than invalid mpack data)
+ put(item[1], item[2] or vim.NIL)
+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 = io.open(dispatch_outputf, 'wb')
+local output = assert(io.open(dispatch_outputf, 'wb'))
-local keysets_defs = io.open(keysets_outputf, 'wb')
+local keysets_defs = assert(io.open(keysets_outputf, 'wb'))
-- ===========================================================================
-- NEW API FILES MUST GO HERE.
@@ -226,9 +304,9 @@ local keysets_defs = io.open(keysets_outputf, 'wb')
output:write([[
#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/msgpack_rpc/helpers.h"
#include "nvim/api/autocmd.h"
#include "nvim/api/buffer.h"
@@ -246,67 +324,84 @@ output:write([[
]])
-for _,k in ipairs(keysets) do
+keysets_defs:write('// IWYU pragma: private, include "nvim/api/private/dispatch.h"\n\n')
+
+for _, k in ipairs(keysets) do
local c_name = {}
- for i = 1,#k.keys do
+ for i = 1, #k.keys do
-- some keys, like "register" are c keywords and get
-- escaped with a trailing _ in the struct.
- if vim.endswith(k.keys[i], "_") then
+ if vim.endswith(k.keys[i], '_') then
local orig = k.keys[i]
- k.keys[i] = string.sub(k.keys[i],1, #(k.keys[i]) - 1)
+ k.keys[i] = string.sub(k.keys[i], 1, #k.keys[i] - 1)
c_name[k.keys[i]] = orig
k.types[k.keys[i]] = k.types[orig]
end
end
- local neworder, hashfun = hashy.hashy_hash(k.name, k.keys, function (idx)
- return k.name.."_table["..idx.."].str"
+ 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[];\n")
+ keysets_defs:write('extern KeySetLink ' .. k.name .. '_table[' .. (1 + #neworder) .. '];\n')
local function typename(type)
- if type ~= nil then
- return "kObjectType"..type
+ if type == 'HLGroupID' then
+ return 'kObjectTypeInteger'
+ elseif type ~= nil then
+ return 'kObjectType' .. type
else
- return "kObjectTypeNil"
+ return 'kObjectTypeNil'
end
end
- output:write("KeySetLink "..k.name.."_table[] = {\n")
+ 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..", "..(c_name[key] or key).."), "..typename(k.types[key])..", "..ind.."},\n")
+ keysets_defs:write('#define KEYSET_OPTIDX_' .. k.name .. '__' .. key .. ' ' .. ind .. '\n')
+ end
+ output:write(
+ ' {"'
+ .. key
+ .. '", offsetof(KeyDict_'
+ .. k.name
+ .. ', '
+ .. (c_name[key] or key)
+ .. '), '
+ .. typename(k.types[key])
+ .. ', '
+ .. ind
+ .. ', '
+ .. (k.types[key] == 'HLGroupID' and 'true' or 'false')
+ .. '},\n'
+ )
end
- output:write(' {NULL, 0, kObjectTypeNil, -1},\n')
- output:write("};\n\n")
+ 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)
+KeySetLink *KeyDict_]] .. k.name .. [[_get_field(const char *str, size_t len)
{
- int hash = ]]..k.name..[[_hash(str, len);
+ int hash = ]] .. k.name .. [[_hash(str, len);
if (hash == -1) {
return NULL;
}
- return &]]..k.name..[[_table[hash];
+ return &]] .. k.name .. [[_table[hash];
}
]])
- keysets_defs:write("#define api_free_keydict_"..k.name.."(x) api_free_keydict(x, "..k.name.."_table)\n")
end
local function real_type(type)
local rv = type
- local rmatch = string.match(type, "Dict%(([_%w]+)%)")
+ local rmatch = string.match(type, 'Dict%(([_%w]+)%)')
if rmatch then
- return "KeyDict_"..rmatch
+ return 'KeyDict_' .. rmatch
elseif c_grammar.typed_container:match(rv) then
if rv:match('Array') then
rv = 'Array'
@@ -333,24 +428,30 @@ for i = 1, #functions do
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(
+ '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 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..';')
+ 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 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
@@ -359,55 +460,121 @@ for i = 1, #functions do
for j = 1, #fn.parameters do
local converted, param
param = fn.parameters[j]
- converted = 'arg_'..j
+ converted = 'arg_' .. j
local rt = real_type(param[1])
if rt == 'Object' then
- output:write('\n '..converted..' = args.items['..(j - 1)..'];\n')
+ 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 == kObjectTypeDictionary) {') --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.dictionary, error)) {')
+ output:write('\n if (args.items[' .. (j - 1) .. '].type == kObjectTypeDictionary) {') --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.dictionary, 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 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 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;')
+ 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)..';')
+ 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
+ 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;')
+ 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;')
+ 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('^Dictionary') 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..' = (Dictionary)ARRAY_DICT_INIT;')
+ 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 .. ' = (Dictionary)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 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
@@ -427,127 +594,127 @@ for i = 1, #functions do
end
-- function call
- local call_args = table.concat(args, ', ')
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 = ')
+ output:write(fn.return_type .. ' rv = ')
end
-- write the function name and the opening parenthesis
- output:write(fn.name..'(')
+ output:write(fn.name .. '(')
+ local call_args = {}
if fn.receives_channel_id then
- -- if the function receives the channel id, pass it as first argument
- if #args > 0 or fn.can_fail then
- output:write('channel_id, ')
- if fn.receives_array_args then
- -- if the function receives the array args, pass it the second argument
- output:write('args, ')
- end
- output:write(call_args)
- else
- output:write('channel_id')
- if fn.receives_array_args then
- output:write(', args')
- end
- end
- else
- if fn.receives_array_args then
- if #args > 0 or fn.call_fail then
- output:write('args, '..call_args)
- else
- output:write('args')
- end
- else
- output:write(call_args)
- end
+ table.insert(call_args, 'channel_id')
+ end
+
+ if fn.receives_array_args then
+ table.insert(call_args, 'args')
end
- if fn.arena_return then
- output:write(', arena')
+ 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
- if #args > 0 then
- output:write(', NULL')
- else
- output:write('NULL')
- end
+ 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
- if #args > 0 then
- output:write(', error);\n')
- else
- output:write('error);\n')
- end
-- and check for the error
output:write('\n if (ERROR_SET(error)) {')
output:write('\n goto cleanup;')
output:write('\n }\n')
- else
- output:write(');\n')
end
- if fn.return_type ~= 'void' then
- output:write('\n ret = '..string.upper(real_type(fn.return_type))..'_OBJ(rv);')
+ 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 = DICTIONARY_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\ncleanup:')
- output:write('\n return ret;\n}\n\n');
+ output:write('\n return ret;\n}\n\n')
end
end
local remote_fns = {}
-for _,fn in ipairs(functions) do
+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}
+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"
+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")
+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)..', .arena_return = '..tostring(not not fn.arena_return)..'},\n')
+ 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('};\n\n')
output:write(hashfun)
output:close()
functions.keysets = keysets
-local mpack_output = io.open(mpack_outputf, 'wb')
+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]..'"')
+ output_handle:write('\n#include "nvim/' .. headers_to_include[i] .. '"')
end
end
end
-local function write_shifted_output(_, str)
+local function write_shifted_output(str, ...)
str = str:gsub('\n ', '\n')
str = str:gsub('^ ', '')
str = str:gsub(' +$', '')
- output:write(str)
+ output:write(string.format(str, ...))
end
-- start building lua output
-output = io.open(lua_c_bindings_outputf, 'wb')
+output = assert(io.open(lua_c_bindings_outputf, 'wb'))
output:write([[
#include <lua.h>
@@ -557,6 +724,7 @@ output:write([[
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
#include "nvim/func_attr.h"
+#include "nvim/globals.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
#include "nvim/api/private/dispatch.h"
@@ -572,42 +740,51 @@ local lua_c_functions = {}
local function process_function(fn)
local lua_c_function_name = ('nlua_api_%s'):format(fn.name)
- write_shifted_output(output, string.format([[
+ 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_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
+ binding = lua_c_function_name,
+ api = fn.name,
}
if not fn.fast then
- write_shifted_output(output, string.format([[
+ write_shifted_output(
+ [[
if (!nlua_is_deferred_safe()) {
return luaL_error(lstate, e_luv_api_disabled, "%s");
}
- ]], fn.name))
+ ]],
+ fn.name
+ )
end
if fn.textlock then
- write_shifted_output(output, [[
+ write_shifted_output([[
if (text_locked()) {
- api_set_error(&err, kErrorTypeException, "%s", get_text_locked_msg());
+ api_set_error(&err, kErrorTypeException, "%%s", get_text_locked_msg());
goto exit_0;
}
]])
elseif fn.textlock_allow_cmdwin then
- write_shifted_output(output, [[
+ write_shifted_output([[
if (textlock != 0 || expr_map_locked()) {
- api_set_error(&err, kErrorTypeException, "%s", e_textlock);
+ api_set_error(&err, kErrorTypeException, "%%s", e_textlock);
goto exit_0;
}
]])
@@ -615,48 +792,69 @@ local function process_function(fn)
local cparams = ''
local free_code = {}
- for j = #fn.parameters,1,-1 do
+ 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 lc_param_type = real_type(param[1]):lower()
- local extra = param_type == "Dictionary" and "false, " or ""
- if param[1] == "Object" or param[1] == "DictionaryOf(LuaRef)" then
- extra = "true, "
+ local extra = param_type == 'Dictionary' 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] == 'DictionaryOf(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(output, string.format([[
- %s %s = { 0 }; nlua_pop_keydict(lstate, &%s, %s_get_field, &err_param, &err);]], param_type, cparam, cparam, param_type))
- cparam = '&'..cparam
+ 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(output, string.format([[
- const %s %s = nlua_pop_%s(lstate, %s&err);]], param[1], cparam, param_type, extra))
- seterr = [[
- err_param = "]]..param[2]..[[";]]
+ 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(output, string.format([[
+ write_shifted_output([[
+
+ if (ERROR_SET(&err)) {]] .. seterr .. [[
- if (ERROR_SET(&err)) {]]..seterr..[[
goto exit_%u;
}
- ]], #fn.parameters - j + errshift))
- free_code[#free_code + 1] = ('api_free_%s(%s);'):format(
- lc_param_type, cparam)
+ ]], #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.arena_return then
+ if fn.receives_arena then
cparams = cparams .. '&arena, '
- write_shifted_output(output, [[
- Arena arena = ARENA_EMPTY;
- ]])
end
if fn.has_lua_imp then
@@ -673,28 +871,28 @@ local function process_function(fn)
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)
+ free_at_exit_code = free_at_exit_code .. ('\n %s'):format(code)
else
- free_at_exit_code = free_at_exit_code .. ('\n exit_%u:\n %s'):format(
- rev_i, code)
+ free_at_exit_code = free_at_exit_code .. ('\nexit_%u:\n %s'):format(rev_i, code)
end
end
local err_throw_code = [[
- exit_0:
- 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);
+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
@@ -702,45 +900,68 @@ local function process_function(fn)
else
return_type = fn.return_type
end
- local free_retval
- if fn.arena_return then
- free_retval = "arena_mem_free(arena_finish(&arena));"
- else
- free_retval = "api_free_"..return_type:lower().."(ret);"
+ local free_retval = ''
+ if fn.ret_alloc then
+ free_retval = ' api_free_' .. return_type:lower() .. '(ret);'
end
- write_shifted_output(output, string.format([[
- const %s ret = %s(%s);
- ]], fn.return_type, fn.name, cparams))
+ 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(output, string.format([[
+ write_shifted_output(string.format(
+ [[
if (lua_gettop(lstate) == 0) {
- nlua_push_%s(lstate, ret, true);
+ nlua_push_%s(lstate, %sret, true);
}
- ]], return_type))
+ ]],
+ 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(output, string.format([[
- nlua_push_%s(lstate, ret, %s);
- ]], return_type, tostring(special)))
+ write_shifted_output(
+ ' nlua_push_%s(lstate, %sret, %s);\n',
+ return_type,
+ ret_mode,
+ tostring(special)
+ )
end
- write_shifted_output(output, string.format([[
+ -- 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))
+ ]],
+ free_retval,
+ free_at_exit_code,
+ err_throw_code
+ )
else
- write_shifted_output(output, string.format([[
+ write_shifted_output(
+ [[
%s(%s);
%s
%s
return 0;
- ]], fn.name, cparams, free_at_exit_code, err_throw_code))
+ ]],
+ fn.name,
+ cparams,
+ free_at_exit_code,
+ err_throw_code
+ )
end
- write_shifted_output(output, [[
+ write_shifted_output([[
}
]])
end
@@ -751,18 +972,25 @@ for _, fn in ipairs(functions) do
end
end
-output:write(string.format([[
-void nlua_add_api_functions(lua_State *lstate); // silence -Wmissing-prototypes
+output:write(string.format(
+ [[
+void nlua_add_api_functions(lua_State *lstate)
+ REAL_FATTR_NONNULL_ALL;
void nlua_add_api_functions(lua_State *lstate)
- FUNC_ATTR_NONNULL_ALL
{
lua_createtable(lstate, 0, %u);
-]], #lua_c_functions))
+]],
+ #lua_c_functions
+))
for _, func in ipairs(lua_c_functions) do
- output:write(string.format([[
+ output:write(string.format(
+ [[
lua_pushcfunction(lstate, &%s);
- lua_setfield(lstate, -2, "%s");]], func.binding, func.api))
+ lua_setfield(lstate, -2, "%s");]],
+ func.binding,
+ func.api
+ ))
end
output:write([[
diff --git a/src/nvim/generators/gen_api_ui_events.lua b/src/nvim/generators/gen_api_ui_events.lua
index e2af5f8d44..0808f71daa 100644
--- a/src/nvim/generators/gen_api_ui_events.lua
+++ b/src/nvim/generators/gen_api_ui_events.lua
@@ -10,11 +10,11 @@ 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 hashy = require 'generators.hashy'
local function write_signature(output, ev, prefix, notype)
- output:write('('..prefix)
- if prefix == "" and #ev.parameters == 0 then
+ output:write('(' .. prefix)
+ if prefix == '' and #ev.parameters == 0 then
output:write('void')
end
for j = 1, #ev.parameters do
@@ -23,7 +23,7 @@ local function write_signature(output, ev, prefix, notype)
end
local param = ev.parameters[j]
if not notype then
- output:write(param[1]..' ')
+ output:write(param[1] .. ' ')
end
output:write(param[2])
end
@@ -35,26 +35,28 @@ local function write_arglist(output, ev)
local param = ev.parameters[j]
local kind = string.upper(param[1])
output:write(' ADD_C(args, ')
- output:write(kind..'_OBJ('..param[2]..')')
+ 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')
+ 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))
+ 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 = 'Dictionary' end
- output:write('\n || args.items['..(j-1)..'].type != kObjectType'..kind..'')
+ if kind ~= 'Object' then
+ if kind == 'HlAttrs' then
+ kind = 'Dictionary'
+ 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(' ELOG("Error handling ui event \'' .. ev.name .. '\'");\n')
output:write(' return;\n')
output:write(' }\n')
end
@@ -62,106 +64,118 @@ local function call_ui_event_method(output, ev)
for j = 1, #ev.parameters do
local param = ev.parameters[j]
local kind = param[1]
- output:write(' '..kind..' arg_'..j..' = ')
+ 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.dictionary, '..(hlattrs_args_count == 0 and 'true' or 'false')..');\n')
+ output:write(
+ 'ui_client_dict2hlattrs(args.items['
+ .. (j - 1)
+ .. '].data.dictionary, '
+ .. (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')
+ output:write('args.items[' .. (j - 1) .. '];\n')
elseif kind == 'Window' then
- output:write('(Window)args.items['..(j-1)..'].data.integer;\n')
+ output:write('(Window)args.items[' .. (j - 1) .. '].data.integer;\n')
else
- output:write('args.items['..(j-1)..'].data.'..string.lower(kind)..';\n')
+ output:write('args.items[' .. (j - 1) .. '].data.' .. string.lower(kind) .. ';\n')
end
end
- output:write(' tui_'..ev.name..'(tui')
+ output:write(' tui_' .. ev.name .. '(tui')
for j = 1, #ev.parameters do
- output:write(', arg_'..j)
+ output:write(', arg_' .. j)
end
output:write(');\n')
output:write('}\n\n')
end
+events = vim.tbl_filter(function(ev)
+ return ev[1] ~= 'empty'
+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")
+ print('Ui event ' .. ev.name .. ' lacks since field.\n')
os.exit(1)
end
ev.since = tonumber(ev.since)
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, 'UI *ui')
+ remote_output:write('void remote_ui_' .. ev.name)
+ write_signature(remote_output, ev, 'RemoteUI *ui')
remote_output:write('\n{\n')
- remote_output:write(' UIData *data = ui->data;\n')
- remote_output:write(' Array args = data->call_buf;\n')
+ remote_output:write(' Array args = ui->call_buf;\n')
write_arglist(remote_output, ev)
- remote_output:write(' push_call(ui, "'..ev.name..'", args);\n')
+ 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)
+ call_output:write('void ui_call_' .. ev.name)
write_signature(call_output, ev, '')
call_output:write('\n{\n')
if ev.remote_only then
call_output:write(' Array args = call_buf;\n')
write_arglist(call_output, ev)
- call_output:write(' ui_call_event("'..ev.name..'", args);\n')
+ call_output:write(' ui_call_event("' .. ev.name .. '", args);\n')
elseif ev.compositor_impl then
- call_output:write(' ui_comp_'..ev.name)
+ call_output:write(' ui_comp_' .. ev.name)
write_signature(call_output, ev, '', true)
- call_output:write(";\n")
+ call_output:write(';\n')
call_output:write(' UI_CALL')
- write_signature(call_output, ev, '!ui->composed, '..ev.name..', ui', true)
- call_output:write(";\n")
+ 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")
+ write_signature(call_output, ev, 'true, ' .. ev.name .. ', ui', true)
+ call_output:write(';\n')
end
- call_output:write("}\n\n")
+ call_output:write('}\n\n')
end
if ev.compositor_impl then
- call_output:write('void ui_composed_call_'..ev.name)
+ 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")
+ 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
+ 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
+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)
+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")
+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')
+ client_output:write(' { .name = "' .. name .. '", .fn = ui_client_event_' .. name .. '},\n')
end
client_output:write('\n};\n\n')
@@ -172,25 +186,22 @@ 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_attributes = { 'name', 'parameters', 'since', 'deprecated_since' }
local exported_events = {}
-for _,ev in ipairs(events) do
+for _, ev in ipairs(events) do
local ev_exported = {}
- for _,attr in ipairs(exported_attributes) do
+ for _, attr in ipairs(exported_attributes) do
ev_exported[attr] = ev[attr]
end
- for _,p in ipairs(ev_exported.parameters) do
+ for _, p in ipairs(ev_exported.parameters) do
if p[1] == 'HlAttrs' then
p[1] = 'Dictionary'
end
end
if not ev.noexport then
- exported_events[#exported_events+1] = ev_exported
+ exported_events[#exported_events + 1] = ev_exported
end
end
-local packed = mpack.encode(exported_events)
-local dump_bin_array = require("generators.dump_bin_array")
-dump_bin_array(metadata_output, 'ui_events_metadata', packed)
+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
index 11f6cbcc13..c40e0d6e82 100644
--- a/src/nvim/generators/gen_char_blob.lua
+++ b/src/nvim/generators/gen_char_blob.lua
@@ -1,6 +1,6 @@
if arg[1] == '--help' then
print('Usage:')
- print(' '..arg[0]..' [-c] target source varname [source varname]...')
+ 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.')
@@ -12,7 +12,7 @@ end
local options = {}
while true do
- local opt = string.match(arg[1], "^-(%w)")
+ local opt = string.match(arg[1], '^-(%w)')
if not opt then
break
end
@@ -36,33 +36,33 @@ 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]))
+ 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"
+ 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")
+ 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")
+ 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")
+ 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
+ local MAX_NUM_BYTES = 15 -- 78 / 5: maximum number of bytes on one line
target:write(' ')
local increase_num_bytes
@@ -81,8 +81,11 @@ for argi = 2, #arg, 2 do
end
target:write(' 0};\n')
- if modname ~= "_" then
- table.insert(index_items, ' { "'..modname..'", '..varname..', sizeof '..varname..' },\n\n')
+ if modname ~= '_' then
+ table.insert(
+ index_items,
+ ' { "' .. modname .. '", ' .. varname .. ', sizeof ' .. varname .. ' },\n\n'
+ )
end
end
diff --git a/src/nvim/generators/gen_declarations.lua b/src/nvim/generators/gen_declarations.lua
index f9e9c6b0a8..5d1e586fe6 100644
--- a/src/nvim/generators/gen_declarations.lua
+++ b/src/nvim/generators/gen_declarations.lua
@@ -5,9 +5,9 @@ local preproc_fname = arg[4]
local lpeg = vim.lpeg
-local fold = function (func, ...)
+local fold = function(func, ...)
local result = nil
- for _, v in ipairs({...}) do
+ for _, v in ipairs({ ... }) do
if result == nil then
result = v
else
@@ -17,144 +17,112 @@ local fold = function (func, ...)
return result
end
-local folder = function (func)
- return function (...)
+local folder = function(func)
+ return function(...)
return fold(func, ...)
end
end
local lit = lpeg.P
local set = function(...)
- return lpeg.S(fold(function (a, b) return a .. b end, ...))
+ return lpeg.S(fold(function(a, b)
+ return a .. b
+ end, ...))
end
local any_character = lpeg.P(1)
-local rng = function(s, e) return lpeg.R(s .. e) end
-local concat = folder(function (a, b) return a * b end)
-local branch = folder(function (a, b) return a + b end)
-local one_or_more = function(v) return v ^ 1 end
-local two_or_more = function(v) return v ^ 2 end
-local any_amount = function(v) return v ^ 0 end
-local one_or_no = function(v) return v ^ -1 end
+local rng = function(s, e)
+ return lpeg.R(s .. e)
+end
+local concat = folder(function(a, b)
+ return a * b
+end)
+local branch = folder(function(a, b)
+ return a + b
+end)
+local one_or_more = function(v)
+ return v ^ 1
+end
+local two_or_more = function(v)
+ return v ^ 2
+end
+local any_amount = function(v)
+ return v ^ 0
+end
+local one_or_no = function(v)
+ return v ^ -1
+end
local look_behind = lpeg.B
-local look_ahead = function(v) return #v end
-local neg_look_ahead = function(v) return -v end
-local neg_look_behind = function(v) return -look_behind(v) end
+local look_ahead = function(v)
+ return #v
+end
+local neg_look_ahead = function(v)
+ return -v
+end
+local neg_look_behind = function(v)
+ return -look_behind(v)
+end
-local w = branch(
- rng('a', 'z'),
- rng('A', 'Z'),
- lit('_')
-)
-local aw = branch(
- w,
- rng('0', '9')
-)
+local w = branch(rng('a', 'z'), rng('A', 'Z'), lit('_'))
+local aw = branch(w, rng('0', '9'))
local s = set(' ', '\n', '\t')
local raw_word = concat(w, any_amount(aw))
-local right_word = concat(
- raw_word,
- neg_look_ahead(aw)
-)
+local right_word = concat(raw_word, neg_look_ahead(aw))
local word = branch(
concat(
branch(lit('ArrayOf('), lit('DictionaryOf('), lit('Dict(')), -- typed container macro
one_or_more(any_character - lit(')')),
lit(')')
),
- concat(
- neg_look_behind(aw),
- right_word
- )
-)
-local inline_comment = concat(
- lit('/*'),
- any_amount(concat(
- neg_look_ahead(lit('*/')),
- any_character
- )),
- lit('*/')
+ concat(neg_look_behind(aw), right_word)
)
+local inline_comment =
+ concat(lit('/*'), any_amount(concat(neg_look_ahead(lit('*/')), any_character)), lit('*/'))
local spaces = any_amount(branch(
s,
-- Comments are really handled by preprocessor, so the following is not needed
inline_comment,
- concat(
- lit('//'),
- any_amount(concat(
- neg_look_ahead(lit('\n')),
- any_character
- )),
- lit('\n')
- ),
+ concat(lit('//'), any_amount(concat(neg_look_ahead(lit('\n')), any_character)), lit('\n')),
-- Linemarker inserted by preprocessor
- concat(
- lit('# '),
- any_amount(concat(
- neg_look_ahead(lit('\n')),
- any_character
- )),
- lit('\n')
- )
+ concat(lit('# '), any_amount(concat(neg_look_ahead(lit('\n')), any_character)), lit('\n'))
))
-local typ_part = concat(
- word,
- any_amount(concat(
- spaces,
- lit('*')
- )),
- spaces
-)
+local typ_part = concat(word, any_amount(concat(spaces, lit('*'))), spaces)
local typ_id = two_or_more(typ_part)
-local arg = typ_id -- argument name is swallowed by typ
+local arg = typ_id -- argument name is swallowed by typ
local pattern = concat(
any_amount(branch(set(' ', '\t'), inline_comment)),
- typ_id, -- return type with function name
+ typ_id, -- return type with function name
spaces,
lit('('),
spaces,
- one_or_no(branch( -- function arguments
+ one_or_no(branch( -- function arguments
concat(
- arg, -- first argument, does not require comma
- any_amount(concat( -- following arguments, start with a comma
+ arg, -- first argument, does not require comma
+ any_amount(concat( -- following arguments, start with a comma
spaces,
lit(','),
spaces,
arg,
- any_amount(concat(
- lit('['),
- spaces,
- any_amount(aw),
- spaces,
- lit(']')
- ))
+ any_amount(concat(lit('['), spaces, any_amount(aw), spaces, lit(']')))
)),
- one_or_no(concat(
- spaces,
- lit(','),
- spaces,
- lit('...')
- ))
+ one_or_no(concat(spaces, lit(','), spaces, lit('...')))
),
- lit('void') -- also accepts just void
+ lit('void') -- also accepts just void
)),
spaces,
lit(')'),
- any_amount(concat( -- optional attributes
+ any_amount(concat( -- optional attributes
spaces,
lit('FUNC_'),
any_amount(aw),
- one_or_no(concat( -- attribute argument
+ one_or_no(concat( -- attribute argument
spaces,
lit('('),
- any_amount(concat(
- neg_look_ahead(lit(')')),
- any_character
- )),
+ any_amount(concat(neg_look_ahead(lit(')')), any_character)),
lit(')')
))
)),
- look_ahead(concat( -- definition must be followed by "{"
+ look_ahead(concat( -- definition must be followed by "{"
spaces,
lit('{')
))
@@ -164,7 +132,7 @@ if fname == '--help' then
print([[
Usage:
- gendeclarations.lua definitions.c static.h non-static.h definitions.i
+ 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
@@ -198,21 +166,13 @@ Additionally uses the following environment variables:
end
local preproc_f = io.open(preproc_fname)
-local text = preproc_f:read("*all")
+local text = preproc_f:read('*all')
preproc_f:close()
-
-local header = [[
+local non_static = [[
#define DEFINE_FUNC_ATTRIBUTES
#include "nvim/func_attr.h"
#undef DEFINE_FUNC_ATTRIBUTES
-]]
-
-local footer = [[
-#include "nvim/func_attr.h"
-]]
-
-local non_static = header .. [[
#ifndef DLLEXPORT
# ifdef MSWIN
# define DLLEXPORT __declspec(dllexport)
@@ -222,7 +182,20 @@ local non_static = header .. [[
#endif
]]
-local static = header
+local static = [[
+#define DEFINE_FUNC_ATTRIBUTES
+#include "nvim/func_attr.h"
+#undef DEFINE_FUNC_ATTRIBUTES
+]]
+
+local non_static_footer = [[
+#include "nvim/func_attr.h"
+]]
+
+local static_footer = [[
+#define DEFINE_EMPTY_ATTRIBUTES
+#include "nvim/func_attr.h" // IWYU pragma: export
+]]
if fname:find('.*/src/nvim/.*%.c$') then
-- Add an IWYU pragma comment if the corresponding .h file exists.
@@ -234,6 +207,22 @@ if fname:find('.*/src/nvim/.*%.c$') then
// IWYU pragma: private, include "%s"
]]):format(header_fname:gsub('.*/src/nvim/', 'nvim/')) .. non_static
end
+elseif non_static_fname:find('/include/api/private/dispatch_wrappers%.h%.generated%.h$') then
+ non_static = [[
+// IWYU pragma: private, include "nvim/api/private/dispatch.h"
+]] .. non_static
+elseif non_static_fname:find('/include/ui_events_call%.h%.generated%.h$') then
+ non_static = [[
+// IWYU pragma: private, include "nvim/ui.h"
+]] .. non_static
+elseif non_static_fname:find('/include/ui_events_client%.h%.generated%.h$') then
+ non_static = [[
+// IWYU pragma: private, include "nvim/ui_client.h"
+]] .. non_static
+elseif non_static_fname:find('/include/ui_events_remote%.h%.generated%.h$') then
+ non_static = [[
+// IWYU pragma: private, include "nvim/api/ui.h"
+]] .. non_static
end
local filepattern = '^#%a* (%d+) "([^"]-)/?([^"/]+)"'
@@ -283,8 +272,7 @@ while init ~= nil do
declaration = declaration .. ';'
if os.getenv('NVIM_GEN_DECLARATIONS_LINE_NUMBERS') == '1' then
- declaration = declaration .. (' // %s/%s:%u'):format(
- curdir, curfile, declline)
+ declaration = declaration .. (' // %s/%s:%u'):format(curdir, curfile, declline)
end
declaration = declaration .. '\n'
if declaration:sub(1, 6) == 'static' then
@@ -307,8 +295,8 @@ while init ~= nil do
end
end
-non_static = non_static .. footer
-static = static .. footer
+non_static = non_static .. non_static_footer
+static = static .. static_footer
local F
F = io.open(static_fname, 'w')
diff --git a/src/nvim/generators/gen_eval.lua b/src/nvim/generators/gen_eval.lua
index 7b272c337e..1ce7f1af9d 100644
--- a/src/nvim/generators/gen_eval.lua
+++ b/src/nvim/generators/gen_eval.lua
@@ -8,7 +8,7 @@ local funcsfname = autodir .. '/funcs.generated.h'
--Will generate funcs.generated.h with definition of functions static const array.
-local hashy = require'generators.hashy'
+local hashy = require 'generators.hashy'
local hashpipe = assert(io.open(funcsfname, 'wb'))
@@ -48,18 +48,18 @@ hashpipe:write([[
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.." }"
+ 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
+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..'] }'
+ args = #fun.parameters,
+ func = 'api_wrapper',
+ data = '{ .api_handler = &method_handlers[' .. fun.handler_id .. '] }',
}
end
end
@@ -74,28 +74,37 @@ 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"
+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")
+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}
+ args = { args, args }
elseif #args == 1 then
args[2] = 'MAX_FUNC_ARGS'
end
- local base = def.base or "BASE_NONE"
+ local base = def.base or 'BASE_NONE'
local func = def.func or ('f_' .. name)
- local data = def.data or "{ .null = NULL }"
+ 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))
+ 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('};\n\n')
hashpipe:write(hashfun)
hashpipe:close()
diff --git a/src/nvim/generators/gen_events.lua b/src/nvim/generators/gen_events.lua
index 4763a2f463..ee48e918e8 100644
--- a/src/nvim/generators/gen_events.lua
+++ b/src/nvim/generators/gen_events.lua
@@ -22,7 +22,7 @@ static const struct event_name {
for i, event in ipairs(events) do
enum_tgt:write(('\n EVENT_%s = %u,'):format(event:upper(), i - 1))
names_tgt:write(('\n {%u, "%s", EVENT_%s},'):format(#event, event, event:upper()))
- if i == #events then -- Last item.
+ if i == #events then -- Last item.
enum_tgt:write(('\n NUM_EVENTS = %u,'):format(i))
end
end
@@ -41,15 +41,15 @@ names_tgt:write('\n};\n')
do
names_tgt:write('\nstatic AutoCmdVec autocmds[NUM_EVENTS] = {\n ')
local line_len = 1
- for _ = 1,((#events) - 1) do
- line_len = line_len + #(' KV_INITIAL_VALUE,')
+ for _ = 1, (#events - 1) do
+ line_len = line_len + #' KV_INITIAL_VALUE,'
if line_len > 80 then
names_tgt:write('\n ')
- line_len = 1 + #(' KV_INITIAL_VALUE,')
+ line_len = 1 + #' KV_INITIAL_VALUE,'
end
names_tgt:write(' KV_INITIAL_VALUE,')
end
- if line_len + #(' KV_INITIAL_VALUE') > 80 then
+ if line_len + #' KV_INITIAL_VALUE' > 80 then
names_tgt:write('\n KV_INITIAL_VALUE')
else
names_tgt:write(' KV_INITIAL_VALUE')
diff --git a/src/nvim/generators/gen_ex_cmds.lua b/src/nvim/generators/gen_ex_cmds.lua
index ae8c952648..e8d1aac182 100644
--- a/src/nvim/generators/gen_ex_cmds.lua
+++ b/src/nvim/generators/gen_ex_cmds.lua
@@ -21,24 +21,32 @@ 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([[
+local cmdidxs1_out = string.format(
+ [[
static const uint16_t cmdidxs1[%u] = {
-]], a_to_z)
+]],
+ 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([[
+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)
+]],
+ 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([[
+defsfile:write(string.format(
+ [[
#include "nvim/arglist.h"
#include "nvim/autocmd.h"
#include "nvim/buffer.h"
@@ -79,23 +87,34 @@ defsfile:write(string.format([[
static const int command_count = %u;
static CommandDefinition cmdnames[%u] = {
-]], #defs, #defs))
+]],
+ #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))
+ 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))
+ 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))
+ 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))
+ 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()
@@ -104,12 +123,13 @@ for _, cmd in ipairs(defs) do
end
local preview_func
if cmd.preview_func then
- preview_func = string.format("&%s", cmd.preview_func)
+ preview_func = string.format('&%s', cmd.preview_func)
else
- preview_func = "NULL"
+ preview_func = 'NULL'
end
enumfile:write(' ' .. enumname .. ',\n')
- defsfile:write(string.format([[
+ defsfile:write(string.format(
+ [[
[%s] = {
.cmd_name = "%s",
.cmd_func = (ex_func_T)&%s,
@@ -117,7 +137,14 @@ for _, cmd in ipairs(defs) do
.cmd_argt = %uL,
.cmd_addr_type = %s
},
-]], enumname, cmd.command, cmd.func, preview_func, cmd.flags, cmd.addr_type))
+]],
+ enumname,
+ cmd.command,
+ cmd.func,
+ preview_func,
+ cmd.flags,
+ cmd.addr_type
+ ))
end
for i = #cmds, 1, -1 do
local cmd = cmds[i]
@@ -141,10 +168,12 @@ for i = byte_a, byte_z do
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') .. ','
+ 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
@@ -154,8 +183,12 @@ enumfile:write([[
CMD_USER_BUF = -2
} cmdidx_T;
]])
-defsfile:write(string.format([[
+defsfile:write(string.format(
+ [[
};
%s};
%s};
-]], cmdidxs1_out, cmdidxs2_out))
+]],
+ cmdidxs1_out,
+ cmdidxs2_out
+))
diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua
index 26ade2745d..749844e658 100644
--- a/src/nvim/generators/gen_options.lua
+++ b/src/nvim/generators/gen_options.lua
@@ -15,40 +15,43 @@ local options = require('options')
local cstr = options.cstr
-local type_flags={
- bool='P_BOOL',
- number='P_NUM',
- string='P_STRING',
+local redraw_flags = {
+ ui_option = 'P_UI_OPTION',
+ tabline = 'P_RTABL',
+ statuslines = 'P_RSTAT',
+ current_window = 'P_RWIN',
+ current_buffer = 'P_RBUF',
+ all_windows = 'P_RALL',
+ curswant = 'P_CURSWANT',
+ highlight_only = 'P_HLONLY',
}
-local redraw_flags={
- ui_option='P_UI_OPTION',
- tabline='P_RTABL',
- statuslines='P_RSTAT',
- current_window='P_RWIN',
- current_window_only='P_RWINONLY',
- current_buffer='P_RBUF',
- all_windows='P_RALL',
- curswant='P_CURSWANT',
+local list_flags = {
+ comma = 'P_COMMA',
+ onecomma = 'P_ONECOMMA',
+ commacolon = 'P_COMMA|P_COLON',
+ onecommacolon = 'P_ONECOMMA|P_COLON',
+ flags = 'P_FLAGLIST',
+ flagscomma = 'P_COMMA|P_FLAGLIST',
}
-local list_flags={
- comma='P_COMMA',
- onecomma='P_ONECOMMA',
- commacolon='P_COMMA|P_COLON',
- onecommacolon='P_ONECOMMA|P_COLON',
- flags='P_FLAGLIST',
- flagscomma='P_COMMA|P_FLAGLIST',
-}
+--- @param s string
+--- @return string
+local lowercase_to_titlecase = function(s)
+ return s:sub(1, 1):upper() .. s:sub(2)
+end
--- @param o vim.option_meta
--- @return string
local function get_flags(o)
- --- @type string[]
- local ret = {type_flags[o.type]}
+ --- @type string
+ local flags = '0'
+
+ --- @param f string
local add_flag = function(f)
- ret[1] = ret[1] .. '|' .. f
+ flags = flags .. '|' .. f
end
+
if o.list then
add_flag(list_flags[o.list])
end
@@ -64,19 +67,19 @@ local function get_flags(o)
end
end
for _, flag_desc in ipairs({
- {'alloced'},
- {'nodefault'},
- {'no_mkrc'},
- {'secure'},
- {'gettext'},
- {'noglob'},
- {'normal_fname_chars', 'P_NFNAME'},
- {'normal_dname_chars', 'P_NDNAME'},
- {'pri_mkrc'},
- {'deny_in_modelines', 'P_NO_ML'},
- {'deny_duplicates', 'P_NODUP'},
- {'modelineexpr', 'P_MLE'},
- {'func'}
+ { 'alloced' },
+ { 'nodefault' },
+ { 'no_mkrc' },
+ { 'secure' },
+ { 'gettext' },
+ { 'noglob' },
+ { 'normal_fname_chars', 'P_NFNAME' },
+ { 'normal_dname_chars', 'P_NDNAME' },
+ { 'pri_mkrc' },
+ { 'deny_in_modelines', 'P_NO_ML' },
+ { 'deny_duplicates', 'P_NODUP' },
+ { 'modelineexpr', 'P_MLE' },
+ { 'func' },
}) do
local key_name = flag_desc[1]
local def_name = flag_desc[2] or ('P_' .. key_name:upper())
@@ -84,7 +87,22 @@ local function get_flags(o)
add_flag(def_name)
end
end
- return ret[1]
+ return flags
+end
+
+--- @param o vim.option_meta
+--- @return string
+local function get_type_flags(o)
+ local opt_types = (type(o.type) == 'table') and o.type or { o.type }
+ local type_flags = '0'
+ assert(type(opt_types) == 'table')
+
+ for _, opt_type in ipairs(opt_types) do
+ assert(type(opt_type) == 'string')
+ type_flags = ('%s | (1 << kOptValType%s)'):format(type_flags, lowercase_to_titlecase(opt_type))
+ end
+
+ return type_flags
end
--- @param c string|string[]
@@ -107,23 +125,27 @@ local function get_cond(c, base_string)
return cond_string
end
-local value_dumpers = {
- ['function']=function(v) return v() end,
- string=cstr,
- boolean=function(v) return v and 'true' or 'false' end,
- number=function(v) return ('%iL'):format(v) end,
- ['nil']=function(_) return '0' end,
-}
-
-local get_value = function(v)
- return '(void *) ' .. value_dumpers[type(v)](v)
-end
-
-local get_defaults = function(d,n)
+local get_defaults = function(d, n)
if d == nil then
- error("option '"..n.."' should have a default value")
- end
- return get_value(d)
+ error("option '" .. n .. "' should have a default value")
+ end
+
+ local value_dumpers = {
+ ['function'] = function(v)
+ return v()
+ end,
+ string = function(v)
+ return '.string=' .. cstr(v)
+ end,
+ boolean = function(v)
+ return '.boolean=' .. (v and 'true' or 'false')
+ end,
+ number = function(v)
+ return ('.number=%iL'):format(v)
+ end,
+ }
+
+ return value_dumpers[type(d)](d)
end
--- @type {[1]:string,[2]:string}[]
@@ -138,12 +160,13 @@ local function dump_option(i, o)
w(' .shortname=' .. cstr(o.abbreviation))
end
w(' .flags=' .. get_flags(o))
+ w(' .type_flags=' .. get_type_flags(o))
if o.enable_if then
w(get_cond(o.enable_if))
end
if o.varname then
w(' .var=&' .. o.varname)
- -- Immutable options should directly point to the default value
+ -- Immutable options can directly point to the default value.
elseif o.immutable then
w((' .var=&options[%u].def_val'):format(i - 1))
elseif #o.scope == 1 and o.scope[1] == 'window' then
@@ -153,20 +176,21 @@ local function dump_option(i, o)
if #o.scope == 1 and o.scope[1] == 'global' then
w(' .indir=PV_NONE')
else
- assert (#o.scope == 1 or #o.scope == 2)
- assert (#o.scope == 1 or o.scope[1] == 'global')
+ assert(#o.scope == 1 or #o.scope == 2)
+ assert(#o.scope == 1 or o.scope[1] == 'global')
local min_scope = o.scope[#o.scope]
- local varname = o.pv_name or o.varname or (
- 'p_' .. (o.abbreviation or o.full_name))
+ local varname = o.pv_name or o.varname or ('p_' .. (o.abbreviation or o.full_name))
local pv_name = (
- 'OPT_' .. min_scope:sub(1, 3):upper() .. '(' .. (
- min_scope:sub(1, 1):upper() .. 'V_' .. varname:sub(3):upper()
- ) .. ')'
+ 'OPT_'
+ .. min_scope:sub(1, 3):upper()
+ .. '('
+ .. (min_scope:sub(1, 1):upper() .. 'V_' .. varname:sub(3):upper())
+ .. ')'
)
if #o.scope == 2 then
pv_name = 'OPT_BOTH(' .. pv_name .. ')'
end
- table.insert(defines, { 'PV_' .. varname:sub(3):upper() , pv_name})
+ table.insert(defines, { 'PV_' .. varname:sub(3):upper(), pv_name })
w(' .indir=' .. pv_name)
end
if o.cb then
@@ -185,11 +209,11 @@ local function dump_option(i, o)
if o.defaults.condition then
w(get_cond(o.defaults.condition))
end
- w(' .def_val=' .. get_defaults(o.defaults.if_true, o.full_name))
+ w(' .def_val' .. get_defaults(o.defaults.if_true, o.full_name))
if o.defaults.condition then
if o.defaults.if_false then
w('#else')
- w(' .def_val=' .. get_defaults(o.defaults.if_false, o.full_name))
+ w(' .def_val' .. get_defaults(o.defaults.if_false, o.full_name))
end
w('#endif')
end
@@ -213,11 +237,9 @@ static vimoption_T options[] = {]])
for i, o in ipairs(options.options) do
dump_option(i, o)
end
-w(' [' .. ('%u'):format(#options.options) .. ']={.fullname=NULL}')
w('};')
w('')
for _, v in ipairs(defines) do
w('#define ' .. v[1] .. ' ' .. v[2])
end
-opt_fd:close()
diff --git a/src/nvim/generators/gen_options_enum.lua b/src/nvim/generators/gen_options_enum.lua
new file mode 100644
index 0000000000..9a3953fcbc
--- /dev/null
+++ b/src/nvim/generators/gen_options_enum.lua
@@ -0,0 +1,129 @@
+-- Generates option index enum and map of option name to option index.
+-- Handles option full name, short name and aliases.
+-- Also generates BV_ and WV_ enum constants.
+
+local options_enum_file = arg[1]
+local options_map_file = arg[2]
+local options_enum_fd = assert(io.open(options_enum_file, 'w'))
+local options_map_fd = assert(io.open(options_map_file, 'w'))
+
+--- @param s string
+local function enum_w(s)
+ options_enum_fd:write(s .. '\n')
+end
+
+--- @param s string
+local function map_w(s)
+ options_map_fd:write(s .. '\n')
+end
+
+enum_w('// IWYU pragma: private, include "nvim/option_defs.h"')
+enum_w('')
+
+--- @param s string
+--- @return string
+local lowercase_to_titlecase = function(s)
+ return s:sub(1, 1):upper() .. s:sub(2)
+end
+
+--- @type vim.option_meta[]
+local options = require('options').options
+
+-- Generate BV_ enum constants.
+enum_w('/// "indir" values for buffer-local options.')
+enum_w('/// These need to be defined globally, so that the BV_COUNT can be used with')
+enum_w('/// b_p_script_stx[].')
+enum_w('enum {')
+
+local bv_val = 0
+
+for _, o in ipairs(options) do
+ assert(#o.scope == 1 or #o.scope == 2)
+ assert(#o.scope == 1 or o.scope[1] == 'global')
+ local min_scope = o.scope[#o.scope]
+ if min_scope == 'buffer' then
+ local varname = o.pv_name or o.varname or ('p_' .. (o.abbreviation or o.full_name))
+ local bv_name = 'BV_' .. varname:sub(3):upper()
+ enum_w((' %s = %u,'):format(bv_name, bv_val))
+ bv_val = bv_val + 1
+ end
+end
+
+enum_w((' BV_COUNT = %u, ///< must be the last one'):format(bv_val))
+enum_w('};')
+enum_w('')
+
+-- Generate WV_ enum constants.
+enum_w('/// "indir" values for window-local options.')
+enum_w('/// These need to be defined globally, so that the WV_COUNT can be used in the')
+enum_w('/// window structure.')
+enum_w('enum {')
+
+local wv_val = 0
+
+for _, o in ipairs(options) do
+ assert(#o.scope == 1 or #o.scope == 2)
+ assert(#o.scope == 1 or o.scope[1] == 'global')
+ local min_scope = o.scope[#o.scope]
+ if min_scope == 'window' then
+ local varname = o.pv_name or o.varname or ('p_' .. (o.abbreviation or o.full_name))
+ local wv_name = 'WV_' .. varname:sub(3):upper()
+ enum_w((' %s = %u,'):format(wv_name, wv_val))
+ wv_val = wv_val + 1
+ end
+end
+
+enum_w((' WV_COUNT = %u, ///< must be the last one'):format(wv_val))
+enum_w('};')
+enum_w('')
+
+--- @type { [string]: string }
+local option_index = {}
+
+-- Generate option index enum and populate the `option_index` dictionary.
+enum_w('typedef enum {')
+enum_w(' kOptInvalid = -1,')
+
+for i, o in ipairs(options) do
+ local enum_val_name = 'kOpt' .. lowercase_to_titlecase(o.full_name)
+ enum_w((' %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
+
+ if o.alias then
+ o.alias = type(o.alias) == 'string' and { o.alias } or o.alias
+
+ for _, v in ipairs(o.alias) do
+ option_index[v] = enum_val_name
+ end
+ end
+end
+
+enum_w(' // Option count, used when iterating through options')
+enum_w('#define kOptIndexCount ' .. tostring(#options))
+enum_w('} OptIndex;')
+enum_w('')
+
+options_enum_fd:close()
+
+--- 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)
+
+map_w('static const struct { const char *name; OptIndex opt_idx; } option_hash_elems[] = {')
+
+for _, name in ipairs(neworder) do
+ assert(option_index[name] ~= nil)
+ map_w((' { .name = "%s", .opt_idx = %s },'):format(name, option_index[name]))
+end
+
+map_w('};\n')
+map_w('static ' .. hashfun)
+
+options_map_fd:close()
diff --git a/src/nvim/generators/gen_unicode_tables.lua b/src/nvim/generators/gen_unicode_tables.lua
index 9ad99c8029..6cedb5db50 100644
--- a/src/nvim/generators/gen_unicode_tables.lua
+++ b/src/nvim/generators/gen_unicode_tables.lua
@@ -60,12 +60,10 @@ local fp_lines_to_lists = function(fp, n, has_comments)
if not line then
break
end
- if (not has_comments
- or (line:sub(1, 1) ~= '#' and not line:match('^%s*$'))) then
+ if not has_comments or (line:sub(1, 1) ~= '#' and not line:match('^%s*$')) then
local l = split_on_semicolons(line)
if #l ~= n then
- io.stderr:write(('Found %s items in line %u, expected %u\n'):format(
- #l, i, n))
+ io.stderr:write(('Found %s items in line %u, expected %u\n'):format(#l, i, n))
io.stderr:write('Line: ' .. line .. '\n')
return nil
end
@@ -93,15 +91,13 @@ end
local make_range = function(start, end_, step, add)
if step and add then
- return (' {0x%x, 0x%x, %d, %d},\n'):format(
- start, end_, step == 0 and -1 or step, add)
+ return (' {0x%x, 0x%x, %d, %d},\n'):format(start, end_, step == 0 and -1 or step, add)
else
return (' {0x%04x, 0x%04x},\n'):format(start, end_)
end
end
-local build_convert_table = function(ut_fp, props, cond_func, nl_index,
- table_name)
+local build_convert_table = function(ut_fp, props, cond_func, nl_index, table_name)
ut_fp:write('static const convertStruct ' .. table_name .. '[] = {\n')
local start = -1
local end_ = -1
@@ -137,8 +133,7 @@ local build_case_table = function(ut_fp, dataprops, table_name, index)
local cond_func = function(p)
return p[index] ~= ''
end
- return build_convert_table(ut_fp, dataprops, cond_func, index,
- 'to' .. table_name)
+ return build_convert_table(ut_fp, dataprops, cond_func, index, 'to' .. table_name)
end
local build_fold_table = function(ut_fp, foldprops)
@@ -154,7 +149,7 @@ local build_combining_table = function(ut_fp, dataprops)
local end_ = -1
for _, p in ipairs(dataprops) do
-- The 'Mc' property was removed, it does take up space.
- if (({Mn=true, Me=true})[p[3]]) then
+ if ({ Mn = true, Me = true })[p[3]] then
local n = tonumber(p[1], 16)
if start >= 0 and end_ + 1 == n then
-- Continue with the same range.
@@ -175,8 +170,7 @@ local build_combining_table = function(ut_fp, dataprops)
ut_fp:write('};\n')
end
-local build_width_table = function(ut_fp, dataprops, widthprops, widths,
- table_name)
+local build_width_table = function(ut_fp, dataprops, widthprops, widths, table_name)
ut_fp:write('static const struct interval ' .. table_name .. '[] = {\n')
local start = -1
local end_ = -1
@@ -208,13 +202,13 @@ local build_width_table = function(ut_fp, dataprops, widthprops, widths,
-- Only use the char when it’s not a composing char.
-- But use all chars from a range.
local dp = dataprops[dataidx]
- if (n_last > n) or (not (({Mn=true, Mc=true, Me=true})[dp[3]])) then
+ if (n_last > n) or not ({ Mn = true, Mc = true, Me = true })[dp[3]] then
if start >= 0 and end_ + 1 == n then -- luacheck: ignore 542
-- Continue with the same range.
else
if start >= 0 then
ut_fp:write(make_range(start, end_))
- table.insert(ret, {start, end_})
+ table.insert(ret, { start, end_ })
end
start = n
end
@@ -224,7 +218,7 @@ local build_width_table = function(ut_fp, dataprops, widthprops, widths,
end
if start >= 0 then
ut_fp:write(make_range(start, end_))
- table.insert(ret, {start, end_})
+ table.insert(ret, { start, end_ })
end
ut_fp:write('};\n')
return ret
@@ -316,10 +310,9 @@ local eaw_fp = io.open(eastasianwidth_fname, 'r')
local widthprops = parse_width_props(eaw_fp)
eaw_fp:close()
-local doublewidth = build_width_table(ut_fp, dataprops, widthprops,
- {W=true, F=true}, 'doublewidth')
-local ambiwidth = build_width_table(ut_fp, dataprops, widthprops,
- {A=true}, 'ambiguous')
+local doublewidth =
+ build_width_table(ut_fp, dataprops, widthprops, { W = true, F = true }, 'doublewidth')
+local ambiwidth = build_width_table(ut_fp, dataprops, widthprops, { A = true }, 'ambiguous')
local emoji_fp = io.open(emoji_fname, 'r')
local emojiprops = parse_emoji_props(emoji_fp)
diff --git a/src/nvim/generators/gen_vimvim.lua b/src/nvim/generators/gen_vimvim.lua
index 29355d3cda..fcdc5bddc2 100644
--- a/src/nvim/generators/gen_vimvim.lua
+++ b/src/nvim/generators/gen_vimvim.lua
@@ -41,12 +41,14 @@ 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')
+ 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 '
@@ -81,7 +83,7 @@ local vimopt_start = 'syn keyword vimOption contained '
w('\n\n' .. vimopt_start)
for _, opt_desc in ipairs(options.options) do
- if not opt_desc.varname or opt_desc.varname:sub(1, 7) ~= 'p_force' then
+ if not opt_desc.immutable then
if lld.line_length > 850 then
w('\n' .. vimopt_start)
end
@@ -89,7 +91,7 @@ for _, opt_desc in ipairs(options.options) do
if opt_desc.abbreviation then
w(' ' .. opt_desc.abbreviation)
end
- if opt_desc.type == 'bool' then
+ if opt_desc.type == 'boolean' then
w(' inv' .. opt_desc.full_name)
w(' no' .. opt_desc.full_name)
if opt_desc.abbreviation then
@@ -133,7 +135,7 @@ 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"))
+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
diff --git a/src/nvim/generators/hashy.lua b/src/nvim/generators/hashy.lua
index b10bafb9f9..711e695742 100644
--- a/src/nvim/generators/hashy.lua
+++ b/src/nvim/generators/hashy.lua
@@ -3,7 +3,6 @@
local M = {}
_G.d = M
-
local function setdefault(table, key)
local val = table[key]
if val == nil then
@@ -16,28 +15,30 @@ 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
+ 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
+ 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 bestpos, minsize, best_bucket = nil, #strs * 2, nil
+ for pos = 1, len do
local try_bucket = {}
- for _,str in ipairs(strs) do
+ 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
+ for _, pos_strs in pairs(try_bucket) do
maxsize = math.max(maxsize, #pos_strs)
end
if maxsize < minsize then
@@ -46,7 +47,7 @@ function M.build_pos_hash(strings)
best_bucket = try_bucket
end
end
- len_pos_buckets[len] = {bestpos, best_bucket}
+ len_pos_buckets[len] = { bestpos, best_bucket }
worst_buck_size = math.max(worst_buck_size, minsize)
end
end
@@ -55,73 +56,79 @@ end
function M.switcher(put, tab, maxlen, worst_buck_size)
local neworder = {}
- put " switch (len) {\n"
+ put ' switch (len) {\n'
local bucky = worst_buck_size > 1
- for len = 1,maxlen do
+ for len = 1, maxlen do
local vals = tab[len]
if vals then
- put(" case "..len..": ")
+ 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
+ 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.."': ")
- put("low = "..startidx.."; ")
- if bucky then put("high = "..endidx.."; ") end
- put "break;\n"
+ put(" case '" .. c .. "': ")
+ put('low = ' .. startidx .. '; ')
+ if bucky then
+ put('high = ' .. endidx .. '; ')
+ end
+ put 'break;\n'
end
- put " default: break;\n"
- put " }\n "
+ 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
+ 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"
+ put 'break;\n'
end
end
- put " default: break;\n"
- put " }\n"
+ 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 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")
+ put('int ' .. name .. '_hash(const char *str, size_t len)\n{\n')
if worst_buck_size > 1 then
- put(" int low = 0, high = 0;\n")
+ put(' int low = 0, high = 0;\n')
else
- put(" int low = -1;\n")
+ put(' int low = -1;\n')
end
local neworder = M.switcher(put, len_pos_buckets, maxlen, worst_buck_size)
if worst_buck_size > 1 then
- put ([[
+ put([[
for (int i = low; i < high; i++) {
- if (!memcmp(str, ]]..access("i")..[[, len)) {
+ if (!memcmp(str, ]] .. access('i') .. [[, len)) {
return i;
}
}
return -1;
]])
else
- put ([[
- if (low < 0 || memcmp(str, ]]..access("low")..[[, len)) {
+ put([[
+ if (low < 0 || memcmp(str, ]] .. access('low') .. [[, len)) {
return -1;
}
return low;
]])
end
- put "}\n\n"
+ put '}\n\n'
return neworder, table.concat(stats)
end
diff --git a/src/nvim/generators/nvim_version.lua.in b/src/nvim/generators/nvim_version.lua.in
new file mode 100644
index 0000000000..d0dbf77922
--- /dev/null
+++ b/src/nvim/generators/nvim_version.lua.in
@@ -0,0 +1,9 @@
+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
index 4b7fde2c39..e14671074c 100644
--- a/src/nvim/generators/preload.lua
+++ b/src/nvim/generators/preload.lua
@@ -1,10 +1,13 @@
local srcdir = table.remove(arg, 1)
local nlualib = table.remove(arg, 1)
-package.path = srcdir .. '/src/nvim/?.lua;' ..srcdir .. '/runtime/lua/?.lua;' .. package.path
-_G.vim = require'vim.shared'
+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])()