mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	docs(api): document types using LuaCATS types
- Render Lua types in api.txt. - Added `DictAs(name)` API type which acts the same as `Dict` (no parens) when generating the dispatchers, but acts the same as `Dict(name)` when generating docs. - Added `Tuple(...)` API type which is the treated the as `Array` for generating the dispatchers, but is used to document richer types. - Added `Enum(...)` API type to better document enums - Improve typing of some API functions. - Improve c_grammar to properly parse API types and replace string pattern logic in the parsers. - Removed all the hardcoded type overrides in gen_eval_files.lua
This commit is contained in:
		 Lewis Russell
					Lewis Russell
				
			
				
					committed by
					
						 Lewis Russell
						Lewis Russell
					
				
			
			
				
	
			
			
			 Lewis Russell
						Lewis Russell
					
				
			
						parent
						
							3eaa6c5a66
						
					
				
				
					commit
					76de3e2d07
				
			
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										20
									
								
								runtime/lua/vim/_meta/api.lua
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										20
									
								
								runtime/lua/vim/_meta/api.lua
									
									
									
										generated
									
									
									
								
							| @@ -27,7 +27,7 @@ function vim.api.nvim__buf_stats(buffer) end | |||||||
| --- @param index integer Completion candidate index | --- @param index integer Completion candidate index | ||||||
| --- @param opts vim.api.keyset.complete_set Optional parameters. | --- @param opts vim.api.keyset.complete_set Optional parameters. | ||||||
| --- - info: (string) info text. | --- - info: (string) info text. | ||||||
| --- @return table<string,any> # Dict containing these keys: | --- @return table<string,number> # Dict containing these keys: | ||||||
| --- - winid: (number) floating window id | --- - winid: (number) floating window id | ||||||
| --- - bufnr: (number) buffer id in floating window | --- - bufnr: (number) buffer id in floating window | ||||||
| function vim.api.nvim__complete_set(index, opts) end | function vim.api.nvim__complete_set(index, opts) end | ||||||
| @@ -37,7 +37,7 @@ function vim.api.nvim__get_lib_dir() end | |||||||
|  |  | ||||||
| --- Find files in runtime directories | --- Find files in runtime directories | ||||||
| --- | --- | ||||||
| --- @param pat any[] pattern of files to search for | --- @param pat string[] pattern of files to search for | ||||||
| --- @param all boolean whether to return all matches or only the first | --- @param all boolean whether to return all matches or only the first | ||||||
| --- @param opts vim.api.keyset.runtime is_lua: only search Lua subdirs | --- @param opts vim.api.keyset.runtime is_lua: only search Lua subdirs | ||||||
| --- @return string[] # list of absolute paths to the found files | --- @return string[] # list of absolute paths to the found files | ||||||
| @@ -348,7 +348,7 @@ function vim.api.nvim_buf_get_changedtick(buffer) end | |||||||
| --- | --- | ||||||
| --- @param buffer integer Buffer id, or 0 for current buffer | --- @param buffer integer Buffer id, or 0 for current buffer | ||||||
| --- @param opts vim.api.keyset.get_commands Optional parameters. Currently not used. | --- @param opts vim.api.keyset.get_commands Optional parameters. Currently not used. | ||||||
| --- @return table<string,any> # Map of maps describing commands. | --- @return vim.api.keyset.command_info # Map of maps describing commands. | ||||||
| function vim.api.nvim_buf_get_commands(buffer, opts) end | function vim.api.nvim_buf_get_commands(buffer, opts) end | ||||||
|  |  | ||||||
| --- Gets the position (0-indexed) of an `extmark`. | --- Gets the position (0-indexed) of an `extmark`. | ||||||
| @@ -359,7 +359,7 @@ function vim.api.nvim_buf_get_commands(buffer, opts) end | |||||||
| --- @param opts vim.api.keyset.get_extmark Optional parameters. Keys: | --- @param opts vim.api.keyset.get_extmark Optional parameters. Keys: | ||||||
| --- - details: Whether to include the details dict | --- - details: Whether to include the details dict | ||||||
| --- - hl_name: Whether to include highlight group name instead of id, true if omitted | --- - hl_name: Whether to include highlight group name instead of id, true if omitted | ||||||
| --- @return vim.api.keyset.get_extmark_item_by_id # 0-indexed (row, col) tuple or empty list () if extmark id was | --- @return [integer, integer, vim.api.keyset.extmark_details?] # 0-indexed (row, col) tuple or empty list () if extmark id was | ||||||
| --- absent | --- absent | ||||||
| function vim.api.nvim_buf_get_extmark_by_id(buffer, ns_id, id, opts) end | function vim.api.nvim_buf_get_extmark_by_id(buffer, ns_id, id, opts) end | ||||||
|  |  | ||||||
| @@ -1096,7 +1096,7 @@ function vim.api.nvim_del_var(name) end | |||||||
| --- vim.api.nvim_echo({ { 'chunk1-line1\nchunk1-line2\n' }, { 'chunk2-line1' } }, true, {}) | --- vim.api.nvim_echo({ { 'chunk1-line1\nchunk1-line2\n' }, { 'chunk2-line1' } }, true, {}) | ||||||
| --- ``` | --- ``` | ||||||
| --- | --- | ||||||
| --- @param chunks any[] List of `[text, hl_group]` pairs, where each is a `text` string highlighted by | --- @param chunks [string, integer|string][] List of `[text, hl_group]` pairs, where each is a `text` string highlighted by | ||||||
| --- the (optional) name or ID `hl_group`. | --- the (optional) name or ID `hl_group`. | ||||||
| --- @param history boolean if true, add to `message-history`. | --- @param history boolean if true, add to `message-history`. | ||||||
| --- @param opts vim.api.keyset.echo_opts Optional parameters. | --- @param opts vim.api.keyset.echo_opts Optional parameters. | ||||||
| @@ -1327,7 +1327,7 @@ function vim.api.nvim_get_color_map() end | |||||||
| --- @see vim.api.nvim_get_all_options_info | --- @see vim.api.nvim_get_all_options_info | ||||||
| --- @param opts vim.api.keyset.get_commands Optional parameters. Currently only supports | --- @param opts vim.api.keyset.get_commands Optional parameters. Currently only supports | ||||||
| --- {"builtin":false} | --- {"builtin":false} | ||||||
| --- @return table<string,any> # Map of maps describing commands. | --- @return table<string,vim.api.keyset.command_info> # Map of maps describing commands. | ||||||
| function vim.api.nvim_get_commands(opts) end | function vim.api.nvim_get_commands(opts) end | ||||||
|  |  | ||||||
| --- Gets a map of the current editor state. | --- Gets a map of the current editor state. | ||||||
| @@ -1427,7 +1427,7 @@ function vim.api.nvim_get_keymap(mode) end | |||||||
| --- @see vim.api.nvim_del_mark | --- @see vim.api.nvim_del_mark | ||||||
| --- @param name string Mark name | --- @param name string Mark name | ||||||
| --- @param opts vim.api.keyset.empty Optional parameters. Reserved for future use. | --- @param opts vim.api.keyset.empty Optional parameters. Reserved for future use. | ||||||
| --- @return vim.api.keyset.get_mark # 4-tuple (row, col, buffer, buffername), (0, 0, 0, '') if the mark is | --- @return [integer, integer, integer, string] # 4-tuple (row, col, buffer, buffername), (0, 0, 0, '') if the mark is | ||||||
| --- not set. | --- not set. | ||||||
| function vim.api.nvim_get_mark(name, opts) end | function vim.api.nvim_get_mark(name, opts) end | ||||||
|  |  | ||||||
| @@ -1599,7 +1599,7 @@ function vim.api.nvim_list_bufs() end | |||||||
|  |  | ||||||
| --- Get information about all open channels. | --- Get information about all open channels. | ||||||
| --- | --- | ||||||
| --- @return any[] # Array of Dictionaries, each describing a channel with | --- @return table<string,any>[] # Array of Dictionaries, each describing a channel with | ||||||
| --- the format specified at |nvim_get_chan_info()|. | --- the format specified at |nvim_get_chan_info()|. | ||||||
| function vim.api.nvim_list_chans() end | function vim.api.nvim_list_chans() end | ||||||
|  |  | ||||||
| @@ -1623,7 +1623,7 @@ function vim.api.nvim_list_tabpages() end | |||||||
| --- vim.print(vim.api.nvim_get_chan_info(vim.api.nvim_list_uis()[1].chan).client.name) | --- vim.print(vim.api.nvim_get_chan_info(vim.api.nvim_list_uis()[1].chan).client.name) | ||||||
| --- ``` | --- ``` | ||||||
| --- | --- | ||||||
| --- @return any[] # Array of UI dictionaries, each with these keys: | --- @return table<string,any>[] # Array of UI dictionaries, each with these keys: | ||||||
| --- - "height"  Requested height of the UI | --- - "height"  Requested height of the UI | ||||||
| --- - "width"   Requested width of the UI | --- - "width"   Requested width of the UI | ||||||
| --- - "rgb"     true if the UI uses RGB colors (false implies |cterm-colors|) | --- - "rgb"     true if the UI uses RGB colors (false implies |cterm-colors|) | ||||||
| @@ -1865,7 +1865,7 @@ function vim.api.nvim_out_write(str) end | |||||||
| --- | --- | ||||||
| --- @param str string Command line string to parse. Cannot contain "\n". | --- @param str string Command line string to parse. Cannot contain "\n". | ||||||
| --- @param opts vim.api.keyset.empty Optional parameters. Reserved for future use. | --- @param opts vim.api.keyset.empty Optional parameters. Reserved for future use. | ||||||
| --- @return vim.api.keyset.parse_cmd # Dict containing command information, with these keys: | --- @return vim.api.keyset.cmd # Dict containing command information, with these keys: | ||||||
| --- - cmd: (string) Command name. | --- - cmd: (string) Command name. | ||||||
| --- - range: (array) (optional) Command range ([<line1>] [<line2>]). | --- - range: (array) (optional) Command range ([<line1>] [<line2>]). | ||||||
| ---                  Omitted if command doesn't accept a range. | ---                  Omitted if command doesn't accept a range. | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								runtime/lua/vim/_meta/api_keysets.lua
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										26
									
								
								runtime/lua/vim/_meta/api_keysets.lua
									
									
									
										generated
									
									
									
								
							| @@ -24,15 +24,15 @@ error('Cannot require a meta file') | |||||||
|  |  | ||||||
| --- @class vim.api.keyset.cmd | --- @class vim.api.keyset.cmd | ||||||
| --- @field cmd? string | --- @field cmd? string | ||||||
| --- @field range? any[] | --- @field range? integer[] | ||||||
| --- @field count? integer | --- @field count? integer | ||||||
| --- @field reg? string | --- @field reg? string | ||||||
| --- @field bang? boolean | --- @field bang? boolean | ||||||
| --- @field args? string[] | --- @field args? string[] | ||||||
| --- @field magic? table<string,any> | --- @field magic? vim.api.keyset.cmd.magic | ||||||
| --- @field mods? table<string,any> | --- @field mods? vim.api.keyset.cmd.mods | ||||||
| --- @field nargs? integer|string | --- @field nargs? integer|"?"|"+"|"*" | ||||||
| --- @field addr? string | --- @field addr? "line"|"arg"|"buf"|"load"|"win"|"tab"|"qf"|"none"|"?" | ||||||
| --- @field nextcmd? string | --- @field nextcmd? string | ||||||
|  |  | ||||||
| --- @class vim.api.keyset.cmd_magic | --- @class vim.api.keyset.cmd_magic | ||||||
| @@ -79,7 +79,7 @@ error('Cannot require a meta file') | |||||||
|  |  | ||||||
| --- @class vim.api.keyset.create_autocmd | --- @class vim.api.keyset.create_autocmd | ||||||
| --- @field buffer? integer | --- @field buffer? integer | ||||||
| --- @field callback? string|(fun(args: vim.api.keyset.create_autocmd.callback_args): boolean?) | --- @field callback? string|fun(args: vim.api.keyset.create_autocmd.callback_args): boolean? | ||||||
| --- @field command? string | --- @field command? string | ||||||
| --- @field desc? string | --- @field desc? string | ||||||
| --- @field group? integer|string | --- @field group? integer|string | ||||||
| @@ -294,9 +294,9 @@ error('Cannot require a meta file') | |||||||
| --- @field col? number | --- @field col? number | ||||||
| --- @field width? integer | --- @field width? integer | ||||||
| --- @field height? integer | --- @field height? integer | ||||||
| --- @field anchor? 'NW'|'NE'|'SW'|'SE' | --- @field anchor? "NW"|"NE"|"SW"|"SE" | ||||||
| --- @field relative? 'cursor'|'editor'|'laststatus'|'mouse'|'tabline'|'win' | --- @field relative? "cursor"|"editor"|"laststatus"|"mouse"|"tabline"|"win" | ||||||
| --- @field split? 'left'|'right'|'above'|'below' | --- @field split? "left"|"right"|"above"|"below" | ||||||
| --- @field win? integer | --- @field win? integer | ||||||
| --- @field bufpos? integer[] | --- @field bufpos? integer[] | ||||||
| --- @field external? boolean | --- @field external? boolean | ||||||
| @@ -304,12 +304,12 @@ error('Cannot require a meta file') | |||||||
| --- @field mouse? boolean | --- @field mouse? boolean | ||||||
| --- @field vertical? boolean | --- @field vertical? boolean | ||||||
| --- @field zindex? integer | --- @field zindex? integer | ||||||
| --- @field border? 'none'|'single'|'double'|'rounded'|'solid'|'shadow'|string[] | --- @field border? string[]|"none"|"single"|"double"|"rounded"|"solid"|"shadow" | ||||||
| --- @field title? any | --- @field title? any | ||||||
| --- @field title_pos? 'center'|'left'|'right' | --- @field title_pos? "center"|"left"|"right" | ||||||
| --- @field footer? any | --- @field footer? any | ||||||
| --- @field footer_pos? 'center'|'left'|'right' | --- @field footer_pos? "center"|"left"|"right" | ||||||
| --- @field style? 'minimal' | --- @field style? "minimal" | ||||||
| --- @field noautocmd? boolean | --- @field noautocmd? boolean | ||||||
| --- @field fixed? boolean | --- @field fixed? boolean | ||||||
| --- @field hide? boolean | --- @field hide? boolean | ||||||
|   | |||||||
| @@ -54,12 +54,6 @@ error('Cannot require a meta file') | |||||||
| --- @field [3] integer col | --- @field [3] integer col | ||||||
| --- @field [4] vim.api.keyset.extmark_details? | --- @field [4] vim.api.keyset.extmark_details? | ||||||
|  |  | ||||||
| --- @class vim.api.keyset.get_mark |  | ||||||
| --- @field [1] integer row |  | ||||||
| --- @field [2] integer col |  | ||||||
| --- @field [3] integer buffer |  | ||||||
| --- @field [4] string buffername |  | ||||||
|  |  | ||||||
| --- @class vim.api.keyset.get_autocmds.ret | --- @class vim.api.keyset.get_autocmds.ret | ||||||
| --- @field id? integer | --- @field id? integer | ||||||
| --- @field group? integer | --- @field group? integer | ||||||
| @@ -212,7 +206,7 @@ error('Cannot require a meta file') | |||||||
| --- @field default string|boolean|integer | --- @field default string|boolean|integer | ||||||
| --- @field allows_duplicates boolean | --- @field allows_duplicates boolean | ||||||
|  |  | ||||||
| --- @class vim.api.keyset.parse_cmd.mods | --- @class vim.api.keyset.cmd.mods | ||||||
| --- @field filter { force: boolean, pattern: string } | --- @field filter { force: boolean, pattern: string } | ||||||
| --- @field silent boolean | --- @field silent boolean | ||||||
| --- @field emsg_silent boolean | --- @field emsg_silent boolean | ||||||
| @@ -234,18 +228,9 @@ error('Cannot require a meta file') | |||||||
| --- @field horizontal boolean | --- @field horizontal boolean | ||||||
| --- @field split ''|'botright'|'topleft'|'belowright'|'aboveleft' | --- @field split ''|'botright'|'topleft'|'belowright'|'aboveleft' | ||||||
|  |  | ||||||
| --- @class vim.api.keyset.parse_cmd | --- @class vim.api.keyset.cmd.magic | ||||||
| --- @field addr 'line'|'arg'|'buf'|'load'|'win'|'tab'|'qf'|'none'|'?' | --- @field bar boolean | ||||||
| --- @field args string[] | --- @field file boolean | ||||||
| --- @field bang boolean |  | ||||||
| --- @field cmd string |  | ||||||
| --- @field magic {bar: boolean, file: boolean} |  | ||||||
| --- @field mods vim.api.keyset.parse_cmd.mods |  | ||||||
| --- @field nargs '0'|'1'|'?'|'+'|'*' |  | ||||||
| --- @field nextcmd string |  | ||||||
| --- @field range? integer[] |  | ||||||
| --- @field count? integer |  | ||||||
| --- @field reg? string |  | ||||||
|  |  | ||||||
| --- @class vim.api.keyset.eval_statusline_ret.highlight | --- @class vim.api.keyset.eval_statusline_ret.highlight | ||||||
| --- @field start integer | --- @field start integer | ||||||
|   | |||||||
							
								
								
									
										74
									
								
								src/gen/api_types.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/gen/api_types.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | |||||||
