local mpack = vim.mpack assert(#arg == 7) local funcs_metadata_inputf = arg[1] -- exported functions metadata local ui_metadata_inputf = arg[2] -- ui events metadata local ui_options_inputf = arg[3] -- for ui options local git_version_inputf = arg[4] -- git version header local nvim_version_inputf = arg[5] -- nvim version local dump_bin_array_inputf = arg[6] local api_metadata_outputf = arg[7] local version = loadfile(nvim_version_inputf)() --[[@as {[1]: string, [2]: any}[] ]] local git_version = io.open(git_version_inputf):read '*a' local version_build = git_version:match('#define NVIM_VERSION_BUILD "([^"]+)"') or vim.NIL local text = assert(io.open(ui_options_inputf)):read '*a' local ui_options_text = assert(text:match('ui_ext_names%[][^{]+{([^}]+)}')) --[[@as string]] local ui_options = { 'rgb' } for x in ui_options_text:gmatch('"([a-z][a-z_]+)"') do table.insert(ui_options, x) end local pieces = {} --- @type string[] -- 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 pieces[#pieces + 1] = 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') table.insert(pieces, io.open(funcs_metadata_inputf, 'rb'):read('*all')) 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) --- @type fun(api_metadata: file*, name: string, packed: string) local dump_bin_array = loadfile(dump_bin_array_inputf)() -- 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')) dump_bin_array(api_metadata_output, 'packed_api_metadata', packed) api_metadata_output:close()