api: consistently use nvim_ prefix and update documentation

This commit is contained in:
Björn Linse
2016-06-28 21:45:19 +02:00
parent e536abc1e1
commit 1c22cab2fd
20 changed files with 491 additions and 347 deletions

View File

@@ -0,0 +1,77 @@
local deprecated_aliases = {
nvim_buf_line_count="buffer_line_count",
nvim_buf_get_lines="buffer_get_lines",
nvim_buf_set_lines="buffer_set_lines",
nvim_buf_get_var="buffer_get_var",
nvim_buf_set_var="buffer_set_var",
nvim_buf_del_var="buffer_del_var",
nvim_buf_get_option="buffer_get_option",
nvim_buf_set_option="buffer_set_option",
nvim_buf_get_number="buffer_get_number",
nvim_buf_get_name="buffer_get_name",
nvim_buf_set_name="buffer_set_name",
nvim_buf_is_valid="buffer_is_valid",
nvim_buf_get_mark="buffer_get_mark",
nvim_buf_add_highlight="buffer_add_highlight",
nvim_buf_clear_highlight="buffer_clear_highlight",
nvim_tabpage_get_windows="tabpage_get_windows",
nvim_tabpage_get_var="tabpage_get_var",
nvim_tabpage_set_var="tabpage_set_var",
nvim_tabpage_del_var="tabpage_del_var",
nvim_tabpage_get_window="tabpage_get_window",
nvim_tabpage_is_valid="tabpage_is_valid",
nvim_ui_detach="ui_detach",
nvim_ui_try_resize="ui_try_resize",
nvim_command="vim_command",
nvim_feedkeys="vim_feedkeys",
nvim_input="vim_input",
nvim_replace_termcodes="vim_replace_termcodes",
nvim_command_output="vim_command_output",
nvim_eval="vim_eval",
nvim_call_function="vim_call_function",
nvim_strwidth="vim_strwidth",
nvim_list_runtime_paths="vim_list_runtime_paths",
nvim_change_directory="vim_change_directory",
nvim_get_var="vim_get_var",
nvim_set_var="vim_set_var",
nvim_del_var="vim_del_var",
nvim_get_vvar="vim_get_vvar",
nvim_get_option="vim_get_option",
nvim_set_option="vim_set_option",
nvim_out_write="vim_out_write",
nvim_err_write="vim_err_write",
nvim_report_error="vim_report_error",
nvim_get_buffers="vim_get_buffers",
nvim_get_current_buffer="vim_get_current_buffer",
nvim_set_current_buffer="vim_set_current_buffer",
nvim_get_windows="vim_get_windows",
nvim_get_current_window="vim_get_current_window",
nvim_set_current_window="vim_set_current_window",
nvim_get_tabpages="vim_get_tabpages",
nvim_get_current_tabpage="vim_get_current_tabpage",
nvim_set_current_tabpage="vim_set_current_tabpage",
nvim_set_current_line="vim_set_current_line",
nvim_get_current_line="vim_get_current_line",
nvim_del_current_line="vim_del_current_line",
nvim_subscribe="vim_subscribe",
nvim_unsubscribe="vim_unsubscribe",
nvim_name_to_color="vim_name_to_color",
nvim_get_color_map="vim_get_color_map",
nvim_get_api_info="vim_get_api_info",
nvim_win_get_buffer="window_get_buffer",
nvim_win_get_cursor="window_get_cursor",
nvim_win_set_cursor="window_set_cursor",
nvim_win_get_height="window_get_height",
nvim_win_set_height="window_set_height",
nvim_win_get_width="window_get_width",
nvim_win_set_width="window_set_width",
nvim_win_get_var="window_get_var",
nvim_win_set_var="window_set_var",
nvim_win_del_var="window_del_var",
nvim_win_get_option="window_get_option",
nvim_win_set_option="window_set_option",
nvim_win_get_position="window_get_position",
nvim_win_get_tabpage="window_get_tabpage",
nvim_win_is_valid="window_is_valid"
}
return deprecated_aliases

View File

