mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #4817 from bfredl/remoteui
api: refactor remote ui to use API dispatch generation
This commit is contained in:
commit
f5642a171f
@ -143,7 +143,7 @@ local pattern = concat(
|
||||
lit(')'),
|
||||
any_amount(concat( -- optional attributes
|
||||
spaces,
|
||||
lit('FUNC_ATTR_'),
|
||||
lit('FUNC_'),
|
||||
any_amount(aw),
|
||||
one_or_no(concat( -- attribute argument
|
||||
spaces,
|
||||
|
@ -35,7 +35,8 @@ c_proto = Ct(
|
||||
Cg(c_type, 'return_type') * Cg(c_id, 'name') *
|
||||
fill * P('(') * fill * Cg(c_params, 'parameters') * fill * P(')') *
|
||||
Cg(Cc(false), 'async') *
|
||||
(fill * Cg((P('FUNC_ATTR_ASYNC') * Cc(true)), 'async') ^ -1) *
|
||||
(fill * Cg((P('FUNC_API_ASYNC') * Cc(true)), 'async') ^ -1) *
|
||||
(fill * Cg((P('FUNC_API_NOEXPORT') * Cc(true)), 'noexport') ^ -1) *
|
||||
fill * P(';')
|
||||
)
|
||||
grammar = Ct((c_proto + c_comment + c_preproc + ws) ^ 1)
|
||||
@ -62,8 +63,11 @@ for i = 1, #arg - 1 do
|
||||
local input = io.open(full_path, 'rb')
|
||||
local tmp = grammar:match(input:read('*all'))
|
||||
for i = 1, #tmp do
|
||||
functions[#functions + 1] = tmp[i]
|
||||
local fn = tmp[i]
|
||||
if fn.noexport then
|
||||
goto continue
|
||||
end
|
||||
functions[#functions + 1] = tmp[i]
|
||||
if #fn.parameters ~= 0 and fn.parameters[1][2] == 'channel_id' then
|
||||
-- this function should receive the channel id
|
||||
fn.receives_channel_id = true
|
||||
@ -77,6 +81,7 @@ for i = 1, #arg - 1 do
|
||||
-- for specifying errors
|
||||
fn.parameters[#fn.parameters] = nil
|
||||
end
|
||||
::continue::
|
||||
end
|
||||
input:close()
|
||||
end
|
||||
@ -217,7 +222,7 @@ for i = 1, #functions do
|
||||
|
||||
if fn.receives_channel_id then
|
||||
-- if the function receives the channel id, pass it as first argument
|
||||
if #args > 0 then
|
||||
if #args > 0 or fn.can_fail then
|
||||
output:write('channel_id, '..call_args)
|
||||
else
|
||||
output:write('channel_id')
|
||||
|
@ -7,13 +7,12 @@
|
||||
#include "nvim/ui.h"
|
||||
#include "nvim/memory.h"
|
||||
#include "nvim/map.h"
|
||||
#include "nvim/msgpack_rpc/remote_ui.h"
|
||||
#include "nvim/msgpack_rpc/channel.h"
|
||||
#include "nvim/api/private/defs.h"
|
||||
#include "nvim/api/private/helpers.h"
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "msgpack_rpc/remote_ui.c.generated.h"
|
||||
# include "api/ui.c.generated.h"
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
@ -24,21 +23,13 @@ typedef struct {
|
||||
static PMap(uint64_t) *connected_uis = NULL;
|
||||
|
||||
void remote_ui_init(void)
|
||||
FUNC_API_NOEXPORT
|
||||
{
|
||||
connected_uis = pmap_new(uint64_t)();
|
||||
// Add handler for "attach_ui"
|
||||
String method = cstr_as_string("ui_attach");
|
||||
MsgpackRpcRequestHandler handler = {.fn = remote_ui_attach, .async = false};
|
||||
msgpack_rpc_add_method_handler(method, handler);
|
||||
method = cstr_as_string("ui_detach");
|
||||
handler.fn = remote_ui_detach;
|
||||
msgpack_rpc_add_method_handler(method, handler);
|
||||
method = cstr_as_string("ui_try_resize");
|
||||
handler.fn = remote_ui_try_resize;
|
||||
msgpack_rpc_add_method_handler(method, handler);
|
||||
}
|
||||
|
||||
void remote_ui_disconnect(uint64_t channel_id)
|
||||
FUNC_API_NOEXPORT
|
||||
{
|
||||
UI *ui = pmap_get(uint64_t)(connected_uis, channel_id);
|
||||
if (!ui) {
|
||||
@ -49,34 +40,30 @@ void remote_ui_disconnect(uint64_t channel_id)
|
||||
api_free_array(data->buffer);
|
||||
pmap_del(uint64_t)(connected_uis, channel_id);
|
||||
xfree(ui->data);
|
||||
ui_detach(ui);
|
||||
ui_detach_impl(ui);
|
||||
xfree(ui);
|
||||
}
|
||||
|
||||
static Object remote_ui_attach(uint64_t channel_id, uint64_t request_id,
|
||||
Array args, Error *error)
|
||||
void ui_attach(uint64_t channel_id, Integer width, Integer height,
|
||||
Boolean enable_rgb, Error *err)
|
||||
{
|
||||
if (pmap_has(uint64_t)(connected_uis, channel_id)) {
|
||||
api_set_error(error, Exception, _("UI already attached for channel"));
|
||||
return NIL;
|
||||
api_set_error(err, Exception, _("UI already attached for channel"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.size != 3 || args.items[0].type != kObjectTypeInteger
|
||||
|| args.items[1].type != kObjectTypeInteger
|
||||
|| args.items[2].type != kObjectTypeBoolean
|
||||
|| args.items[0].data.integer <= 0 || args.items[1].data.integer <= 0) {
|
||||
api_set_error(error, Validation,
|
||||
_("Invalid arguments. Expected: "
|
||||
"(uint width > 0, uint height > 0, bool enable_rgb)"));
|
||||
return NIL;
|
||||
if (width <= 0 || height <= 0) {
|
||||
api_set_error(err, Validation,
|
||||
_("Expected width > 0 and height > 0"));
|
||||
return;
|
||||
}
|
||||
UIData *data = xmalloc(sizeof(UIData));
|
||||
data->channel_id = channel_id;
|
||||
data->buffer = (Array)ARRAY_DICT_INIT;
|
||||
UI *ui = xcalloc(1, sizeof(UI));
|
||||
ui->width = (int)args.items[0].data.integer;
|
||||
ui->height = (int)args.items[1].data.integer;
|
||||
ui->rgb = args.items[2].data.boolean;
|
||||
ui->width = (int)width;
|
||||
ui->height = (int)height;
|
||||
ui->rgb = enable_rgb;
|
||||
ui->data = data;
|
||||
ui->resize = remote_ui_resize;
|
||||
ui->clear = remote_ui_clear;
|
||||
@ -102,45 +89,38 @@ static Object remote_ui_attach(uint64_t channel_id, uint64_t request_id,
|
||||
ui->set_title = remote_ui_set_title;
|
||||
ui->set_icon = remote_ui_set_icon;
|
||||
pmap_put(uint64_t)(connected_uis, channel_id, ui);
|
||||
ui_attach(ui);
|
||||
return NIL;
|
||||
ui_attach_impl(ui);
|
||||
return;
|
||||
}
|
||||
|
||||
static Object remote_ui_detach(uint64_t channel_id, uint64_t request_id,
|
||||
Array args, Error *error)
|
||||
void ui_detach(uint64_t channel_id, Error *err)
|
||||
{
|
||||
if (!pmap_has(uint64_t)(connected_uis, channel_id)) {
|
||||
api_set_error(error, Exception, _("UI is not attached for channel"));
|
||||
api_set_error(err, Exception, _("UI is not attached for channel"));
|
||||
}
|
||||
remote_ui_disconnect(channel_id);
|
||||
|
||||
return NIL;
|
||||
}
|
||||
|
||||
static Object remote_ui_try_resize(uint64_t channel_id, uint64_t request_id,
|
||||
Array args, Error *error)
|
||||
Object ui_try_resize(uint64_t channel_id, Integer width,
|
||||
Integer height, Error *err)
|
||||
{
|
||||
if (!pmap_has(uint64_t)(connected_uis, channel_id)) {
|
||||
api_set_error(error, Exception, _("UI is not attached for channel"));
|
||||
api_set_error(err, Exception, _("UI is not attached for channel"));
|
||||
}
|
||||
|
||||
if (args.size != 2 || args.items[0].type != kObjectTypeInteger
|
||||
|| args.items[1].type != kObjectTypeInteger
|
||||
|| args.items[0].data.integer <= 0 || args.items[1].data.integer <= 0) {
|
||||
api_set_error(error, Validation,
|
||||
_("Invalid arguments. Expected: "
|
||||
"(uint width > 0, uint height > 0)"));
|
||||
if (width <= 0 || height <= 0) {
|
||||
api_set_error(err, Validation,
|
||||
_("Expected width > 0 and height > 0"));
|
||||
return NIL;
|
||||
}
|
||||
|
||||
UI *ui = pmap_get(uint64_t)(connected_uis, channel_id);
|
||||
ui->width = (int)args.items[0].data.integer;
|
||||
ui->height = (int)args.items[1].data.integer;
|
||||
ui->width = (int)width;
|
||||
ui->height = (int)height;
|
||||
ui_refresh();
|
||||
return NIL;
|
||||
}
|
||||
|
||||
|
||||
static void push_call(UI *ui, char *name, Array args)
|
||||
{
|
||||
Array call = ARRAY_DICT_INIT;
|
||||
@ -297,7 +277,7 @@ static void remote_ui_highlight_set(UI *ui, HlAttrs attrs)
|
||||
static void remote_ui_put(UI *ui, uint8_t *data, size_t size)
|
||||
{
|
||||
Array args = ARRAY_DICT_INIT;
|
||||
String str = {.data = xmemdupz(data, size), .size = size};
|
||||
String str = { .data = xmemdupz(data, size), .size = size };
|
||||
ADD(args, STRING_OBJ(str));
|
||||
push_call(ui, "put", args);
|
||||
}
|
11
src/nvim/api/ui.h
Normal file
11
src/nvim/api/ui.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef NVIM_API_UI_H
|
||||
#define NVIM_API_UI_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "nvim/api/private/defs.h"
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "api/ui.h.generated.h"
|
||||
#endif
|
||||
#endif // NVIM_API_UI_H
|
@ -98,7 +98,7 @@ void vim_feedkeys(String keys, String mode, Boolean escape_csi)
|
||||
/// @return The number of bytes actually written, which can be lower than
|
||||
/// requested if the buffer becomes full.
|
||||
Integer vim_input(String keys)
|
||||
FUNC_ATTR_ASYNC
|
||||
FUNC_API_ASYNC
|
||||
{
|
||||
return (Integer)input_enqueue(keys);
|
||||
}
|
||||
@ -618,7 +618,7 @@ Dictionary vim_get_color_map(void)
|
||||
|
||||
|
||||
Array vim_get_api_info(uint64_t channel_id)
|
||||
FUNC_ATTR_ASYNC
|
||||
FUNC_API_ASYNC
|
||||
{
|
||||
Array rv = ARRAY_DICT_INIT;
|
||||
|
||||
|
@ -179,7 +179,8 @@
|
||||
#endif
|
||||
|
||||
#ifdef DEFINE_FUNC_ATTRIBUTES
|
||||
#define FUNC_ATTR_ASYNC
|
||||
#define FUNC_API_ASYNC
|
||||
#define FUNC_API_NOEXPORT
|
||||
#define FUNC_ATTR_MALLOC REAL_FATTR_MALLOC
|
||||
#define FUNC_ATTR_ALLOC_SIZE(x) REAL_FATTR_ALLOC_SIZE(x)
|
||||
#define FUNC_ATTR_ALLOC_SIZE_PROD(x,y) REAL_FATTR_ALLOC_SIZE_PROD(x,y)
|
||||
|
@ -7,8 +7,8 @@
|
||||
|
||||
#include "nvim/api/private/helpers.h"
|
||||
#include "nvim/api/vim.h"
|
||||
#include "nvim/api/ui.h"
|
||||
#include "nvim/msgpack_rpc/channel.h"
|
||||
#include "nvim/msgpack_rpc/remote_ui.h"
|
||||
#include "nvim/event/loop.h"
|
||||
#include "nvim/event/libuv_process.h"
|
||||
#include "nvim/event/rstream.h"
|
||||
|
@ -1,9 +0,0 @@
|
||||
#ifndef NVIM_MSGPACK_RPC_REMOTE_UI_H
|
||||
#define NVIM_MSGPACK_RPC_REMOTE_UI_H
|
||||
|
||||
#include "nvim/ui.h"
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "msgpack_rpc/remote_ui.h.generated.h"
|
||||
#endif
|
||||
#endif // NVIM_MSGPACK_RPC_REMOTE_UI_H
|
@ -207,7 +207,7 @@ void ui_mouse_off(void)
|
||||
UI_CALL(mouse_off);
|
||||
}
|
||||
|
||||
void ui_attach(UI *ui)
|
||||
void ui_attach_impl(UI *ui)
|
||||
{
|
||||
if (ui_count == MAX_UI_COUNT) {
|
||||
abort();
|
||||
@ -217,7 +217,7 @@ void ui_attach(UI *ui)
|
||||
ui_refresh();
|
||||
}
|
||||
|
||||
void ui_detach(UI *ui)
|
||||
void ui_detach_impl(UI *ui)
|
||||
{
|
||||
size_t shift_index = MAX_UI_COUNT;
|
||||
|
||||
|
@ -71,7 +71,7 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)
|
||||
}
|
||||
uv_mutex_unlock(&rv->mutex);
|
||||
|
||||
ui_attach(&rv->bridge);
|
||||
ui_attach_impl(&rv->bridge);
|
||||
return &rv->bridge;
|
||||
}
|
||||
|
||||
@ -105,7 +105,7 @@ static void ui_bridge_stop(UI *b)
|
||||
uv_thread_join(&bridge->ui_thread);
|
||||
uv_mutex_destroy(&bridge->mutex);
|
||||
uv_cond_destroy(&bridge->cond);
|
||||
ui_detach(b);
|
||||
ui_detach_impl(b);
|
||||
xfree(b);
|
||||
}
|
||||
static void ui_bridge_stop_event(void **argv)
|
||||
|
Loading…
Reference in New Issue
Block a user