|  | local API_TYPES = { | ||||||
|  |   Window = 'integer', | ||||||
|  |   Tabpage = 'integer', | ||||||
|  |   Buffer = 'integer', | ||||||
|  |   Boolean = 'boolean', | ||||||
|  |   Object = 'any', | ||||||
|  |   Integer = 'integer', | ||||||
|  |   String = 'string', | ||||||
|  |   Array = 'any[]', | ||||||
|  |   LuaRef = 'function', | ||||||
|  |   Dict = 'table<string,any>', | ||||||
|  |   Float = 'number', | ||||||
|  |   HLGroupID = 'integer|string', | ||||||
|  |   void = 'nil', | ||||||
|  | } | ||||||
|  |  | ||||||
|  | local typed_container = require('gen.c_grammar').typed_container | ||||||
|  |  | ||||||
|  | --- Convert an API type to Lua | ||||||
|  | --- @param t string | ||||||
|  | --- @return string | ||||||
|  | local function api_type(t) | ||||||
|  |   if vim.startswith(t, '*') then | ||||||
|  |     return api_type(t:sub(2)) .. '?' | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   --- @type nvim.c_grammar.Container? | ||||||
|  |   local t0 = typed_container:match(t) | ||||||
|  |  | ||||||
|  |   if t0 then | ||||||
|  |     local container = t0[1] | ||||||
|  |  | ||||||
|  |     if container == 'ArrayOf' then | ||||||
|  |       --- @cast t0 nvim.c_grammar.Container.ArrayOf | ||||||
|  |       local ty = api_type(t0[2]) | ||||||
|  |       local count = tonumber(t0[3]) | ||||||
|  |       if count then | ||||||
|  |         return ('[%s]'):format(ty:rep(count, ', ')) | ||||||
|  |       else | ||||||
|  |         return ty .. '[]' | ||||||
|  |       end | ||||||
|  |     elseif container == 'Dict' or container == 'DictAs' then | ||||||
|  |       --- @cast t0 nvim.c_grammar.Container.Dict | ||||||
|  |       return 'vim.api.keyset.' .. t0[2]:gsub('__', '.') | ||||||
|  |     elseif container == 'DictOf' then | ||||||
|  |       --- @cast t0 nvim.c_grammar.Container.DictOf | ||||||
|  |       local ty = api_type(t0[2]) | ||||||
|  |       return ('table<string,%s>'):format(ty) | ||||||
|  |     elseif container == 'Tuple' then | ||||||
|  |       --- @cast t0 nvim.c_grammar.Container.Tuple | ||||||
|  |       return ('[%s]'):format(table.concat(vim.tbl_map(api_type, t0[2]), ', ')) | ||||||
|  |     elseif container == 'Enum' or container == 'Union' then | ||||||
|  |       --- @cast t0 nvim.c_grammar.Container.Enum|nvim.c_grammar.Container.Union | ||||||
|  |       return table.concat(vim.tbl_map(api_type, t0[2]), '|') | ||||||
|  |     elseif container == 'LuaRefOf' then | ||||||
|  |       --- @cast t0 nvim.c_grammar.Container.LuaRefOf | ||||||
|  |       local _, as, r = unpack(t0) | ||||||
|  |  | ||||||
|  |       local as1 = {} --- @type string[] | ||||||
|  |       for _, a in ipairs(as) do | ||||||
|  |         local ty, nm = unpack(a) | ||||||
|  |         nm = nm:gsub('%*(.*)$', '%1?') | ||||||
|  |         as1[#as1 + 1] = ('%s: %s'):format(nm, api_type(ty)) | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       return ('fun(%s)%s'):format(table.concat(as1, ', '), r and ': ' .. api_type(r) or '') | ||||||
|  |     end | ||||||
|  |     error('Unknown container type: ' .. container) | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   return API_TYPES[t] or t | ||||||
|  | end | ||||||
|  |  | ||||||
|  | return api_type | ||||||
| @@ -2,21 +2,51 @@ | |||||||
| -- ignores comments and preprocessor commands and parses a very small subset | -- ignores comments and preprocessor commands and parses a very small subset | ||||||
| -- of C prototypes with a limited set of types | -- of C prototypes with a limited set of types | ||||||
|  |  | ||||||
|  | ---@diagnostic disable: missing-fields | ||||||
|  |  | ||||||
| --- @class nvim.c_grammar.Proto | --- @class nvim.c_grammar.Proto | ||||||
| --- @field [1] 'proto' | --- @field [1] 'proto' | ||||||
| --- @field pos integer | --- @field pos integer | ||||||
| --- @field endpos integer | --- @field endpos integer | ||||||
| --- @field fast boolean |  | ||||||
| --- @field name string | --- @field name string | ||||||
| --- @field return_type string | --- @field return_type string | ||||||
| --- @field parameters [string, string][] | --- @field parameters [string, string][] | ||||||
|  | --- | ||||||
|  | --- Decl modifiers | ||||||
|  | --- | ||||||
| --- @field static true? | --- @field static true? | ||||||
| --- @field inline true? | --- @field inline true? | ||||||
|  | --- | ||||||
|  | --- Attributes | ||||||
|  | --- | ||||||
|  | --- @field since integer? | ||||||
|  | --- @field deprecated_since integer? | ||||||
|  | --- @field fast true? | ||||||
|  | --- @field ret_alloc true? | ||||||
|  | --- @field noexport true? | ||||||
|  | --- @field remote_only true? | ||||||
|  | --- @field lua_only true? | ||||||
|  | --- @field textlock_allow_cmdwin true? | ||||||
|  | --- @field textlock true? | ||||||
|  | --- @field remote_impl true? | ||||||
|  | --- @field compositor_impl true? | ||||||
|  | --- @field client_impl true? | ||||||
|  | --- @field client_ignore true? | ||||||
|  |  | ||||||
| --- @class nvim.c_grammar.Preproc | --- @class nvim.c_grammar.Preproc | ||||||
| --- @field [1] 'preproc' | --- @field [1] 'preproc' | ||||||
| --- @field content string | --- @field content string | ||||||
|  |  | ||||||
|  | --- @class nvim.c_grammar.Keyset.Field | ||||||
|  | --- @field type string | ||||||
|  | --- @field name string | ||||||
|  | --- @field dict_key? string | ||||||
|  |  | ||||||
|  | --- @class nvim.c_grammar.Keyset | ||||||
|  | --- @field [1] 'typedef' | ||||||
|  | --- @field keyset_name string | ||||||
|  | --- @field fields nvim.c_grammar.Keyset.Field[] | ||||||
|  |  | ||||||
| --- @class nvim.c_grammar.Empty | --- @class nvim.c_grammar.Empty | ||||||
| --- @field [1] 'empty' | --- @field [1] 'empty' | ||||||
|  |  | ||||||
| @@ -24,6 +54,7 @@ | |||||||
| --- | nvim.c_grammar.Proto | --- | nvim.c_grammar.Proto | ||||||
| --- | nvim.c_grammar.Preproc | --- | nvim.c_grammar.Preproc | ||||||
| --- | nvim.c_grammar.Empty | --- | nvim.c_grammar.Empty | ||||||
|  | --- | nvim.c_grammar.Keyset | ||||||
|  |  | ||||||
| --- @class nvim.c_grammar | --- @class nvim.c_grammar | ||||||
| --- @field match fun(self, input: string): nvim.c_grammar.result[] | --- @field match fun(self, input: string): nvim.c_grammar.result[] | ||||||
| @@ -95,19 +126,44 @@ local braces = P({ | |||||||
|   S = P('{') * rep(V('A')) * rep(V('S') + V('A')) * P('}'), |   S = P('{') * rep(V('A')) * rep(V('S') + V('A')) * P('}'), | ||||||
| }) | }) | ||||||
|  |  | ||||||
|  | --- @alias nvim.c_grammar.Container.Union ['Union', string[]] | ||||||
|  | --- @alias nvim.c_grammar.Container.Tuple ['Tuple', string[]] | ||||||
|  | --- @alias nvim.c_grammar.Container.Enum ['Enum', string[]] | ||||||
|  | --- @alias nvim.c_grammar.Container.ArrayOf ['ArrayOf', string, integer?] | ||||||
|  | --- @alias nvim.c_grammar.Container.DictOf ['DictOf', string] | ||||||
|  | --- @alias nvim.c_grammar.Container.LuaRefOf ['LuaRefOf', [string, string][], string] | ||||||
|  | --- @alias nvim.c_grammar.Container.Dict ['Dict', string] | ||||||
|  | --- @alias nvim.c_grammar.Container.DictAs ['DictAs', string] | ||||||
|  |  | ||||||
|  | --- @alias nvim.c_grammar.Container | ||||||
|  | --- | nvim.c_grammar.Container.Union | ||||||
|  | --- | nvim.c_grammar.Container.Tuple | ||||||
|  | --- | nvim.c_grammar.Container.Enum | ||||||
|  | --- | nvim.c_grammar.Container.ArrayOf | ||||||
|  | --- | nvim.c_grammar.Container.DictOf | ||||||
|  | --- | nvim.c_grammar.Container.LuaRefOf | ||||||
|  | --- | nvim.c_grammar.Container.Dict | ||||||
|  |  | ||||||
| -- stylua: ignore start | -- stylua: ignore start | ||||||
| local typed_container = P({ | local typed_container = P({ | ||||||
|   'S', |   'S', | ||||||
|   S = ( |   S = Ct( | ||||||
|     (P('Union') * paren(comma1(V('ID')))) |     Cg(opt(P('*')) * P('Union')) * paren(Ct(comma1(V('TY')))) | ||||||
|     + (P('ArrayOf') * paren(id * opt(P(',') * fill * rep1(num)))) |     + Cg(opt(P('*')) * P('Enum')) * paren(Ct(comma1(Cg(str)))) | ||||||
|     + (P('DictOf') * paren(id)) |     + Cg(opt(P('*')) * P('Tuple')) * paren(Ct(comma1(V('TY')))) | ||||||
|     + (P('LuaRefOf') * paren( |     + Cg(opt(P('*')) * P('ArrayOf')) * paren(V('TY') * opt(P(',') * fill * C(rep1(num)))) | ||||||
|       paren(comma1((V('ID') + str) * rep1(ws) * opt(P('*')) * id)) |     + Cg(opt(P('*')) * P('DictOf')) * paren(V('TY')) | ||||||
|       * opt(P(',') * fill * opt(P('*')) * V('ID')) |     + Cg(opt(P('*')) * P('LuaRefOf')) | ||||||
|     )) |       * paren( | ||||||
|     + (P('Dict') * paren(id))), |           Ct(paren(comma1(Ct((V('TY') + C(str)) * rep1(ws) * Cg(V('ID')))))) | ||||||
|   ID = V('S') + id, |           * opt(P(',') * fill * V('TY')) | ||||||
|  |         ) | ||||||
|  |     + Cg(opt(P('*')) * P('Dict')) * paren(C(id)) | ||||||
|  |     + Cg(opt(P('*')) * P('DictAs')) * paren(C(id)) | ||||||
|  |   ), | ||||||
|  |   -- Remove captures here (with / 0 ) as api_types will recursively run parse the type. | ||||||
|  |   TY = Cg(V('S') / 0 + V('ID')), | ||||||
|  |   ID = opt(P('*')) * id, | ||||||
| }) | }) | ||||||
| -- stylua: ignore end | -- stylua: ignore end | ||||||
|  |  | ||||||
| @@ -156,7 +212,7 @@ local api_param_type = ( | |||||||
| local ctype = C( | local ctype = C( | ||||||
|   opt(word('const')) |   opt(word('const')) | ||||||
|     * ( |     * ( | ||||||
|       typed_container |       typed_container / 0 | ||||||
|       -- 'unsigned' is a type modifier, and a type itself |       -- 'unsigned' is a type modifier, and a type itself | ||||||
|       + (word('unsigned char') + word('unsigned')) |       + (word('unsigned char') + word('unsigned')) | ||||||
|       + (word('struct') * fill * id) |       + (word('struct') * fill * id) | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| local cdoc_grammar = require('gen.cdoc_grammar') | local cdoc_grammar = require('gen.cdoc_grammar') | ||||||
| local c_grammar = require('gen.c_grammar') | local c_grammar = require('gen.c_grammar') | ||||||
|  | local api_type = require('gen.api_types') | ||||||
|  |  | ||||||
| --- @class nvim.cdoc.parser.param | --- @class nvim.cdoc.parser.param | ||||||
| --- @field name string | --- @field name string | ||||||
| @@ -140,7 +141,7 @@ local function process_proto(item, state) | |||||||
|   cur_obj.params = cur_obj.params or {} |   cur_obj.params = cur_obj.params or {} | ||||||
|  |  | ||||||
|   for _, p in ipairs(item.parameters) do |   for _, p in ipairs(item.parameters) do | ||||||
|     local param = { name = p[2], type = p[1] } |     local param = { name = p[2], type = api_type(p[1]) } | ||||||
|     local added = false |     local added = false | ||||||
|     for _, cp in ipairs(cur_obj.params) do |     for _, cp in ipairs(cur_obj.params) do | ||||||
|       if cp.name == param.name then |       if cp.name == param.name then | ||||||
| @@ -156,7 +157,7 @@ local function process_proto(item, state) | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   cur_obj.returns = cur_obj.returns or { {} } |   cur_obj.returns = cur_obj.returns or { {} } | ||||||
|   cur_obj.returns[1].type = item.return_type |   cur_obj.returns[1].type = api_type(item.return_type) | ||||||
|  |  | ||||||
|   for _, a in ipairs({ |   for _, a in ipairs({ | ||||||
|     'fast', |     'fast', | ||||||
|   | |||||||
| @@ -7,9 +7,8 @@ | |||||||
| --    cd src/nvim | --    cd src/nvim | ||||||
| --    nvim -l generators/gen_api_dispatch.lua "../../build/src/nvim/auto/api/private/dispatch_wrappers.generated.h" "../../build/src/nvim/auto/api/private/api_metadata.generated.h" "../../build/funcs_metadata.mpack" "../../build/src/nvim/auto/lua_api_c_bindings.generated.h" "../../build/src/nvim/auto/keysets_defs.generated.h" "../../build/ui_metadata.mpack" "../../build/cmake.config/auto/versiondef_git.h" "./api/autocmd.h" "./api/buffer.h" "./api/command.h" "./api/deprecated.h" "./api/extmark.h" "./api/keysets_defs.h" "./api/options.h" "./api/tabpage.h" "./api/ui.h" "./api/vim.h" "./api/vimscript.h" "./api/win_config.h" "./api/window.h" "../../build/include/api/autocmd.h.generated.h" "../../build/include/api/buffer.h.generated.h" "../../build/include/api/command.h.generated.h" "../../build/include/api/deprecated.h.generated.h" "../../build/include/api/extmark.h.generated.h" "../../build/include/api/options.h.generated.h" "../../build/include/api/tabpage.h.generated.h" "../../build/include/api/ui.h.generated.h" "../../build/include/api/vim.h.generated.h" "../../build/include/api/vimscript.h.generated.h" "../../build/include/api/win_config.h.generated.h" "../../build/include/api/window.h.generated.h" | --    nvim -l generators/gen_api_dispatch.lua "../../build/src/nvim/auto/api/private/dispatch_wrappers.generated.h" "../../build/src/nvim/auto/api/private/api_metadata.generated.h" "../../build/funcs_metadata.mpack" "../../build/src/nvim/auto/lua_api_c_bindings.generated.h" "../../build/src/nvim/auto/keysets_defs.generated.h" "../../build/ui_metadata.mpack" "../../build/cmake.config/auto/versiondef_git.h" "./api/autocmd.h" "./api/buffer.h" "./api/command.h" "./api/deprecated.h" "./api/extmark.h" "./api/keysets_defs.h" "./api/options.h" "./api/tabpage.h" "./api/ui.h" "./api/vim.h" "./api/vimscript.h" "./api/win_config.h" "./api/window.h" "../../build/include/api/autocmd.h.generated.h" "../../build/include/api/buffer.h.generated.h" "../../build/include/api/command.h.generated.h" "../../build/include/api/deprecated.h.generated.h" "../../build/include/api/extmark.h.generated.h" "../../build/include/api/options.h.generated.h" "../../build/include/api/tabpage.h.generated.h" "../../build/include/api/ui.h.generated.h" "../../build/include/api/vim.h.generated.h" "../../build/include/api/vimscript.h.generated.h" "../../build/include/api/win_config.h.generated.h" "../../build/include/api/window.h.generated.h" | ||||||
|  |  | ||||||
| local mpack = vim.mpack |  | ||||||
|  |  | ||||||
| local hashy = require 'gen.hashy' | local hashy = require 'gen.hashy' | ||||||
|  | local c_grammar = require('gen.c_grammar') | ||||||
|  |  | ||||||
| -- output h file with generated dispatch functions (dispatch_wrappers.generated.h) | -- output h file with generated dispatch functions (dispatch_wrappers.generated.h) | ||||||
| local dispatch_outputf = arg[1] | local dispatch_outputf = arg[1] | ||||||
| @@ -27,19 +26,59 @@ local dispatch_deprecated_inputf = arg[10] | |||||||
| local pre_args = 10 | local pre_args = 10 | ||||||
| assert(#arg >= pre_args) | assert(#arg >= pre_args) | ||||||
|  |  | ||||||
|  | local function real_type(type, exported) | ||||||
|  |   local ptype = c_grammar.typed_container:match(type) | ||||||
|  |   if ptype then | ||||||
|  |     local container = ptype[1] | ||||||
|  |     if container == 'Union' then | ||||||
|  |       return 'Object' | ||||||
|  |     elseif container == 'Tuple' or container == 'ArrayOf' then | ||||||
|  |       return 'Array' | ||||||
|  |     elseif container == 'DictOf' or container == 'DictAs' then | ||||||
|  |       return 'Dict' | ||||||
|  |     elseif container == 'LuaRefOf' then | ||||||
|  |       return 'LuaRef' | ||||||
|  |     elseif container == 'Enum' then | ||||||
|  |       return 'String' | ||||||
|  |     elseif container == 'Dict' then | ||||||
|  |       if exported then | ||||||
|  |         return 'Dict' | ||||||
|  |       end | ||||||
|  |       -- internal type, used for keysets | ||||||
|  |       return 'KeyDict_' .. ptype[2] | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  |   return type | ||||||
|  | end | ||||||
|  |  | ||||||
|  | --- @class gen_api_dispatch.Function : nvim.c_grammar.Proto | ||||||
|  | --- @field method boolean | ||||||
|  | --- @field receives_array_args? true | ||||||
|  | --- @field receives_channel_id? true | ||||||
|  | --- @field can_fail? true | ||||||
|  | --- @field has_lua_imp? true | ||||||
|  | --- @field receives_arena? true | ||||||
|  | --- @field impl_name? string | ||||||
|  | --- @field remote? boolean | ||||||
|  | --- @field lua? boolean | ||||||
|  | --- @field eval? boolean | ||||||
|  | --- @field handler_id? integer | ||||||
|  |  | ||||||
|  | --- @type gen_api_dispatch.Function[] | ||||||
| local functions = {} | local functions = {} | ||||||
|  |  | ||||||
| -- names of all headers relative to the source root (for inclusion in the | --- Names of all headers relative to the source root (for inclusion in the | ||||||
| -- generated file) | --- generated file) | ||||||
|  | --- @type string[] | ||||||
| local headers = {} | local headers = {} | ||||||
|  |  | ||||||
| -- set of function names, used to detect duplicates | --- Set of function names, used to detect duplicates | ||||||
|  | --- @type table<string, true> | ||||||
| local function_names = {} | local function_names = {} | ||||||
|  |  | ||||||
| local c_grammar = require('gen.c_grammar') |  | ||||||
|  |  | ||||||
| local startswith = vim.startswith | local startswith = vim.startswith | ||||||
|  |  | ||||||
|  | --- @param fn gen_api_dispatch.Function | ||||||
| local function add_function(fn) | 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 |   if public and not fn.noexport then | ||||||
| @@ -79,12 +118,21 @@ local function add_function(fn) | |||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
|  | --- @class gen_api_dispatch.Keyset | ||||||
|  | --- @field name string | ||||||
|  | --- @field keys string[] | ||||||
|  | --- @field c_names table<string, string> | ||||||
|  | --- @field types table<string, string> | ||||||
|  | --- @field has_optional boolean | ||||||
|  |  | ||||||
|  | --- @type gen_api_dispatch.Keyset[] | ||||||
| local keysets = {} | local keysets = {} | ||||||
|  |  | ||||||
|  | --- @param val nvim.c_grammar.Keyset | ||||||
| local function add_keyset(val) | local function add_keyset(val) | ||||||
|   local keys = {} |   local keys = {} --- @type string[] | ||||||
|   local types = {} |   local types = {} --- @type table<string, string> | ||||||
|   local c_names = {} |   local c_names = {} --- @type table<string, string> | ||||||
|   local is_set_name = 'is_set__' .. val.keyset_name .. '_' |   local is_set_name = 'is_set__' .. val.keyset_name .. '_' | ||||||
|   local has_optional = false |   local has_optional = false | ||||||
|   for i, field in ipairs(val.fields) do |   for i, field in ipairs(val.fields) do | ||||||
| @@ -108,13 +156,13 @@ local function add_keyset(val) | |||||||
|       has_optional = true |       has_optional = true | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|   table.insert(keysets, { |   keysets[#keysets + 1] = { | ||||||
|     name = val.keyset_name, |     name = val.keyset_name, | ||||||
|     keys = keys, |     keys = keys, | ||||||
|     c_names = c_names, |     c_names = c_names, | ||||||
|     types = types, |     types = types, | ||||||
|     has_optional = has_optional, |     has_optional = has_optional, | ||||||
|   }) |   } | ||||||
| end | end | ||||||
|  |  | ||||||
| local ui_options_text = nil | local ui_options_text = nil | ||||||
| @@ -122,29 +170,35 @@ local ui_options_text = nil | |||||||
| -- read each input file, parse and append to the api metadata | -- read each input file, parse and append to the api metadata | ||||||
| for i = pre_args + 1, #arg do | for i = pre_args + 1, #arg do | ||||||
|   local full_path = arg[i] |   local full_path = arg[i] | ||||||
|   local parts = {} |   local parts = {} --- @type string[] | ||||||
|   for part in string.gmatch(full_path, '[^/]+') do |   for part in full_path:gmatch('[^/]+') do | ||||||
|     parts[#parts + 1] = part |     parts[#parts + 1] = part | ||||||
|   end |   end | ||||||
|   headers[#headers + 1] = parts[#parts - 1] .. '/' .. parts[#parts] |   headers[#headers + 1] = parts[#parts - 1] .. '/' .. parts[#parts] | ||||||
|  |  | ||||||
|   local input = assert(io.open(full_path, 'rb')) |   local input = assert(io.open(full_path, 'rb')) | ||||||
|  |  | ||||||
|  |   --- @type string | ||||||
|   local text = input:read('*all') |   local text = input:read('*all') | ||||||
|   local tmp = c_grammar.grammar:match(text) |   for _, val in ipairs(c_grammar.grammar:match(text)) do | ||||||
|   for j = 1, #tmp do |  | ||||||
|     local val = tmp[j] |  | ||||||
|     if val.keyset_name then |     if val.keyset_name then | ||||||
|  |       --- @cast val nvim.c_grammar.Keyset | ||||||
|       add_keyset(val) |       add_keyset(val) | ||||||
|     elseif val.name then |     elseif val.name then | ||||||
|  |       --- @cast val gen_api_dispatch.Function | ||||||
|       add_function(val) |       add_function(val) | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   ui_options_text = ui_options_text or string.match(text, 'ui_ext_names%[][^{]+{([^}]+)}') |   ui_options_text = ui_options_text or text:match('ui_ext_names%[][^{]+{([^}]+)}') | ||||||
|   input:close() |   input:close() | ||||||
| end | end | ||||||
|  |  | ||||||
|  | --- @cast ui_options_text string | ||||||
|  |  | ||||||
|  | --- @generic T: table | ||||||
|  | --- @param orig T | ||||||
|  | --- @return T | ||||||
| local function shallowcopy(orig) | local function shallowcopy(orig) | ||||||
|   local copy = {} |   local copy = {} | ||||||
|   for orig_key, orig_value in pairs(orig) do |   for orig_key, orig_value in pairs(orig) do | ||||||
| @@ -153,9 +207,11 @@ local function shallowcopy(orig) | |||||||
|   return copy |   return copy | ||||||
| end | end | ||||||
|  |  | ||||||
| -- Export functions under older deprecated names. | --- Export functions under older deprecated names. | ||||||
| -- These will be removed eventually. | --- These will be removed eventually. | ||||||
|  | --- @type table<string, string> | ||||||
| local deprecated_aliases = loadfile(dispatch_deprecated_inputf)() | local deprecated_aliases = loadfile(dispatch_deprecated_inputf)() | ||||||
|  |  | ||||||
| for _, f in ipairs(shallowcopy(functions)) do | for _, f in ipairs(shallowcopy(functions)) do | ||||||
|   local ismethod = false |   local ismethod = false | ||||||
|   if startswith(f.name, 'nvim_') then |   if startswith(f.name, 'nvim_') then | ||||||
| @@ -217,44 +273,47 @@ for _, f in ipairs(shallowcopy(functions)) do | |||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
| -- don't expose internal attributes like "impl_name" in public metadata | --- don't expose internal attributes like "impl_name" in public metadata | ||||||
| local exported_attributes = { 'name', 'return_type', 'method', 'since', 'deprecated_since' } | --- @class gen_api_dispatch.Function.Exported | ||||||
|  | --- @field name string | ||||||
|  | --- @field parameters [string, string][] | ||||||
|  | --- @field return_type string | ||||||
|  | --- @field method boolean | ||||||
|  | --- @field since integer | ||||||
|  | --- @field deprecated_since integer | ||||||
|  |  | ||||||
|  | --- @type gen_api_dispatch.Function.Exported[] | ||||||
| local exported_functions = {} | local exported_functions = {} | ||||||
|  |  | ||||||
| for _, f in ipairs(functions) do | for _, f in ipairs(functions) do | ||||||
|   if not (startswith(f.name, 'nvim__') or f.name == 'nvim_error_event' or f.name == 'redraw') then |   if not (startswith(f.name, 'nvim__') or f.name == 'nvim_error_event' or f.name == 'redraw') then | ||||||
|     local f_exported = {} |     --- @type gen_api_dispatch.Function.Exported | ||||||
|     for _, attr in ipairs(exported_attributes) do |     local f_exported = { | ||||||
|       f_exported[attr] = f[attr] |       name = f.name, | ||||||
|     end |       method = f.method, | ||||||
|     f_exported.parameters = {} |       since = f.since, | ||||||
|  |       deprecated_since = f.deprecated_since, | ||||||
|  |       parameters = {}, | ||||||
|  |       return_type = real_type(f.return_type, true), | ||||||
|  |     } | ||||||
|     for i, param in ipairs(f.parameters) do |     for i, param in ipairs(f.parameters) do | ||||||
|       if param[1] == 'DictOf(LuaRef)' then |       f_exported.parameters[i] = { real_type(param[1], true), param[2] } | ||||||
|         param = { 'Dict', param[2] } |  | ||||||
|       elseif startswith(param[1], 'Dict(') then |  | ||||||
|         param = { 'Dict', param[2] } |  | ||||||
|       end |  | ||||||
|       f_exported.parameters[i] = param |  | ||||||
|     end |  | ||||||
|     if startswith(f.return_type, 'Dict(') then |  | ||||||
|       f_exported.return_type = 'Dict' |  | ||||||
|     end |     end | ||||||
|     exported_functions[#exported_functions + 1] = f_exported |     exported_functions[#exported_functions + 1] = f_exported | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
| local ui_options = { 'rgb' } | local ui_options = { 'rgb' } | ||||||
| for x in string.gmatch(ui_options_text, '"([a-z][a-z_]+)"') do | for x in ui_options_text:gmatch('"([a-z][a-z_]+)"') do | ||||||
|   table.insert(ui_options, x) |   table.insert(ui_options, x) | ||||||
| end | end | ||||||
|  |  | ||||||
|  | --- @type integer[] | ||||||
| local version = loadfile(nvim_version_inputf)() | local version = loadfile(nvim_version_inputf)() | ||||||
| local git_version = io.open(git_version_inputf):read '*a' | local git_version = io.open(git_version_inputf):read '*a' | ||||||
| local version_build = string.match(git_version, '#define NVIM_VERSION_BUILD "([^"]+)"') or vim.NIL | local version_build = git_version:match('#define NVIM_VERSION_BUILD "([^"]+)"') or vim.NIL | ||||||
|  |  | ||||||
| -- serialize the API metadata using msgpack and embed into the resulting | local pieces = {} --- @type string[] | ||||||
| -- binary for easy querying by clients |  | ||||||
| local api_metadata_output = assert(io.open(api_metadata_outputf, 'wb')) |  | ||||||
| local pieces = {} |  | ||||||
|  |  | ||||||
| -- Naively using mpack.encode({foo=x, bar=y}) will make the build | -- 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 | -- "non-reproducible". Emit maps directly as FIXDICT(2) "foo" x "bar" y instead | ||||||
| @@ -262,12 +321,13 @@ local function fixdict(num) | |||||||
|   if num > 15 then |   if num > 15 then | ||||||
|     error 'implement more dict codes' |     error 'implement more dict codes' | ||||||
|   end |   end | ||||||
|   table.insert(pieces, string.char(128 + num)) |   pieces[#pieces + 1] = string.char(128 + num) | ||||||
| end | end | ||||||
|  |  | ||||||
| local function put(item, item2) | local function put(item, item2) | ||||||
|   table.insert(pieces, mpack.encode(item)) |   table.insert(pieces, vim.mpack.encode(item)) | ||||||
|   if item2 ~= nil then |   if item2 ~= nil then | ||||||
|     table.insert(pieces, mpack.encode(item2)) |     table.insert(pieces, vim.mpack.encode(item2)) | ||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
| @@ -305,15 +365,18 @@ for i, item in ipairs(types) do | |||||||
| end | end | ||||||
|  |  | ||||||
| local packed = table.concat(pieces) | local packed = table.concat(pieces) | ||||||
|  | --- @type fun(api_metadata: file*, name: string, packed: string) | ||||||
| local dump_bin_array = loadfile(dump_bin_array_inputf)() | 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) | dump_bin_array(api_metadata_output, 'packed_api_metadata', packed) | ||||||
| api_metadata_output:close() | api_metadata_output:close() | ||||||
|  |  | ||||||
| -- start building the dispatch wrapper output | -- start building the dispatch wrapper output | ||||||
| local output = assert(io.open(dispatch_outputf, 'wb')) | local output = assert(io.open(dispatch_outputf, 'wb')) | ||||||
|  |  | ||||||
| local keysets_defs = assert(io.open(keysets_outputf, 'wb')) |  | ||||||
|  |  | ||||||
| -- =========================================================================== | -- =========================================================================== | ||||||
| -- NEW API FILES MUST GO HERE. | -- NEW API FILES MUST GO HERE. | ||||||
| -- | -- | ||||||
| @@ -344,6 +407,8 @@ output:write([[ | |||||||
|  |  | ||||||
| ]]) | ]]) | ||||||
|  |  | ||||||
|  | local keysets_defs = assert(io.open(keysets_outputf, 'wb')) | ||||||
|  |  | ||||||
| keysets_defs:write('// IWYU pragma: private, include "nvim/api/private/dispatch.h"\n\n') | keysets_defs:write('// IWYU pragma: private, include "nvim/api/private/dispatch.h"\n\n') | ||||||
|  |  | ||||||
| for _, k in ipairs(keysets) do | for _, k in ipairs(keysets) do | ||||||
| @@ -358,15 +423,10 @@ for _, k in ipairs(keysets) do | |||||||
|       return 'kObjectTypeInteger' |       return 'kObjectTypeInteger' | ||||||
|     elseif not type or vim.startswith(type, 'Union') then |     elseif not type or vim.startswith(type, 'Union') then | ||||||
|       return 'kObjectTypeNil' |       return 'kObjectTypeNil' | ||||||
|     elseif vim.startswith(type, 'LuaRefOf') then |  | ||||||
|       return 'kObjectTypeLuaRef' |  | ||||||
|     elseif type == 'StringArray' then |     elseif type == 'StringArray' then | ||||||
|       return 'kUnpackTypeStringArray' |       return 'kUnpackTypeStringArray' | ||||||
|     elseif vim.startswith(type, 'ArrayOf') then |  | ||||||
|       return 'kObjectTypeArray' |  | ||||||
|     else |  | ||||||
|       return 'kObjectType' .. type |  | ||||||
|     end |     end | ||||||
|  |     return 'kObjectType' .. real_type(type) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   output:write('KeySetLink ' .. k.name .. '_table[] = {\n') |   output:write('KeySetLink ' .. k.name .. '_table[] = {\n') | ||||||
| @@ -410,20 +470,7 @@ KeySetLink *KeyDict_]] .. k.name .. [[_get_field(const char *str, size_t len) | |||||||
| ]]) | ]]) | ||||||
| end | end | ||||||
|  |  | ||||||
| local function real_type(type) | keysets_defs:close() | ||||||
|   local rv = type |  | ||||||
|   local rmatch = string.match(type, 'Dict%(([_%w]+)%)') |  | ||||||
|   if rmatch then |  | ||||||
|     return 'KeyDict_' .. rmatch |  | ||||||
|   elseif c_grammar.typed_container:match(rv) then |  | ||||||
|     if rv:match('Array') then |  | ||||||
|       rv = 'Array' |  | ||||||
|     else |  | ||||||
|       rv = 'Dict' |  | ||||||
|     end |  | ||||||
|   end |  | ||||||
|   return rv |  | ||||||
| end |  | ||||||
|  |  | ||||||
| local function attr_name(rt) | local function attr_name(rt) | ||||||
|   if rt == 'Float' then |   if rt == 'Float' then | ||||||
| @@ -439,7 +486,7 @@ end | |||||||
| for i = 1, #functions do | for i = 1, #functions do | ||||||
|   local fn = functions[i] |   local fn = functions[i] | ||||||
|   if fn.impl_name == nil and fn.remote then |   if fn.impl_name == nil and fn.remote then | ||||||
|     local args = {} |     local args = {} --- @type string[] | ||||||
|  |  | ||||||
|     output:write( |     output:write( | ||||||
|       'Object handle_' .. fn.name .. '(uint64_t channel_id, Array args, Arena* arena, Error *error)' |       'Object handle_' .. fn.name .. '(uint64_t channel_id, Array args, Arena* arena, Error *error)' | ||||||
| @@ -653,8 +700,8 @@ for i = 1, #functions do | |||||||
|     end |     end | ||||||
|  |  | ||||||
|     local ret_type = real_type(fn.return_type) |     local ret_type = real_type(fn.return_type) | ||||||
|     if string.match(ret_type, '^KeyDict_') then |     if ret_type:match('^KeyDict_') then | ||||||
|       local table = string.sub(ret_type, 9) .. '_table' |       local table = ret_type:sub(9) .. '_table' | ||||||
|       output:write( |       output:write( | ||||||
|         '\n  ret = DICT_OBJ(api_keydict_to_dict(&rv, ' |         '\n  ret = DICT_OBJ(api_keydict_to_dict(&rv, ' | ||||||
|           .. table |           .. table | ||||||
| @@ -663,7 +710,7 @@ for i = 1, #functions do | |||||||
|           .. '), arena));' |           .. '), arena));' | ||||||
|       ) |       ) | ||||||
|     elseif ret_type ~= 'void' then |     elseif ret_type ~= 'void' then | ||||||
|       output:write('\n  ret = ' .. string.upper(real_type(fn.return_type)) .. '_OBJ(rv);') |       output:write('\n  ret = ' .. real_type(fn.return_type):upper() .. '_OBJ(rv);') | ||||||
|     end |     end | ||||||
|     output:write('\n\ncleanup:') |     output:write('\n\ncleanup:') | ||||||
|  |  | ||||||
| @@ -671,6 +718,7 @@ for i = 1, #functions do | |||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
|  | --- @type {[string]: gen_api_dispatch.Function, redraw: {impl_name: string, fast: boolean}} | ||||||
| local remote_fns = {} | local remote_fns = {} | ||||||
| for _, fn in ipairs(functions) do | for _, fn in ipairs(functions) do | ||||||
|   if fn.remote then |   if fn.remote then | ||||||
| @@ -706,9 +754,10 @@ output:write(hashfun) | |||||||
|  |  | ||||||
| output:close() | output:close() | ||||||
|  |  | ||||||
|  | --- @cast functions {[integer]: gen_api_dispatch.Function, keysets: gen_api_dispatch.Keyset[]} | ||||||
| functions.keysets = keysets | functions.keysets = keysets | ||||||
| local mpack_output = assert(io.open(mpack_outputf, 'wb')) | local mpack_output = assert(io.open(mpack_outputf, 'wb')) | ||||||
| mpack_output:write(mpack.encode(functions)) | mpack_output:write(vim.mpack.encode(functions)) | ||||||
| mpack_output:close() | mpack_output:close() | ||||||
|  |  | ||||||
| local function include_headers(output_handle, headers_to_include) | local function include_headers(output_handle, headers_to_include) | ||||||
| @@ -719,11 +768,12 @@ local function include_headers(output_handle, headers_to_include) | |||||||
|   end |   end | ||||||
| end | end | ||||||
|  |  | ||||||
|  | --- @param str string | ||||||
| local function write_shifted_output(str, ...) | local function write_shifted_output(str, ...) | ||||||
|   str = str:gsub('\n  ', '\n') |   str = str:gsub('\n  ', '\n') | ||||||
|   str = str:gsub('^  ', '') |   str = str:gsub('^  ', '') | ||||||
|   str = str:gsub(' +$', '') |   str = str:gsub(' +$', '') | ||||||
|   output:write(string.format(str, ...)) |   output:write(str:format(...)) | ||||||
| end | end | ||||||
|  |  | ||||||
| -- start building lua output | -- start building lua output | ||||||
| @@ -732,12 +782,14 @@ output = assert(io.open(lua_c_bindings_outputf, 'wb')) | |||||||
| include_headers(output, headers) | include_headers(output, headers) | ||||||
| output:write('\n') | output:write('\n') | ||||||
|  |  | ||||||
|  | --- @type {binding: string, api:string}[] | ||||||
| local lua_c_functions = {} | local lua_c_functions = {} | ||||||
|  |  | ||||||
| --- Generates C code to bridge RPC API <=> Lua. | --- Generates C code to bridge RPC API <=> Lua. | ||||||
| --- | --- | ||||||
| --- Inspect the result here: | --- Inspect the result here: | ||||||
| ---    build/src/nvim/auto/api/private/dispatch_wrappers.generated.h | ---    build/src/nvim/auto/api/private/dispatch_wrappers.generated.h | ||||||
|  | --- @param fn gen_api_dispatch.Function | ||||||
| local function process_function(fn) | local function process_function(fn) | ||||||
|   local lua_c_function_name = ('nlua_api_%s'):format(fn.name) |   local lua_c_function_name = ('nlua_api_%s'):format(fn.name) | ||||||
|   write_shifted_output( |   write_shifted_output( | ||||||
| @@ -791,14 +843,14 @@ local function process_function(fn) | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   local cparams = '' |   local cparams = '' | ||||||
|   local free_code = {} |   local free_code = {} --- @type string[] | ||||||
|   for j = #fn.parameters, 1, -1 do |   for j = #fn.parameters, 1, -1 do | ||||||
|     local param = fn.parameters[j] |     local param = fn.parameters[j] | ||||||
|     local cparam = string.format('arg%u', j) |     local cparam = string.format('arg%u', j) | ||||||
|     local param_type = real_type(param[1]) |     local param_type = real_type(param[1]) | ||||||
|     local extra = param_type == 'Dict' and 'false, ' or '' |     local extra = param_type == 'Dict' and 'false, ' or '' | ||||||
|     local arg_free_code = '' |     local arg_free_code = '' | ||||||
|     if param[1] == 'Object' then |     if param_type == 'Object' then | ||||||
|       extra = 'true, ' |       extra = 'true, ' | ||||||
|       arg_free_code = '  api_luarefs_free_object(' .. cparam .. ');' |       arg_free_code = '  api_luarefs_free_object(' .. cparam .. ');' | ||||||
|     elseif param[1] == 'DictOf(LuaRef)' then |     elseif param[1] == 'DictOf(LuaRef)' then | ||||||
| @@ -809,7 +861,7 @@ local function process_function(fn) | |||||||
|     end |     end | ||||||
|     local errshift = 0 |     local errshift = 0 | ||||||
|     local seterr = '' |     local seterr = '' | ||||||
|     if string.match(param_type, '^KeyDict_') then |     if param_type:match('^KeyDict_') then | ||||||
|       write_shifted_output( |       write_shifted_output( | ||||||
|         [[ |         [[ | ||||||
|     %s %s = KEYDICT_INIT; |     %s %s = KEYDICT_INIT; | ||||||
| @@ -825,7 +877,7 @@ local function process_function(fn) | |||||||
|       arg_free_code = '  api_luarefs_free_keydict(' |       arg_free_code = '  api_luarefs_free_keydict(' | ||||||
|         .. cparam |         .. cparam | ||||||
|         .. ', ' |         .. ', ' | ||||||
|         .. string.sub(param_type, 9) |         .. param_type:sub(9) | ||||||
|         .. '_table);' |         .. '_table);' | ||||||
|     else |     else | ||||||
|       write_shifted_output( |       write_shifted_output( | ||||||
| @@ -851,6 +903,7 @@ local function process_function(fn) | |||||||
|     cparams = cparam .. ', ' .. cparams |     cparams = cparam .. ', ' .. cparams | ||||||
|   end |   end | ||||||
|   if fn.receives_channel_id then |   if fn.receives_channel_id then | ||||||
|  |     --- @type string | ||||||
|     cparams = 'LUA_INTERNAL_CALL, ' .. cparams |     cparams = 'LUA_INTERNAL_CALL, ' .. cparams | ||||||
|   end |   end | ||||||
|   if fn.receives_arena then |   if fn.receives_arena then | ||||||
| @@ -870,7 +923,7 @@ local function process_function(fn) | |||||||
|   for i = 1, #free_code do |   for i = 1, #free_code do | ||||||
|     local rev_i = #free_code - i + 1 |     local rev_i = #free_code - i + 1 | ||||||
|     local code = free_code[rev_i] |     local code = free_code[rev_i] | ||||||
|     if i == 1 and not string.match(real_type(fn.parameters[1][1]), '^KeyDict_') then |     if i == 1 and not real_type(fn.parameters[1][1]):match('^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 |     else | ||||||
|       free_at_exit_code = free_at_exit_code .. ('\nexit_%u:\n%s'):format(rev_i, code) |       free_at_exit_code = free_at_exit_code .. ('\nexit_%u:\n%s'):format(rev_i, code) | ||||||
| @@ -893,13 +946,8 @@ exit_0: | |||||||
|     return lua_error(lstate); |     return lua_error(lstate); | ||||||
|   } |   } | ||||||
| ]] | ]] | ||||||
|   local return_type |  | ||||||
|   if fn.return_type ~= 'void' then |   if fn.return_type ~= 'void' then | ||||||
|     if fn.return_type:match('^ArrayOf') then |     local return_type = real_type(fn.return_type) | ||||||
|       return_type = 'Array' |  | ||||||
|     else |  | ||||||
|       return_type = fn.return_type |  | ||||||
|     end |  | ||||||
|     local free_retval = '' |     local free_retval = '' | ||||||
|     if fn.ret_alloc then |     if fn.ret_alloc then | ||||||
|       free_retval = '  api_free_' .. return_type:lower() .. '(ret);' |       free_retval = '  api_free_' .. return_type:lower() .. '(ret);' | ||||||
| @@ -919,11 +967,8 @@ exit_0: | |||||||
|         return_type, |         return_type, | ||||||
|         ret_mode |         ret_mode | ||||||
|       ) |       ) | ||||||
|     elseif string.match(ret_type, '^KeyDict_') then |     elseif ret_type:match('^KeyDict_') then | ||||||
|       write_shifted_output( |       write_shifted_output('    nlua_push_keydict(lstate, &ret, %s_table);\n', return_type:sub(9)) | ||||||
|         '    nlua_push_keydict(lstate, &ret, %s_table);\n', |  | ||||||
|         string.sub(ret_type, 9) |  | ||||||
|       ) |  | ||||||
|     else |     else | ||||||
|       local special = (fn.since ~= nil and fn.since < 11) |       local special = (fn.since ~= nil and fn.since < 11) | ||||||
|       write_shifted_output( |       write_shifted_output( | ||||||
| @@ -996,4 +1041,3 @@ output:write([[ | |||||||
| ]]) | ]]) | ||||||
|  |  | ||||||
| output:close() | output:close() | ||||||
| keysets_defs:close() |  | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
| -- Generator for various vimdoc and Lua type files | -- Generator for various vimdoc and Lua type files | ||||||
|  |  | ||||||
| local util = require('gen.util') | local util = require('gen.util') | ||||||
|  | local api_type = require('gen.api_types') | ||||||
| local fmt = string.format | local fmt = string.format | ||||||
|  |  | ||||||
| local DEP_API_METADATA = arg[1] | local DEP_API_METADATA = arg[1] | ||||||
| @@ -23,54 +24,6 @@ local TEXT_WIDTH = 78 | |||||||
| --- @field remote boolean | --- @field remote boolean | ||||||
| --- @field since integer | --- @field since integer | ||||||
|  |  | ||||||
| local LUA_API_RETURN_OVERRIDES = { |  | ||||||
|   nvim_buf_get_command = 'table<string,vim.api.keyset.command_info>', |  | ||||||
|   nvim_buf_get_extmark_by_id = 'vim.api.keyset.get_extmark_item_by_id', |  | ||||||
|   nvim_buf_get_extmarks = 'vim.api.keyset.get_extmark_item[]', |  | ||||||
|   nvim_buf_get_keymap = 'vim.api.keyset.get_keymap[]', |  | ||||||
|   nvim_get_autocmds = 'vim.api.keyset.get_autocmds.ret[]', |  | ||||||
|   nvim_get_color_map = 'table<string,integer>', |  | ||||||
|   nvim_get_command = 'table<string,vim.api.keyset.command_info>', |  | ||||||
|   nvim_get_keymap = 'vim.api.keyset.get_keymap[]', |  | ||||||
|   nvim_get_mark = 'vim.api.keyset.get_mark', |  | ||||||
|   nvim_eval_statusline = 'vim.api.keyset.eval_statusline_ret', |  | ||||||
|  |  | ||||||
|   -- Can also return table<string,vim.api.keyset.get_hl_info>, however we need to |  | ||||||
|   -- pick one to get some benefit. |  | ||||||
|   -- REVISIT lewrus01 (26/01/24): we can maybe add |  | ||||||
|   -- @overload fun(ns: integer, {}): table<string,vim.api.keyset.get_hl_info> |  | ||||||
|   nvim_get_hl = 'vim.api.keyset.get_hl_info', |  | ||||||
|  |  | ||||||
|   nvim_get_mode = 'vim.api.keyset.get_mode', |  | ||||||
|   nvim_get_namespaces = 'table<string,integer>', |  | ||||||
|   nvim_get_option_info = 'vim.api.keyset.get_option_info', |  | ||||||
|   nvim_get_option_info2 = 'vim.api.keyset.get_option_info', |  | ||||||
|   nvim_parse_cmd = 'vim.api.keyset.parse_cmd', |  | ||||||
|   nvim_win_get_config = 'vim.api.keyset.win_config', |  | ||||||
|   nvim_win_text_height = 'vim.api.keyset.win_text_height_ret', |  | ||||||
| } |  | ||||||
|  |  | ||||||
| local LUA_API_KEYSET_OVERRIDES = { |  | ||||||
|   create_autocmd = { |  | ||||||
|     callback = 'string|(fun(args: vim.api.keyset.create_autocmd.callback_args): boolean?)', |  | ||||||
|   }, |  | ||||||
|   win_config = { |  | ||||||
|     anchor = "'NW'|'NE'|'SW'|'SE'", |  | ||||||
|     relative = "'cursor'|'editor'|'laststatus'|'mouse'|'tabline'|'win'", |  | ||||||
|     split = "'left'|'right'|'above'|'below'", |  | ||||||
|     border = "'none'|'single'|'double'|'rounded'|'solid'|'shadow'|string[]", |  | ||||||
|     title_pos = "'center'|'left'|'right'", |  | ||||||
|     footer_pos = "'center'|'left'|'right'", |  | ||||||
|     style = "'minimal'", |  | ||||||
|   }, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| local LUA_API_PARAM_OVERRIDES = { |  | ||||||
|   nvim_create_user_command = { |  | ||||||
|     command = 'string|fun(args: vim.api.keyset.create_user_command.command_args)', |  | ||||||
|   }, |  | ||||||
| } |  | ||||||
|  |  | ||||||
| local LUA_META_HEADER = { | local LUA_META_HEADER = { | ||||||
|   '--- @meta _', |   '--- @meta _', | ||||||
|   '-- THIS FILE IS GENERATED', |   '-- THIS FILE IS GENERATED', | ||||||
| @@ -134,22 +87,6 @@ local OPTION_TYPES = { | |||||||
|   string = 'string', |   string = 'string', | ||||||
| } | } | ||||||
|  |  | ||||||
| local API_TYPES = { |  | ||||||
|   Window = 'integer', |  | ||||||
|   Tabpage = 'integer', |  | ||||||
|   Buffer = 'integer', |  | ||||||
|   Boolean = 'boolean', |  | ||||||
|   Object = 'any', |  | ||||||
|   Integer = 'integer', |  | ||||||
|   String = 'string', |  | ||||||
|   Array = 'any[]', |  | ||||||
|   LuaRef = 'function', |  | ||||||
|   Dict = 'table<string,any>', |  | ||||||
|   Float = 'number', |  | ||||||
|   HLGroupID = 'integer|string', |  | ||||||
|   void = '', |  | ||||||
| } |  | ||||||
|  |  | ||||||
| --- @param s string | --- @param s string | ||||||
| --- @return string | --- @return string | ||||||
| local function luaescape(s) | local function luaescape(s) | ||||||
| @@ -166,66 +103,6 @@ local function split(x, sep) | |||||||
|   return vim.split(x, sep or '\n', { plain = true }) |   return vim.split(x, sep or '\n', { plain = true }) | ||||||
| end | end | ||||||
|  |  | ||||||
| --- Convert an API type to Lua |  | ||||||
| --- @param t string |  | ||||||
| --- @return string |  | ||||||
| local function api_type(t) |  | ||||||
|   if vim.startswith(t, '*') then |  | ||||||
|     return api_type(t:sub(2)) .. '?' |  | ||||||
|   end |  | ||||||
|  |  | ||||||
|   local as0 = t:match('^ArrayOf%((.*)%)') |  | ||||||
|   if as0 then |  | ||||||
|     local as = split(as0, ', ') |  | ||||||
|     local a = api_type(as[1]) |  | ||||||
|     local count = tonumber(as[2]) |  | ||||||
|     if count then |  | ||||||
|       return fmt('[%s]', a:rep(count, ', ')) |  | ||||||
|     else |  | ||||||
|       return a .. '[]' |  | ||||||
|     end |  | ||||||
|   end |  | ||||||
|  |  | ||||||
|   local d = t:match('^Dict%((.*)%)') |  | ||||||
|   if d then |  | ||||||
|     return 'vim.api.keyset.' .. d |  | ||||||
|   end |  | ||||||
|  |  | ||||||
|   local d0 = t:match('^DictOf%((.*)%)') |  | ||||||
|   if d0 then |  | ||||||
|     return 'table<string,' .. api_type(d0) .. '>' |  | ||||||
|   end |  | ||||||
|  |  | ||||||
|   local u = t:match('^Union%((.*)%)') |  | ||||||
|   if u then |  | ||||||
|     local us = vim.split(u, ',%s*') |  | ||||||
|     return table.concat(vim.tbl_map(api_type, us), '|') |  | ||||||
|   end |  | ||||||
|  |  | ||||||
|   local l = t:match('^LuaRefOf%((.*)%)') |  | ||||||
|   if l then |  | ||||||
|     --- @type string |  | ||||||
|     l = l:gsub('%s+', ' ') |  | ||||||
|     --- @type string?, string? |  | ||||||
|     local as, r = l:match('%((.*)%),%s*(.*)') |  | ||||||
|     if not as then |  | ||||||
|       --- @type string |  | ||||||
|       as = assert(l:match('%((.*)%)')) |  | ||||||
|     end |  | ||||||
|  |  | ||||||
|     local as1 = {} --- @type string[] |  | ||||||
|     for a in vim.gsplit(as, ',%s') do |  | ||||||
|       local a1 = vim.split(a, '%s+', { trimempty = true }) |  | ||||||
|       local nm = a1[2]:gsub('%*(.*)$', '%1?') |  | ||||||
|       as1[#as1 + 1] = nm .. ': ' .. api_type(a1[1]) |  | ||||||
|     end |  | ||||||
|  |  | ||||||
|     return fmt('fun(%s)%s', table.concat(as1, ', '), r and ': ' .. api_type(r) or '') |  | ||||||
|   end |  | ||||||
|  |  | ||||||
|   return API_TYPES[t] or t |  | ||||||
| end |  | ||||||
|  |  | ||||||
| --- @param f string | --- @param f string | ||||||
| --- @param params [string,string][]|true | --- @param params [string,string][]|true | ||||||
| --- @return string | --- @return string | ||||||
| @@ -321,13 +198,11 @@ local function get_api_meta() | |||||||
|       sees[#sees + 1] = see.desc |       sees[#sees + 1] = see.desc | ||||||
|     end |     end | ||||||
|  |  | ||||||
|     local pty_overrides = LUA_API_PARAM_OVERRIDES[fun.name] or {} |  | ||||||
|  |  | ||||||
|     local params = {} --- @type [string,string][] |     local params = {} --- @type [string,string][] | ||||||
|     for _, p in ipairs(fun.params) do |     for _, p in ipairs(fun.params) do | ||||||
|       params[#params + 1] = { |       params[#params + 1] = { | ||||||
|         p.name, |         p.name, | ||||||
|         api_type(pty_overrides[p.name] or p.type), |         p.type, | ||||||
|         not deprecated and p.desc or nil, |         not deprecated and p.desc or nil, | ||||||
|       } |       } | ||||||
|     end |     end | ||||||
| @@ -338,7 +213,7 @@ local function get_api_meta() | |||||||
|       params = params, |       params = params, | ||||||
|       notes = notes, |       notes = notes, | ||||||
|       see = sees, |       see = sees, | ||||||
|       returns = api_type(fun.returns[1].type), |       returns = fun.returns[1].type, | ||||||
|       deprecated = deprecated, |       deprecated = deprecated, | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -429,10 +304,9 @@ local function render_api_meta(_f, fun, write) | |||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   if fun.returns ~= '' then |   if fun.returns ~= 'nil' then | ||||||
|     local ret_desc = fun.returns_desc and ' # ' .. fun.returns_desc or '' |     local ret_desc = fun.returns_desc and ' # ' .. fun.returns_desc or '' | ||||||
|     local ret = LUA_API_RETURN_OVERRIDES[fun.name] or fun.returns |     write(util.prefix_lines('--- ', '@return ' .. fun.returns .. ret_desc)) | ||||||
|     write(util.prefix_lines('--- ', '@return ' .. ret .. ret_desc)) |  | ||||||
|   end |   end | ||||||
|   local param_str = table.concat(param_names, ', ') |   local param_str = table.concat(param_names, ', ') | ||||||
|  |  | ||||||
| @@ -450,10 +324,9 @@ local function get_api_keysets_meta() | |||||||
|   local keysets = metadata.keysets |   local keysets = metadata.keysets | ||||||
|  |  | ||||||
|   for _, k in ipairs(keysets) do |   for _, k in ipairs(keysets) do | ||||||
|     local pty_overrides = LUA_API_KEYSET_OVERRIDES[k.name] or {} |  | ||||||
|     local params = {} |     local params = {} | ||||||
|     for _, key in ipairs(k.keys) do |     for _, key in ipairs(k.keys) do | ||||||
|       local pty = pty_overrides[key] or k.types[key] or 'any' |       local pty = k.types[key] or 'any' | ||||||
|       table.insert(params, { key .. '?', api_type(pty) }) |       table.insert(params, { key .. '?', api_type(pty) }) | ||||||
|     end |     end | ||||||
|     ret[k.name] = { |     ret[k.name] = { | ||||||
|   | |||||||
| @@ -38,8 +38,6 @@ local INDENTATION = 4 | |||||||
| --- List of files/directories for doxygen to read, relative to `base_dir`. | --- List of files/directories for doxygen to read, relative to `base_dir`. | ||||||
| --- @field files string[] | --- @field files string[] | ||||||
| --- | --- | ||||||
| --- @field exclude_types? true |  | ||||||
| --- |  | ||||||
| --- Section name overrides. Key: filename (e.g., vim.c) | --- Section name overrides. Key: filename (e.g., vim.c) | ||||||
| --- @field section_name? table<string,string> | --- @field section_name? table<string,string> | ||||||
| --- | --- | ||||||
| @@ -119,7 +117,6 @@ local config = { | |||||||
|       'autocmd.c', |       'autocmd.c', | ||||||
|       'ui.c', |       'ui.c', | ||||||
|     }, |     }, | ||||||
|     exclude_types = true, |  | ||||||
|     fn_name_pat = 'nvim_.*', |     fn_name_pat = 'nvim_.*', | ||||||
|     files = { 'src/nvim/api' }, |     files = { 'src/nvim/api' }, | ||||||
|     section_name = { |     section_name = { | ||||||
| @@ -550,9 +547,8 @@ end | |||||||
| --- @param xs (nvim.luacats.parser.param|nvim.luacats.parser.field)[] | --- @param xs (nvim.luacats.parser.param|nvim.luacats.parser.field)[] | ||||||
| --- @param generics? table<string,string> | --- @param generics? table<string,string> | ||||||
| --- @param classes? table<string,nvim.luacats.parser.class> | --- @param classes? table<string,nvim.luacats.parser.class> | ||||||
| --- @param exclude_types? true |  | ||||||
| --- @param cfg nvim.gen_vimdoc.Config | --- @param cfg nvim.gen_vimdoc.Config | ||||||
| local function render_fields_or_params(xs, generics, classes, exclude_types, cfg) | local function render_fields_or_params(xs, generics, classes, cfg) | ||||||
|   local ret = {} --- @type string[] |   local ret = {} --- @type string[] | ||||||
|  |  | ||||||
|   xs = vim.tbl_filter(should_render_field_or_param, xs) |   xs = vim.tbl_filter(should_render_field_or_param, xs) | ||||||
| @@ -562,9 +558,6 @@ local function render_fields_or_params(xs, generics, classes, exclude_types, cfg | |||||||
|     if p.type or p.desc then |     if p.type or p.desc then | ||||||
|       indent = math.max(indent, #p.name + 3) |       indent = math.max(indent, #p.name + 3) | ||||||
|     end |     end | ||||||
|     if exclude_types then |  | ||||||
|       p.type = nil |  | ||||||
|     end |  | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   for _, p in ipairs(xs) do |   for _, p in ipairs(xs) do | ||||||
| @@ -627,7 +620,7 @@ local function render_class(class, classes, cfg) | |||||||
|     table.insert(ret, md_to_vimdoc(class.desc, INDENTATION, INDENTATION, TEXT_WIDTH)) |     table.insert(ret, md_to_vimdoc(class.desc, INDENTATION, INDENTATION, TEXT_WIDTH)) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   local fields_txt = render_fields_or_params(class.fields, nil, classes, nil, cfg) |   local fields_txt = render_fields_or_params(class.fields, nil, classes, cfg) | ||||||
|   if not fields_txt:match('^%s*$') then |   if not fields_txt:match('^%s*$') then | ||||||
|     table.insert(ret, '\n    Fields: ~\n') |     table.insert(ret, '\n    Fields: ~\n') | ||||||
|     table.insert(ret, fields_txt) |     table.insert(ret, fields_txt) | ||||||
| @@ -692,15 +685,12 @@ end | |||||||
| --- @param returns nvim.luacats.parser.return[] | --- @param returns nvim.luacats.parser.return[] | ||||||
| --- @param generics? table<string,string> | --- @param generics? table<string,string> | ||||||
| --- @param classes? table<string,nvim.luacats.parser.class> | --- @param classes? table<string,nvim.luacats.parser.class> | ||||||
| --- @param exclude_types boolean | --- @return string? | ||||||
| local function render_returns(returns, generics, classes, exclude_types) | local function render_returns(returns, generics, classes) | ||||||
|   local ret = {} --- @type string[] |   local ret = {} --- @type string[] | ||||||
|  |  | ||||||
|   returns = vim.deepcopy(returns) |   if #returns == 1 and returns[1].type == 'nil' then | ||||||
|   if exclude_types then |     return | ||||||
|     for _, r in ipairs(returns) do |  | ||||||
|       r.type = nil |  | ||||||
|     end |  | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   if #returns > 1 then |   if #returns > 1 then | ||||||
| @@ -720,7 +710,7 @@ local function render_returns(returns, generics, classes, exclude_types) | |||||||
|     blk[#blk + 1] = rnm |     blk[#blk + 1] = rnm | ||||||
|     blk[#blk + 1] = desc |     blk[#blk + 1] = desc | ||||||
|  |  | ||||||
|     table.insert(ret, md_to_vimdoc(table.concat(blk, ' '), 8, 8, TEXT_WIDTH, true)) |     ret[#ret + 1] = md_to_vimdoc(table.concat(blk, ' '), 8, 8, TEXT_WIDTH, true) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   return table.concat(ret) |   return table.concat(ret) | ||||||
| @@ -788,8 +778,7 @@ local function render_fun(fun, classes, cfg) | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   if fun.params and #fun.params > 0 then |   if fun.params and #fun.params > 0 then | ||||||
|     local param_txt = |     local param_txt = render_fields_or_params(fun.params, fun.generics, classes, cfg) | ||||||
|       render_fields_or_params(fun.params, fun.generics, classes, cfg.exclude_types, cfg) |  | ||||||
|     if not param_txt:match('^%s*$') then |     if not param_txt:match('^%s*$') then | ||||||
|       table.insert(ret, '\n    Parameters: ~\n') |       table.insert(ret, '\n    Parameters: ~\n') | ||||||
|       ret[#ret + 1] = param_txt |       ret[#ret + 1] = param_txt | ||||||
| @@ -804,8 +793,8 @@ local function render_fun(fun, classes, cfg) | |||||||
|   end |   end | ||||||
|  |  | ||||||
|   if fun.returns then |   if fun.returns then | ||||||
|     local txt = render_returns(fun.returns, fun.generics, classes, cfg.exclude_types) |     local txt = render_returns(fun.returns, fun.generics, classes) | ||||||
|     if not txt:match('^%s*$') then |     if txt and not txt:match('^%s*$') then | ||||||
|       table.insert(ret, '\n') |       table.insert(ret, '\n') | ||||||
|       ret[#ret + 1] = txt |       ret[#ret + 1] = txt | ||||||
|     end |     end | ||||||
|   | |||||||
| @@ -90,7 +90,8 @@ static int64_t next_autocmd_id = 1; | |||||||
| ///             - once: (boolean) whether the autocommand is only run once. | ///             - once: (boolean) whether the autocommand is only run once. | ||||||
| ///             - pattern: (string) the autocommand pattern. | ///             - pattern: (string) the autocommand pattern. | ||||||
| ///               If the autocommand is buffer local |autocmd-buffer-local|: | ///               If the autocommand is buffer local |autocmd-buffer-local|: | ||||||
| Array nvim_get_autocmds(Dict(get_autocmds) *opts, Arena *arena, Error *err) | ArrayOf(DictAs(get_autocmds__ret)) nvim_get_autocmds(Dict(get_autocmds) *opts, Arena *arena, | ||||||
|  |                                                      Error *err) | ||||||
|   FUNC_API_SINCE(9) |   FUNC_API_SINCE(9) | ||||||
| { | { | ||||||
|   ArrayBuilder autocmd_list = KV_INITIAL_VALUE; |   ArrayBuilder autocmd_list = KV_INITIAL_VALUE; | ||||||
|   | |||||||
| @@ -856,7 +856,8 @@ Integer nvim_buf_get_changedtick(Buffer buffer, Error *err) | |||||||
| /// @param[out]  err   Error details, if any | /// @param[out]  err   Error details, if any | ||||||
| /// @returns Array of |maparg()|-like dictionaries describing mappings. | /// @returns Array of |maparg()|-like dictionaries describing mappings. | ||||||
| ///          The "buffer" key holds the associated buffer id. | ///          The "buffer" key holds the associated buffer id. | ||||||
| ArrayOf(Dict) nvim_buf_get_keymap(Buffer buffer, String mode, Arena *arena, Error *err) | ArrayOf(DictAs(get_keymap)) nvim_buf_get_keymap(Buffer buffer, String mode, Arena *arena, | ||||||
|  |                                                 Error *err) | ||||||
|   FUNC_API_SINCE(3) |   FUNC_API_SINCE(3) | ||||||
| { | { | ||||||
|   buf_T *buf = find_buffer_by_handle(buffer, err); |   buf_T *buf = find_buffer_by_handle(buffer, err); | ||||||
|   | |||||||
| @@ -927,6 +927,8 @@ static void build_cmdline_str(char **cmdlinep, exarg_T *eap, CmdParseInfo *cmdin | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // uncrustify:off | ||||||
|  |  | ||||||
| /// Creates a global |user-commands| command. | /// Creates a global |user-commands| command. | ||||||
| /// | /// | ||||||
| /// For Lua usage see |lua-guide-commands-create|. | /// For Lua usage see |lua-guide-commands-create|. | ||||||
| @@ -968,13 +970,18 @@ static void build_cmdline_str(char **cmdlinep, exarg_T *eap, CmdParseInfo *cmdin | |||||||
| ///                   - force: (boolean, default true) Override any previous definition. | ///                   - force: (boolean, default true) Override any previous definition. | ||||||
| ///                   - preview: (function) Preview callback for 'inccommand' |:command-preview| | ///                   - preview: (function) Preview callback for 'inccommand' |:command-preview| | ||||||
| /// @param[out] err Error details, if any. | /// @param[out] err Error details, if any. | ||||||
| void nvim_create_user_command(uint64_t channel_id, String name, Object command, | void nvim_create_user_command(uint64_t channel_id, | ||||||
|                               Dict(user_command) *opts, Error *err) |                               String name, | ||||||
|  |                               Union(String, LuaRefOf((DictAs(create_user_command__command_args) args))) command, | ||||||
|  |                               Dict(user_command) *opts, | ||||||
|  |                               Error *err) | ||||||
|   FUNC_API_SINCE(9) |   FUNC_API_SINCE(9) | ||||||
| { | { | ||||||
|   create_user_command(channel_id, name, command, opts, 0, err); |   create_user_command(channel_id, name, command, opts, 0, err); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // uncrustify:on | ||||||
|  |  | ||||||
| /// Delete a user-defined command. | /// Delete a user-defined command. | ||||||
| /// | /// | ||||||
| /// @param  name    Name of the command to delete. | /// @param  name    Name of the command to delete. | ||||||
| @@ -1045,8 +1052,8 @@ void nvim_buf_del_user_command(Buffer buffer, String name, Error *err) | |||||||
|   api_set_error(err, kErrorTypeException, "Invalid command (not found): %s", name.data); |   api_set_error(err, kErrorTypeException, "Invalid command (not found): %s", name.data); | ||||||
| } | } | ||||||
|  |  | ||||||
| void create_user_command(uint64_t channel_id, String name, Object command, Dict(user_command) *opts, | void create_user_command(uint64_t channel_id, String name, Union(String, LuaRef) command, | ||||||
|                          int flags, Error *err) |                          Dict(user_command) *opts, int flags, Error *err) | ||||||
| { | { | ||||||
|   uint32_t argt = 0; |   uint32_t argt = 0; | ||||||
|   int64_t def = -1; |   int64_t def = -1; | ||||||
| @@ -1260,7 +1267,7 @@ err: | |||||||
| /// @param[out]  err   Error details, if any. | /// @param[out]  err   Error details, if any. | ||||||
| /// | /// | ||||||
| /// @returns Map of maps describing commands. | /// @returns Map of maps describing commands. | ||||||
| Dict nvim_get_commands(Dict(get_commands) *opts, Arena *arena, Error *err) | DictOf(DictAs(command_info)) nvim_get_commands(Dict(get_commands) *opts, Arena *arena, Error *err) | ||||||
|   FUNC_API_SINCE(4) |   FUNC_API_SINCE(4) | ||||||
| { | { | ||||||
|   return nvim_buf_get_commands(-1, opts, arena, err); |   return nvim_buf_get_commands(-1, opts, arena, err); | ||||||
| @@ -1273,7 +1280,8 @@ Dict nvim_get_commands(Dict(get_commands) *opts, Arena *arena, Error *err) | |||||||
| /// @param[out]  err   Error details, if any. | /// @param[out]  err   Error details, if any. | ||||||
| /// | /// | ||||||
| /// @returns Map of maps describing commands. | /// @returns Map of maps describing commands. | ||||||
| Dict nvim_buf_get_commands(Buffer buffer, Dict(get_commands) *opts, Arena *arena, Error *err) | DictAs(command_info) nvim_buf_get_commands(Buffer buffer, Dict(get_commands) *opts, Arena *arena, | ||||||
|  |                                            Error *err) | ||||||
|   FUNC_API_SINCE(4) |   FUNC_API_SINCE(4) | ||||||
| { | { | ||||||
|   bool global = (buffer == -1); |   bool global = (buffer == -1); | ||||||
|   | |||||||
| @@ -603,7 +603,7 @@ static int64_t convert_index(int64_t index) | |||||||
| /// @param          name Option name | /// @param          name Option name | ||||||
| /// @param[out] err Error details, if any | /// @param[out] err Error details, if any | ||||||
| /// @return         Option Information | /// @return         Option Information | ||||||
| Dict nvim_get_option_info(String name, Arena *arena, Error *err) | DictAs(get_option_info) nvim_get_option_info(String name, Arena *arena, Error *err) | ||||||
|   FUNC_API_SINCE(7) |   FUNC_API_SINCE(7) | ||||||
|   FUNC_API_DEPRECATED_SINCE(11) |   FUNC_API_DEPRECATED_SINCE(11) | ||||||
| { | { | ||||||
|   | |||||||
| @@ -75,7 +75,7 @@ Integer nvim_create_namespace(String name) | |||||||
| /// Gets existing, non-anonymous |namespace|s. | /// Gets existing, non-anonymous |namespace|s. | ||||||
| /// | /// | ||||||
| /// @return dict that maps from names to namespace ids. | /// @return dict that maps from names to namespace ids. | ||||||
| Dict nvim_get_namespaces(Arena *arena) | DictOf(Integer) nvim_get_namespaces(Arena *arena) | ||||||
|   FUNC_API_SINCE(5) |   FUNC_API_SINCE(5) | ||||||
| { | { | ||||||
|   Dict retval = arena_dict(arena, map_size(&namespace_ids)); |   Dict retval = arena_dict(arena, map_size(&namespace_ids)); | ||||||
| @@ -201,9 +201,9 @@ static Array extmark_to_array(MTPair extmark, bool id, bool add_dict, bool hl_na | |||||||
| /// @param[out] err   Error details, if any | /// @param[out] err   Error details, if any | ||||||
| /// @return 0-indexed (row, col) tuple or empty list () if extmark id was | /// @return 0-indexed (row, col) tuple or empty list () if extmark id was | ||||||
| /// absent | /// absent | ||||||
| ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id, | Tuple(Integer, Integer, *DictAs(extmark_details)) | ||||||
|                                             Integer id, Dict(get_extmark) *opts, | nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id, Integer id, Dict(get_extmark) * opts, | ||||||
|                                             Arena *arena, Error *err) |                            Arena *arena, Error *err) | ||||||
|   FUNC_API_SINCE(7) |   FUNC_API_SINCE(7) | ||||||
| { | { | ||||||
|   Array rv = ARRAY_DICT_INIT; |   Array rv = ARRAY_DICT_INIT; | ||||||
| @@ -287,8 +287,10 @@ ArrayOf(Integer) nvim_buf_get_extmark_by_id(Buffer buffer, Integer ns_id, | |||||||
| ///          - type: Filter marks by type: "highlight", "sign", "virt_text" and "virt_lines" | ///          - type: Filter marks by type: "highlight", "sign", "virt_text" and "virt_lines" | ||||||
| /// @param[out] err   Error details, if any | /// @param[out] err   Error details, if any | ||||||
| /// @return List of `[extmark_id, row, col]` tuples in "traversal order". | /// @return List of `[extmark_id, row, col]` tuples in "traversal order". | ||||||
| Array nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, Object end, | ArrayOf(DictAs(get_extmark_item)) nvim_buf_get_extmarks(Buffer buffer, Integer ns_id, Object start, | ||||||
|                             Dict(get_extmarks) *opts, Arena *arena, Error *err) |                                                         Object end, | ||||||
|  |                                                         Dict(get_extmarks) *opts, Arena *arena, | ||||||
|  |                                                         Error *err) | ||||||
|   FUNC_API_SINCE(7) |   FUNC_API_SINCE(7) | ||||||
| { | { | ||||||
|   Array rv = ARRAY_DICT_INIT; |   Array rv = ARRAY_DICT_INIT; | ||||||
|   | |||||||
| @@ -116,9 +116,9 @@ typedef struct { | |||||||
|   Float col; |   Float col; | ||||||
|   Integer width; |   Integer width; | ||||||
|   Integer height; |   Integer height; | ||||||
|   String anchor; |   Enum("NW", "NE", "SW", "SE") anchor; | ||||||
|   String relative; |   Enum("cursor", "editor", "laststatus", "mouse", "tabline", "win") relative; | ||||||
|   String split; |   Enum("left", "right", "above", "below") split; | ||||||
|   Window win; |   Window win; | ||||||
|   ArrayOf(Integer) bufpos; |   ArrayOf(Integer) bufpos; | ||||||
|   Boolean external; |   Boolean external; | ||||||
| @@ -126,12 +126,12 @@ typedef struct { | |||||||
|   Boolean mouse; |   Boolean mouse; | ||||||
|   Boolean vertical; |   Boolean vertical; | ||||||
|   Integer zindex; |   Integer zindex; | ||||||
|   Object border; |   Union(ArrayOf(String), Enum("none", "single", "double", "rounded", "solid", "shadow")) border; | ||||||
|   Object title; |   Object title; | ||||||
|   String title_pos; |   Enum("center", "left", "right") title_pos; | ||||||
|   Object footer; |   Object footer; | ||||||
|   String footer_pos; |   Enum("center", "left", "right") footer_pos; | ||||||
|   String style; |   Enum("minimal") style; | ||||||
|   Boolean noautocmd; |   Boolean noautocmd; | ||||||
|   Boolean fixed; |   Boolean fixed; | ||||||
|   Boolean hide; |   Boolean hide; | ||||||
| @@ -244,7 +244,7 @@ typedef struct { | |||||||
| typedef struct { | typedef struct { | ||||||
|   OptionalKeys is_set__create_autocmd_; |   OptionalKeys is_set__create_autocmd_; | ||||||
|   Buffer buffer; |   Buffer buffer; | ||||||
|   Object callback; |   Union(String, LuaRefOf((DictAs(create_autocmd__callback_args) args), *Boolean)) callback; | ||||||
|   String command; |   String command; | ||||||
|   String desc; |   String desc; | ||||||
|   Union(Integer, String) group; |   Union(Integer, String) group; | ||||||
| @@ -279,15 +279,15 @@ typedef struct { | |||||||
| typedef struct { | typedef struct { | ||||||
|   OptionalKeys is_set__cmd_; |   OptionalKeys is_set__cmd_; | ||||||
|   String cmd; |   String cmd; | ||||||
|   Array range; |   ArrayOf(Integer) range; | ||||||
|   Integer count; |   Integer count; | ||||||
|   String reg; |   String reg; | ||||||
|   Boolean bang; |   Boolean bang; | ||||||
|   ArrayOf(String) args; |   ArrayOf(String) args; | ||||||
|   Dict magic; |   DictAs(cmd__magic) magic; | ||||||
|   Dict mods; |   DictAs(cmd__mods) mods; | ||||||
|   Union(Integer, String) nargs; |   Union(Integer, Enum("?", "+", "*")) nargs; | ||||||
|   String addr; |   Enum("line", "arg", "buf", "load", "win", "tab", "qf", "none", "?") addr; | ||||||
|   String nextcmd; |   String nextcmd; | ||||||
| } Dict(cmd); | } Dict(cmd); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -308,7 +308,8 @@ Dict nvim_get_all_options_info(Arena *arena, Error *err) | |||||||
| ///                         Implies {scope} is "local". | ///                         Implies {scope} is "local". | ||||||
| /// @param[out] err Error details, if any | /// @param[out] err Error details, if any | ||||||
| /// @return         Option Information | /// @return         Option Information | ||||||
| Dict nvim_get_option_info2(String name, Dict(option) *opts, Arena *arena, Error *err) | DictAs(get_option_info) nvim_get_option_info2(String name, Dict(option) *opts, Arena *arena, | ||||||
|  |                                               Error *err) | ||||||
|   FUNC_API_SINCE(11) |   FUNC_API_SINCE(11) | ||||||
| { | { | ||||||
|   OptIndex opt_idx = 0; |   OptIndex opt_idx = 0; | ||||||
|   | |||||||
| @@ -18,11 +18,14 @@ | |||||||
| #ifdef INCLUDE_GENERATED_DECLARATIONS | #ifdef INCLUDE_GENERATED_DECLARATIONS | ||||||
| # define ArrayOf(...) Array | # define ArrayOf(...) Array | ||||||
| # define DictOf(...) Dict | # define DictOf(...) Dict | ||||||
|  | # define DictAs(name) Dict | ||||||
| # define Dict(name) KeyDict_##name | # define Dict(name) KeyDict_##name | ||||||
|  | # define Enum(...) String | ||||||
| # define DictHash(name) KeyDict_##name##_get_field | # define DictHash(name) KeyDict_##name##_get_field | ||||||
| # define DictKey(name) | # define DictKey(name) | ||||||
| # define LuaRefOf(...) LuaRef | # define LuaRefOf(...) LuaRef | ||||||
| # define Union(...) Object | # define Union(...) Object | ||||||
|  | # define Tuple(...) Array | ||||||
| # include "api/private/defs.h.inline.generated.h" | # include "api/private/defs.h.inline.generated.h" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|   | |||||||
| @@ -115,7 +115,7 @@ Integer nvim_get_hl_id_by_name(String name) | |||||||
| /// @param[out] err Error details, if any. | /// @param[out] err Error details, if any. | ||||||
| /// @return Highlight groups as a map from group name to a highlight definition map as in |nvim_set_hl()|, | /// @return Highlight groups as a map from group name to a highlight definition map as in |nvim_set_hl()|, | ||||||
| ///                   or only a single highlight definition map if requested by name or id. | ///                   or only a single highlight definition map if requested by name or id. | ||||||
| Dict nvim_get_hl(Integer ns_id, Dict(get_highlight) *opts, Arena *arena, Error *err) | DictAs(get_hl_info) nvim_get_hl(Integer ns_id, Dict(get_highlight) *opts, Arena *arena, Error *err) | ||||||
|   FUNC_API_SINCE(11) |   FUNC_API_SINCE(11) | ||||||
| { | { | ||||||
|   return ns_get_hl_defs((NS)ns_id, opts, arena, err); |   return ns_get_hl_defs((NS)ns_id, opts, arena, err); | ||||||
| @@ -607,7 +607,8 @@ String nvim__get_lib_dir(void) | |||||||
| /// @param all whether to return all matches or only the first | /// @param all whether to return all matches or only the first | ||||||
| /// @param opts is_lua: only search Lua subdirs | /// @param opts is_lua: only search Lua subdirs | ||||||
| /// @return list of absolute paths to the found files | /// @return list of absolute paths to the found files | ||||||
| ArrayOf(String) nvim__get_runtime(Array pat, Boolean all, Dict(runtime) *opts, Arena *arena, | ArrayOf(String) nvim__get_runtime(ArrayOf(String) pat, Boolean all, Dict(runtime) *opts, | ||||||
|  |                                   Arena *arena, | ||||||
|                                   Error *err) |                                   Error *err) | ||||||
|   FUNC_API_SINCE(8) |   FUNC_API_SINCE(8) | ||||||
|   FUNC_API_FAST |   FUNC_API_FAST | ||||||
| @@ -761,7 +762,8 @@ void nvim_set_vvar(String name, Object value, Error *err) | |||||||
| ///          - kind: Set the |ui-messages| kind with which this message will be emitted. | ///          - kind: Set the |ui-messages| kind with which this message will be emitted. | ||||||
| ///          - verbose: Message is controlled by the 'verbose' option. Nvim invoked with `-V3log` | ///          - verbose: Message is controlled by the 'verbose' option. Nvim invoked with `-V3log` | ||||||
| ///            will write the message to the "log" file instead of standard output. | ///            will write the message to the "log" file instead of standard output. | ||||||
| void nvim_echo(Array chunks, Boolean history, Dict(echo_opts) *opts, Error *err) | void nvim_echo(ArrayOf(Tuple(String, HLGroupID)) chunks, Boolean history, Dict(echo_opts) *opts, | ||||||
|  |                Error *err) | ||||||
|   FUNC_API_SINCE(7) |   FUNC_API_SINCE(7) | ||||||
| { | { | ||||||
|   HlMessage hl_msg = parse_hl_msg(chunks, opts->err, err); |   HlMessage hl_msg = parse_hl_msg(chunks, opts->err, err); | ||||||
| @@ -1320,10 +1322,10 @@ Integer nvim_get_color_by_name(String name) | |||||||
| /// (e.g. 65535). | /// (e.g. 65535). | ||||||
| /// | /// | ||||||
| /// @return Map of color names and RGB values. | /// @return Map of color names and RGB values. | ||||||
| Dict nvim_get_color_map(Arena *arena) | DictOf(Integer) nvim_get_color_map(Arena *arena) | ||||||
|   FUNC_API_SINCE(1) |   FUNC_API_SINCE(1) | ||||||
| { | { | ||||||
|   Dict colors = arena_dict(arena, ARRAY_SIZE(color_name_table)); |   DictOf(Integer) colors = arena_dict(arena, ARRAY_SIZE(color_name_table)); | ||||||
|  |  | ||||||
|   for (int i = 0; color_name_table[i].name != NULL; i++) { |   for (int i = 0; color_name_table[i].name != NULL; i++) { | ||||||
|     PUT_C(colors, color_name_table[i].name, INTEGER_OBJ(color_name_table[i].color)); |     PUT_C(colors, color_name_table[i].name, INTEGER_OBJ(color_name_table[i].color)); | ||||||
| @@ -1406,7 +1408,7 @@ Object nvim_load_context(Dict dict, Error *err) | |||||||
| /// "blocking" is true if Nvim is waiting for input. | /// "blocking" is true if Nvim is waiting for input. | ||||||
| /// | /// | ||||||
| /// @returns Dict { "mode": String, "blocking": Boolean } | /// @returns Dict { "mode": String, "blocking": Boolean } | ||||||
| Dict nvim_get_mode(Arena *arena) | DictAs(get_mode) nvim_get_mode(Arena *arena) | ||||||
|   FUNC_API_SINCE(2) FUNC_API_FAST |   FUNC_API_SINCE(2) FUNC_API_FAST | ||||||
| { | { | ||||||
|   Dict rv = arena_dict(arena, 2); |   Dict rv = arena_dict(arena, 2); | ||||||
| @@ -1425,7 +1427,7 @@ Dict nvim_get_mode(Arena *arena) | |||||||
| /// @param  mode       Mode short-name ("n", "i", "v", ...) | /// @param  mode       Mode short-name ("n", "i", "v", ...) | ||||||
| /// @returns Array of |maparg()|-like dictionaries describing mappings. | /// @returns Array of |maparg()|-like dictionaries describing mappings. | ||||||
| ///          The "buffer" key is always zero. | ///          The "buffer" key is always zero. | ||||||
| ArrayOf(Dict) nvim_get_keymap(String mode, Arena *arena) | ArrayOf(DictAs(get_keymap)) nvim_get_keymap(String mode, Arena *arena) | ||||||
|   FUNC_API_SINCE(3) |   FUNC_API_SINCE(3) | ||||||
| { | { | ||||||
|   return keymap_array(mode, NULL, arena); |   return keymap_array(mode, NULL, arena); | ||||||
| @@ -1487,7 +1489,7 @@ void nvim_del_keymap(uint64_t channel_id, String mode, String lhs, Error *err) | |||||||
| /// 1 is the |api-metadata| map (Dict). | /// 1 is the |api-metadata| map (Dict). | ||||||
| /// | /// | ||||||
| /// @returns 2-tuple `[{channel-id}, {api-metadata}]` | /// @returns 2-tuple `[{channel-id}, {api-metadata}]` | ||||||
| Array nvim_get_api_info(uint64_t channel_id, Arena *arena) | ArrayOf(Object, 2) nvim_get_api_info(uint64_t channel_id, Arena *arena) | ||||||
|   FUNC_API_SINCE(1) FUNC_API_FAST FUNC_API_REMOTE_ONLY |   FUNC_API_SINCE(1) FUNC_API_FAST FUNC_API_REMOTE_ONLY | ||||||
| { | { | ||||||
|   Array rv = arena_array(arena, 2); |   Array rv = arena_array(arena, 2); | ||||||
| @@ -1624,7 +1626,7 @@ Dict nvim_get_chan_info(uint64_t channel_id, Integer chan, Arena *arena, Error * | |||||||
| /// | /// | ||||||
| /// @returns Array of Dictionaries, each describing a channel with | /// @returns Array of Dictionaries, each describing a channel with | ||||||
| ///          the format specified at |nvim_get_chan_info()|. | ///          the format specified at |nvim_get_chan_info()|. | ||||||
| Array nvim_list_chans(Arena *arena) | ArrayOf(Dict) nvim_list_chans(Arena *arena) | ||||||
|   FUNC_API_SINCE(4) |   FUNC_API_SINCE(4) | ||||||
| { | { | ||||||
|   return channel_all_info(arena); |   return channel_all_info(arena); | ||||||
| @@ -1715,7 +1717,7 @@ Dict nvim__stats(Arena *arena) | |||||||
| ///   - "rgb"     true if the UI uses RGB colors (false implies |cterm-colors|) | ///   - "rgb"     true if the UI uses RGB colors (false implies |cterm-colors|) | ||||||
| ///   - "ext_..." Requested UI extensions, see |ui-option| | ///   - "ext_..." Requested UI extensions, see |ui-option| | ||||||
| ///   - "chan"    |channel-id| of remote UI | ///   - "chan"    |channel-id| of remote UI | ||||||
| Array nvim_list_uis(Arena *arena) | ArrayOf(Dict) nvim_list_uis(Arena *arena) | ||||||
|   FUNC_API_SINCE(4) |   FUNC_API_SINCE(4) | ||||||
| { | { | ||||||
|   return ui_array(arena); |   return ui_array(arena); | ||||||
| @@ -1916,7 +1918,8 @@ Boolean nvim_del_mark(String name, Error *err) | |||||||
| /// not set. | /// not set. | ||||||
| /// @see |nvim_buf_set_mark()| | /// @see |nvim_buf_set_mark()| | ||||||
| /// @see |nvim_del_mark()| | /// @see |nvim_del_mark()| | ||||||
| Array nvim_get_mark(String name, Dict(empty) *opts, Arena *arena, Error *err) | Tuple(Integer, Integer, Buffer, String) nvim_get_mark(String name, Dict(empty) *opts, Arena *arena, | ||||||
|  |                                                       Error *err) | ||||||
|   FUNC_API_SINCE(8) |   FUNC_API_SINCE(8) | ||||||
| { | { | ||||||
|   Array rv = ARRAY_DICT_INIT; |   Array rv = ARRAY_DICT_INIT; | ||||||
| @@ -2001,7 +2004,8 @@ Array nvim_get_mark(String name, Dict(empty) *opts, Arena *arena, Error *err) | |||||||
| ///           - start: (number) Byte index (0-based) of first character that uses the highlight. | ///           - start: (number) Byte index (0-based) of first character that uses the highlight. | ||||||
| ///           - group: (string) Deprecated. Use `groups` instead. | ///           - group: (string) Deprecated. Use `groups` instead. | ||||||
| ///           - groups: (array) Names of stacked highlight groups (highest priority last). | ///           - groups: (array) Names of stacked highlight groups (highest priority last). | ||||||
| Dict nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Arena *arena, Error *err) | DictAs(eval_statusline_ret) nvim_eval_statusline(String str, Dict(eval_statusline) *opts, | ||||||
|  |                                                  Arena *arena, Error *err) | ||||||
|   FUNC_API_SINCE(8) FUNC_API_FAST |   FUNC_API_SINCE(8) FUNC_API_FAST | ||||||
| { | { | ||||||
|   Dict result = ARRAY_DICT_INIT; |   Dict result = ARRAY_DICT_INIT; | ||||||
| @@ -2188,7 +2192,7 @@ void nvim_error_event(uint64_t channel_id, Integer lvl, String data) | |||||||
| /// @return Dict containing these keys: | /// @return Dict containing these keys: | ||||||
| ///       - winid: (number) floating window id | ///       - winid: (number) floating window id | ||||||
| ///       - bufnr: (number) buffer id in floating window | ///       - bufnr: (number) buffer id in floating window | ||||||
| Dict nvim__complete_set(Integer index, Dict(complete_set) *opts, Arena *arena, Error *err) | DictOf(Float) nvim__complete_set(Integer index, Dict(complete_set) *opts, Arena *arena, Error *err) | ||||||
| { | { | ||||||
|   Dict rv = arena_dict(arena, 2); |   Dict rv = arena_dict(arena, 2); | ||||||
|   if ((get_cot_flags() & kOptCotFlagPopup) == 0) { |   if ((get_cot_flags() & kOptCotFlagPopup) == 0) { | ||||||
|   | |||||||
| @@ -500,7 +500,8 @@ void nvim_win_set_hl_ns(Window window, Integer ns_id, Error *err) | |||||||
| ///            height is reached. 0 if "end_row" is a closed fold. | ///            height is reached. 0 if "end_row" is a closed fold. | ||||||
| /// | /// | ||||||
| /// @see |virtcol()| for text width. | /// @see |virtcol()| for text width. | ||||||
| Dict nvim_win_text_height(Window window, Dict(win_text_height) *opts, Arena *arena, Error *err) | DictAs(win_text_height_ret) nvim_win_text_height(Window window, Dict(win_text_height) *opts, | ||||||
|  |                                                  Arena *arena, Error *err) | ||||||
|   FUNC_API_SINCE(12) |   FUNC_API_SINCE(12) | ||||||
| { | { | ||||||
|   Dict rv = arena_dict(arena, 2); |   Dict rv = arena_dict(arena, 2); | ||||||
|   | |||||||
| @@ -63,12 +63,14 @@ describe('api metadata', function() | |||||||
|     -- Dictionary was renamed to Dict. That doesn't break back-compat because clients don't actually |     -- Dictionary was renamed to Dict. That doesn't break back-compat because clients don't actually | ||||||
|     -- use the `return_type` field (evidence: "ArrayOf(…)" didn't break clients). |     -- use the `return_type` field (evidence: "ArrayOf(…)" didn't break clients). | ||||||
|     f.return_type = f.return_type:gsub('Dictionary', 'Dict') |     f.return_type = f.return_type:gsub('Dictionary', 'Dict') | ||||||
|  |     f.return_type = f.return_type:gsub('^ArrayOf%(.*', 'Array') | ||||||
|  |  | ||||||
|     f.deprecated_since = nil |     f.deprecated_since = nil | ||||||
|     for idx, _ in ipairs(f.parameters) do |     for idx, _ in ipairs(f.parameters) do | ||||||
|       -- Dictionary was renamed to Dict. Doesn't break back-compat because clients don't actually |       -- Dictionary was renamed to Dict. Doesn't break back-compat because clients don't actually | ||||||
|       -- use the `parameters` field of API metadata (evidence: "ArrayOf(…)" didn't break clients). |       -- use the `parameters` field of API metadata (evidence: "ArrayOf(…)" didn't break clients). | ||||||
|       f.parameters[idx][1] = f.parameters[idx][1]:gsub('Dictionary', 'Dict') |       f.parameters[idx][1] = f.parameters[idx][1]:gsub('Dictionary', 'Dict') | ||||||
|  |       f.parameters[idx][1] = f.parameters[idx][1]:gsub('ArrayOf%(.*', 'Array') | ||||||
|  |  | ||||||
|       f.parameters[idx][2] = '' -- Remove parameter name. |       f.parameters[idx][2] = '' -- Remove parameter name. | ||||||
|     end |     end | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user