xC/xP: send buffer input history during sync

This transfer is currenly quite simplistic,
but it paves the way for further extensions.
This commit is contained in:
Přemysl Eric Janouch 2022-09-30 17:16:16 +02:00
parent 46d68eacce
commit c4707e2803
Signed by: p
GPG Key ID: A0420B94F92B9493
3 changed files with 82 additions and 1 deletions

70
xC.c
View File

@ -231,6 +231,8 @@ struct input_vtable
void (*buffer_destroy) (void *input, input_buffer_t buffer); void (*buffer_destroy) (void *input, input_buffer_t buffer);
/// Switch to a different input buffer /// Switch to a different input buffer
void (*buffer_switch) (void *input, input_buffer_t buffer); void (*buffer_switch) (void *input, input_buffer_t buffer);
/// Return all history lines in the locale encoding
struct strv (*buffer_history) (void *input, input_buffer_t buffer);
/// Register a function that can be bound to character sequences /// Register a function that can be bound to character sequences
void (*register_fn) (void *input, void (*register_fn) (void *input,
@ -258,7 +260,7 @@ struct input_vtable
#define INPUT_VTABLE(XX) \ #define INPUT_VTABLE(XX) \
XX (start) XX (stop) XX (prepare) XX (destroy) \ XX (start) XX (stop) XX (prepare) XX (destroy) \
XX (hide) XX (show) XX (get_prompt) XX (set_prompt) XX (ding) \ XX (hide) XX (show) XX (get_prompt) XX (set_prompt) XX (ding) \
XX (buffer_new) XX (buffer_destroy) XX (buffer_switch) \ XX (buffer_new) XX (buffer_destroy) XX (buffer_switch) XX (buffer_history) \
XX (register_fn) XX (bind) XX (bind_control) XX (bind_meta) \ XX (register_fn) XX (bind) XX (bind_control) XX (bind_meta) \
XX (get_line) XX (clear_line) XX (insert) \ XX (get_line) XX (clear_line) XX (insert) \
XX (on_tty_resized) XX (on_tty_readable) XX (on_tty_resized) XX (on_tty_readable)
@ -584,6 +586,19 @@ input_rl_buffer_switch (void *input, input_buffer_t input_buffer)
self->current = buffer; self->current = buffer;
} }
static struct strv
input_rl_buffer_history (void *input, input_buffer_t input_buffer)
{
struct input_rl *self = input;
struct input_rl_buffer *buffer = input_buffer;
HIST_ENTRY **p =
buffer->history ? buffer->history->entries : history_list();
struct strv v = strv_make ();
while (p && *p)
strv_append (&v, (*p++)->line);
return v;
}
static void static void
input_rl__buffer_destroy_wo_history (struct input_rl_buffer *self) input_rl__buffer_destroy_wo_history (struct input_rl_buffer *self)
{ {
@ -1059,6 +1074,30 @@ input_el_buffer_switch (void *input, input_buffer_t input_buffer)
input_el__restore_buffer (self, buffer); input_el__restore_buffer (self, buffer);
} }
static struct strv
input_el_buffer_history (void *input, input_buffer_t input_buffer)
{
struct input_el *self = input;
struct input_el_buffer *buffer = input_buffer;
struct strv v = strv_make ();
HistEventW ev;
if (history_w (buffer->history, &ev, H_LAST) < 0)
return v;
do
{
size_t len = wcstombs (NULL, ev.str, 0);
if (len++ == (size_t) -1)
continue;
char *mb = xmalloc (len);
mb[wcstombs (mb, ev.str, len)] = 0;
strv_append_owned (&v, mb);
}
while (history_w (buffer->history, &ev, H_PREV) >= 0);
return v;
}
static void static void
input_el_buffer_destroy (void *input, input_buffer_t input_buffer) input_el_buffer_destroy (void *input, input_buffer_t input_buffer)
{ {
@ -3092,6 +3131,20 @@ relay_prepare_buffer_activate (struct app_context *ctx, struct buffer *buffer)
e->buffer_name = str_from_cstr (buffer->name); e->buffer_name = str_from_cstr (buffer->name);
} }
static void
relay_prepare_buffer_input (struct app_context *ctx, struct buffer *buffer,
const char *locale_input)
{
struct relay_event_message *m = relay_prepare (ctx);
struct relay_event_data_buffer_input *e = &m->data.buffer_input;
e->event = RELAY_EVENT_BUFFER_INPUT;
e->buffer_name = str_from_cstr (buffer->name);
char *input = iconv_xstrdup (ctx->term_to_utf8,
(char *) locale_input, -1, NULL);
e->text = str_from_cstr (input);
free (input);
}
static void static void
relay_prepare_buffer_clear (struct app_context *ctx, relay_prepare_buffer_clear (struct app_context *ctx,
struct buffer *buffer) struct buffer *buffer)
@ -15307,6 +15360,19 @@ init_poller_events (struct app_context *ctx)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
static void
client_resync_buffer_input (struct client *c, struct buffer *buffer)
{
struct strv history =
CALL_ (c->ctx->input, buffer_history, buffer->input_data);
for (size_t i = 0; i < history.len; i++)
{
relay_prepare_buffer_input (c->ctx, buffer, history.vector[i]);
relay_send (c);
}
strv_free (&history);
}
static void static void
client_resync (struct client *c) client_resync (struct client *c)
{ {
@ -15325,6 +15391,8 @@ client_resync (struct client *c)
relay_prepare_buffer_stats (c->ctx, buffer); relay_prepare_buffer_stats (c->ctx, buffer);
relay_send (c); relay_send (c);
client_resync_buffer_input (c, buffer);
LIST_FOR_EACH (struct buffer_line, line, buffer->lines) LIST_FOR_EACH (struct buffer_line, line, buffer->lines)
{ {
relay_prepare_buffer_line (c->ctx, buffer, line, false); relay_prepare_buffer_line (c->ctx, buffer, line, false);

View File

@ -59,6 +59,7 @@ struct EventMessage {
BUFFER_RENAME, BUFFER_RENAME,
BUFFER_REMOVE, BUFFER_REMOVE,
BUFFER_ACTIVATE, BUFFER_ACTIVATE,
BUFFER_INPUT,
BUFFER_CLEAR, BUFFER_CLEAR,
SERVER_UPDATE, SERVER_UPDATE,
SERVER_RENAME, SERVER_RENAME,
@ -153,6 +154,9 @@ struct EventMessage {
string buffer_name; string buffer_name;
case BUFFER_ACTIVATE: case BUFFER_ACTIVATE:
string buffer_name; string buffer_name;
case BUFFER_INPUT:
string buffer_name;
string text;
case BUFFER_CLEAR: case BUFFER_CLEAR:
string buffer_name; string buffer_name;

View File

@ -387,6 +387,15 @@ rpcEventHandlers.set(Relay.Event.BufferActivate, e => {
} }
}) })
rpcEventHandlers.set(Relay.Event.BufferInput, e => {
let b = buffers.get(e.bufferName)
if (b === undefined)
return
if (b.historyAt == b.history.length)
b.historyAt++
b.history.push(e.text)
})
rpcEventHandlers.set(Relay.Event.BufferClear, e => { rpcEventHandlers.set(Relay.Event.BufferClear, e => {
let b = buffers.get(e.bufferName) let b = buffers.get(e.bufferName)
if (b !== undefined) if (b !== undefined)