Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 6bba09b

Browse files
committed
rpc/events: allow handling of nvim_ui_try_resize at the pager
1 parent 411341f commit 6bba09b

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

src/nvim/event/multiqueue.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,13 @@ struct multiqueue {
7878
size_t size;
7979
};
8080

81+
typedef struct {
82+
Event event;
83+
bool fired;
84+
int refcount;
85+
} SplitEvent;
86+
87+
8188
#ifdef INCLUDE_GENERATED_DECLARATIONS
8289
# include "event/multiqueue.c.generated.h"
8390
#endif
@@ -245,3 +252,34 @@ static MultiQueueItem *multiqueue_node_data(QUEUE *q)
245252
{
246253
return QUEUE_DATA(q, MultiQueueItem, node);
247254
}
255+
256+
/// Allow an event to be processed by multiple child queues to the main queue
257+
///
258+
/// The handler will be fired once by the _first_ queue that processes the
259+
/// event. Later processing will do nothing (just memory cleanup).
260+
///
261+
/// @param ev the event
262+
/// @param num number of queues that the split event will be put on
263+
/// @return an Event that is safe to put onto `num` queues
264+
Event event_split(Event ev, int num)
265+
{
266+
SplitEvent *data = xmalloc(sizeof(*data));
267+
data->event = ev;
268+
data->fired = false;
269+
data->refcount = num;
270+
return event_create(split_event, 1, data);
271+
}
272+
static void split_event(void ** argv)
273+
{
274+
SplitEvent *data = argv[0];
275+
if (!data->fired) {
276+
data->fired = true;
277+
if (data->event.handler) {
278+
data->event.handler(data->event.argv);
279+
}
280+
}
281+
if ((--data->refcount) == 0) {
282+
xfree(data);
283+
}
284+
}
285+

src/nvim/msgpack_rpc/channel.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "nvim/misc1.h"
3232
#include "nvim/lib/kvec.h"
3333
#include "nvim/os/input.h"
34+
#include "nvim/ui.h"
3435

3536
#if MIN_LOG_LEVEL > DEBUG_LOG_LEVEL
3637
#define log_client_msg(...)
@@ -289,6 +290,7 @@ static void parse_msgpack(Channel *channel)
289290
}
290291
}
291292

293+
292294
/// Handles requests and notifications received on the channel.
293295
static void handle_request(Channel *channel, msgpack_object *request)
294296
FUNC_ATTR_NONNULL_ALL
@@ -355,11 +357,19 @@ static void handle_request(Channel *channel, msgpack_object *request)
355357
request_event((void **)&evdata);
356358
}
357359
} else {
358-
multiqueue_put(channel->events, request_event, 1, evdata);
359-
DLOG("RPC: scheduled %.*s", method->via.bin.size, method->via.bin.ptr);
360+
bool is_resize = handler.fn == handle_nvim_ui_try_resize;
361+
if (is_resize) {
362+
Event ev = event_split(event_create(request_event, 1, evdata), 2);
363+
multiqueue_put_event(channel->events, ev);
364+
multiqueue_put_event(resize_events, ev);
365+
} else {
366+
multiqueue_put(channel->events, request_event, 1, evdata);
367+
DLOG("RPC: scheduled %.*s", method->via.bin.size, method->via.bin.ptr);
368+
}
360369
}
361370
}
362371

372+
363373
/// Handles a message, depending on the type:
364374
/// - Request: invokes method and writes the response (or error).
365375
/// - Notification: invokes method (emits `nvim_error_event` on error).

0 commit comments

Comments
 (0)