@@ -42,10 +42,13 @@ c_proto = Ct(
)
grammar = Ct((c_proto + c_comment + c_preproc + ws) ^ 1)
-- we need at least 3 arguments since the last two are output files
assert(#arg >= 2)
-- we need at least 4 arguments since the last two are output files
assert(#arg >= 3)
functions = {}
local scriptdir = arg[1]
package.path = scriptdir .. '/?.lua;' .. package.path
-- names of all headers relative to the source root (for inclusion in the
-- generated file)
headers = {}
@@ -55,7 +58,7 @@ outputf = arg[#arg-1]
mpack_outputf = arg[#arg]
-- read each input file, parse and append to the api metadata
for i = 1, #arg - 2 do
for i = 2, #arg - 2 do
local full_path = arg[i]
local parts = {}
for part in string.gmatch(full_path, '[^/]+') do
@@ -87,6 +90,45 @@ for i = 1, #arg - 2 do
input:close()
end
local function shallowcopy(orig)
local copy = {}
for orig_key, orig_value in pairs(orig) do
copy[orig_key] = orig_value
end
return copy
end
local function startswith(String,Start)
return string.sub(String,1,string.len(Start))==Start
end
-- Export functions under older deprecated names.
-- These will be removed eventually.
local deprecated_aliases = require("dispatch_deprecated")
for i,f in ipairs(shallowcopy(functions)) do
local ismethod = false
if startswith(f.name, "nvim_buf_") then
ismethod = true
elseif startswith(f.name, "nvim_win_") then
ismethod = true
elseif startswith(f.name, "nvim_tabpage_") then
ismethod = true
elseif not startswith(f.name, "nvim_") then
f.noeval = true
f.deprecated_since = 1
end
f.method = ismethod
local newname = deprecated_aliases[f.name]
if newname ~= nil then
local newf = shallowcopy(f)
newf.name = newname
newf.impl_name = f.name
newf.noeval = true
newf.deprecated_since = 1
functions[#functions+1] = newf
end
end
-- start building the output
output = io.open(outputf, 'wb')
@@ -166,99 +208,101 @@ end
-- the real API.
for i = 1, #functions do
local fn = functions[i]
local args = {}
if fn.impl_name == nil then
local args = {}
output:write('Object handle_'..fn.name..'(uint64_t channel_id, uint64_t request_id, Array args, Error *error)')
output:write('\n{')
output:write('\n Object ret = NIL;')
-- Declare/initialize variables that will hold converted arguments
for j = 1, #fn.parameters do
local param = fn.parameters[j]
local converted = 'arg_'..j
output:write('\n '..param[1]..' '..converted..' api_init_'..string.lower(real_type(param[1]))..';')
end
output:write('\n')
output:write('\n if (args.size != '..#fn.parameters..') {')
output:write('\n snprintf(error->msg, sizeof(error->msg), "Wrong number of arguments: expecting '..#fn.parameters..' but got %zu", args.size);')
output:write('\n error->set = true;')
output:write('\n goto cleanup;')
output:write('\n }\n')
output:write('Object handle_'..fn.name..'(uint64_t channel_id, uint64_t request_id, Array args, Error *error)')
output:write('\n{')
output:write('\n Object ret = NIL;')
-- Declare/initialize variables that will hold converted arguments
for j = 1, #fn.parameters do
local param = fn.parameters[j]
local converted = 'arg_'..j
output:write('\n '..param[1]..' '..converted..' api_init_'..string.lower(real_type(param[1]))..';')
end
output:write('\n')
output:write('\n if (args.size != '..#fn.parameters..') {')
output:write('\n snprintf(error->msg, sizeof(error->msg), "Wrong number of arguments: expecting '..#fn.parameters..' but got %zu", args.size);')
output:write('\n error->set = true;')
output:write('\n goto cleanup;')
output:write('\n }\n')
-- Validation/conversion for each argument
for j = 1, #fn.parameters do
local converted, convert_arg, param, arg
param = fn.parameters[j]
converted = 'arg_'..j
local rt = real_type(param[1])
if rt ~= 'Object' then
output:write('\n if (args.items['..(j - 1)..'].type == kObjectType'..rt..') {')
output:write('\n '..converted..' = args.items['..(j - 1)..'].data.'..rt:lower()..';')
if rt:match('^Buffer$') or rt:match('^Window$') or rt:match('^Tabpage$') or rt:match('^Boolean$') then
-- accept nonnegative integers for Booleans, Buffers, Windows and Tabpages
output:write('\n } else if (args.items['..(j - 1)..'].type == kObjectTypeInteger && args.items['..(j - 1)..'].data.integer >= 0) {')
output:write('\n '..converted..' = (handle_T)args.items['..(j - 1)..'].data.integer;')
-- Validation/conversion for each argument
for j = 1, #fn.parameters do
local converted, convert_arg, param, arg
param = fn.parameters[j]
converted = 'arg_'..j
local rt = real_type(param[1])
if rt ~= 'Object' then
output:write('\n if (args.items['..(j - 1)..'].type == kObjectType'..rt..') {')
output:write('\n '..converted..' = args.items['..(j - 1)..'].data.'..rt:lower()..';')
if rt:match('^Buffer$') or rt:match('^Window$') or rt:match('^Tabpage$') or rt:match('^Boolean$') then
-- accept nonnegative integers for Booleans, Buffers, Windows and Tabpages
output:write('\n } else if (args.items['..(j - 1)..'].type == kObjectTypeInteger && args.items['..(j - 1)..'].data.integer >= 0) {')
output:write('\n '..converted..' = (handle_T)args.items['..(j - 1)..'].data.integer;')
end
output:write('\n } else {')
output:write('\n snprintf(error->msg, sizeof(error->msg), "Wrong type for argument '..j..', expecting '..param[1]..'");')
output:write('\n error->set = true;')
output:write('\n goto cleanup;')
output:write('\n }\n')
else
output:write('\n '..converted..' = args.items['..(j - 1)..'];\n')
end
output:write('\n } else {')
output:write('\n snprintf(error->msg, sizeof(error->msg), "Wrong type for argument '..j..', expecting '..param[1]..'");')
output:write('\n error->set = true;')
args[#args + 1] = converted
end
-- function call
local call_args = table.concat(args, ', ')
output:write('\n ')
if fn.return_type ~= 'void' then
-- has a return value, prefix the call with a declaration
output:write(fn.return_type..' rv = ')
end
-- write the function name and the opening parenthesis
output:write(fn.name..'(')
if fn.receives_channel_id then
-- if the function receives the channel id, pass it as first argument
if #args > 0 or fn.can_fail then
output:write('channel_id, '..call_args)
else
output:write('channel_id')
end
else
output:write(call_args)
end
if fn.can_fail then
-- if the function can fail, also pass a pointer to the local error object
if #args > 0 then
output:write(', error);\n')
else
output:write('error);\n')
end
-- and check for the error
output:write('\n if (error->set) {')
output:write('\n goto cleanup;')
output:write('\n }\n')
else
output:write('\n '..converted..' = args.items['..(j - 1)..'];\n')
output:write(');\n')
end
args[#args + 1] = converted
end
-- function call
local call_args = table.concat(args, ', ')
output:write('\n ')
if fn.return_type ~= 'void' then
-- has a return value, prefix the call with a declaration
output:write(fn.return_type..' rv = ')
end
-- write the function name and the opening parenthesis
output:write(fn.name..'(')
if fn.receives_channel_id then
-- if the function receives the channel id, pass it as first argument
if #args > 0 or fn.can_fail then
output:write('channel_id, '..call_args)
else
output:write('channel_id')
if fn.return_type ~= 'void' then
output:write('\n ret = '..string.upper(real_type(fn.return_type))..'_OBJ(rv);')
end
else
output:write(call_args)
end
-- Now generate the cleanup label for freeing memory allocated for the
-- arguments
output:write('\n\ncleanup:');
if fn.can_fail then
-- if the function can fail, also pass a pointer to the local error object
if #args > 0 then
output:write(', error);\n')
else
output:write('error);\n')
for j = 1, #fn.parameters do
local param = fn.parameters[j]
output:write('\n api_free_'..string.lower(real_type(param[1]))..'(arg_'..j..');')
end
-- and check for the error
output:write('\n if (error->set) {')
output:write('\n goto cleanup;')
output:write('\n }\n')
else
output:write(');\n')
output:write('\n return ret;\n}\n\n');
end
if fn.return_type ~= 'void' then
output:write('\n ret = '..string.upper(real_type(fn.return_type))..'_OBJ(rv);')
end
-- Now generate the cleanup label for freeing memory allocated for the
-- arguments
output:write('\n\ncleanup:');
for j = 1, #fn.parameters do
local param = fn.parameters[j]
output:write('\n api_free_'..string.lower(real_type(param[1]))..'(arg_'..j..');')
end
output:write('\n return ret;\n}\n\n');
end
-- Generate a function that initializes method names with handler functions
@@ -284,7 +328,7 @@ for i = 1, #functions do
output:write(' msgpack_rpc_add_method_handler('..
'(String) {.data = "'..fn.name..'", '..
'.size = sizeof("'..fn.name..'") - 1}, '..
'(MsgpackRpcRequestHandler) {.fn = handle_'.. fn.name..
'(MsgpackRpcRequestHandler) {.fn = handle_'.. (fn.impl_name or fn.name)..
', .async = '..tostring(fn.async)..'});\n')
if #fn.name > max_fname_len then

View File

@@ -26,7 +26,7 @@ local funcs = require('eval').funcs
local metadata = mpack.unpack(io.open(arg[3], 'rb'):read("*all"))
for i,fun in ipairs(metadata) do
if not fun.noeval then
funcs['api_'..fun.name] = {
funcs[fun.name] = {
args=#fun.parameters,
func='api_wrapper',
data='&handle_'..fun.name,