summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2022-09-30 17:16:16 +0200
committerPřemysl Eric Janouch <p@janouch.name>2022-09-30 17:36:29 +0200
commitc4707e2803c26885d1938d320db5b368a221ffea (patch)
tree22289e6dcc39d9181bc0c0e984fe650aaf81feb3
parent46d68eacce700e675ce534fe948024f939a968c8 (diff)
downloadxK-c4707e2803c26885d1938d320db5b368a221ffea.tar.gz
xK-c4707e2803c26885d1938d320db5b368a221ffea.tar.xz
xK-c4707e2803c26885d1938d320db5b368a221ffea.zip
xC/xP: send buffer input history during sync
This transfer is currenly quite simplistic, but it paves the way for further extensions.
-rw-r--r--xC.c70
-rw-r--r--xC.lxdr4
-rw-r--r--xP/public/xP.js9
3 files changed, 82 insertions, 1 deletions
diff --git a/xC.c b/xC.c
index 5aadb17..3a7b8c1 100644
--- a/xC.c
+++ b/xC.c
@@ -231,6 +231,8 @@ struct input_vtable
void (*buffer_destroy) (void *input, input_buffer_t buffer);
/// Switch to a different input 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
void (*register_fn) (void *input,
@@ -258,7 +260,7 @@ struct input_vtable
#define INPUT_VTABLE(XX) \
XX (start) XX (stop) XX (prepare) XX (destroy) \
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 (get_line) XX (clear_line) XX (insert) \
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;
}
+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
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);
}
+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
input_el_buffer_destroy (void *input, input_buffer_t input_buffer)
{
@@ -3093,6 +3132,20 @@ relay_prepare_buffer_activate (struct app_context *ctx, struct buffer *buffer)
}
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
relay_prepare_buffer_clear (struct app_context *ctx,
struct buffer *buffer)
{
@@ -15308,6 +15361,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
client_resync (struct client *c)
{
struct str_map_iter iter = str_map_iter_make (&c->ctx->servers);
@@ -15325,6 +15391,8 @@ client_resync (struct client *c)
relay_prepare_buffer_stats (c->ctx, buffer);
relay_send (c);
+ client_resync_buffer_input (c, buffer);
+
LIST_FOR_EACH (struct buffer_line, line, buffer->lines)
{
relay_prepare_buffer_line (c->ctx, buffer, line, false);
diff --git a/xC.lxdr b/xC.lxdr
index 3057404..af0f170 100644
--- a/xC.lxdr
+++ b/xC.lxdr
@@ -59,6 +59,7 @@ struct EventMessage {
BUFFER_RENAME,
BUFFER_REMOVE,
BUFFER_ACTIVATE,
+ BUFFER_INPUT,
BUFFER_CLEAR,
SERVER_UPDATE,
SERVER_RENAME,
@@ -153,6 +154,9 @@ struct EventMessage {
string buffer_name;
case BUFFER_ACTIVATE:
string buffer_name;
+ case BUFFER_INPUT:
+ string buffer_name;
+ string text;
case BUFFER_CLEAR:
string buffer_name;
diff --git a/xP/public/xP.js b/xP/public/xP.js
index a7b7b11..795641d 100644
--- a/xP/public/xP.js
+++ b/xP/public/xP.js
@@ -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 => {
let b = buffers.get(e.bufferName)
if (b !== undefined)