aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/ui.c6
-rw-r--r--src/nvim/terminal.c57
2 files changed, 45 insertions, 18 deletions
diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c
index 41a09999d0..7aa4cf4576 100644
--- a/src/nvim/api/ui.c
+++ b/src/nvim/api/ui.c
@@ -507,7 +507,11 @@ void nvim_ui_term_event(uint64_t channel_id, String event, Object value, Error *
const String termresponse = value.data.string;
set_vim_var_string(VV_TERMRESPONSE, termresponse.data, (ptrdiff_t)termresponse.size);
- apply_autocmds_group(EVENT_TERMRESPONSE, NULL, NULL, false, AUGROUP_ALL, NULL, NULL, &value);
+
+ MAXSIZE_TEMP_DICT(data, 1);
+ PUT_C(data, "sequence", value);
+ apply_autocmds_group(EVENT_TERMRESPONSE, NULL, NULL, false, AUGROUP_ALL, NULL, NULL,
+ &DICT_OBJ(data));
}
}
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index 47630ddea9..e0ebcc05b8 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -186,7 +186,7 @@ struct terminal {
char *selection_buffer; ///< libvterm selection buffer
StringBuilder selection; ///< Growable array containing full selection data
- StringBuilder termrequest_buffer; ///< Growable array containing unfinished request payload
+ StringBuilder termrequest_buffer; ///< Growable array containing unfinished request sequence
size_t refcount; // reference count
};
@@ -213,16 +213,36 @@ static Set(ptr_t) invalidated_terminals = SET_INIT;
static void emit_termrequest(void **argv)
{
Terminal *term = argv[0];
- char *payload = argv[1];
- size_t payload_length = (size_t)argv[2];
+ char *sequence = argv[1];
+ size_t sequence_length = (size_t)argv[2];
StringBuilder *pending_send = argv[3];
+ int row = (int)(intptr_t)argv[4];
+ int col = (int)(intptr_t)argv[5];
+
+ if (term->sb_pending > 0) {
+ // Don't emit the event while there is pending scrollback because we need
+ // the buffer contents to be fully updated. If this is the case, re-schedule
+ // the event.
+ multiqueue_put(main_loop.events, emit_termrequest, term, sequence, (void *)sequence_length,
+ pending_send, (void *)(intptr_t)row, (void *)(intptr_t)col);
+ return;
+ }
+
+ set_vim_var_string(VV_TERMREQUEST, sequence, (ptrdiff_t)sequence_length);
+
+ MAXSIZE_TEMP_ARRAY(cursor, 2);
+ ADD_C(cursor, INTEGER_OBJ(row));
+ ADD_C(cursor, INTEGER_OBJ(col));
+
+ MAXSIZE_TEMP_DICT(data, 2);
+ String termrequest = { .data = sequence, .size = sequence_length };
+ PUT_C(data, "sequence", STRING_OBJ(termrequest));
+ PUT_C(data, "cursor", ARRAY_OBJ(cursor));
buf_T *buf = handle_get_buffer(term->buf_handle);
- String termrequest = { .data = payload, .size = payload_length };
- Object data = STRING_OBJ(termrequest);
- set_vim_var_string(VV_TERMREQUEST, payload, (ptrdiff_t)payload_length);
- apply_autocmds_group(EVENT_TERMREQUEST, NULL, NULL, false, AUGROUP_ALL, buf, NULL, &data);
- xfree(payload);
+ apply_autocmds_group(EVENT_TERMREQUEST, NULL, NULL, false, AUGROUP_ALL, buf, NULL,
+ &DICT_OBJ(data));
+ xfree(sequence);
StringBuilder *term_pending_send = term->pending.send;
term->pending.send = NULL;
@@ -236,12 +256,15 @@ static void emit_termrequest(void **argv)
xfree(pending_send);
}
-static void schedule_termrequest(Terminal *term, char *payload, size_t payload_length)
+static void schedule_termrequest(Terminal *term, char *sequence, size_t sequence_length)
{
term->pending.send = xmalloc(sizeof(StringBuilder));
kv_init(*term->pending.send);
- multiqueue_put(main_loop.events, emit_termrequest, term, payload, (void *)payload_length,
- term->pending.send);
+
+ int line = row_to_linenr(term, term->cursor.row);
+ multiqueue_put(main_loop.events, emit_termrequest, term, sequence, (void *)sequence_length,
+ term->pending.send, (void *)(intptr_t)line,
+ (void *)(intptr_t)term->cursor.col);
}
static int parse_osc8(VTermStringFragment frag, int *attr)
@@ -315,8 +338,8 @@ static int on_osc(int command, VTermStringFragment frag, void *user)
}
kv_concat_len(term->termrequest_buffer, frag.str, frag.len);
if (frag.final) {
- char *payload = xmemdup(term->termrequest_buffer.items, term->termrequest_buffer.size);
- schedule_termrequest(user, payload, term->termrequest_buffer.size);
+ char *sequence = xmemdup(term->termrequest_buffer.items, term->termrequest_buffer.size);
+ schedule_termrequest(user, sequence, term->termrequest_buffer.size);
}
return 1;
}
@@ -338,8 +361,8 @@ static int on_dcs(const char *command, size_t commandlen, VTermStringFragment fr
}
kv_concat_len(term->termrequest_buffer, frag.str, frag.len);
if (frag.final) {
- char *payload = xmemdup(term->termrequest_buffer.items, term->termrequest_buffer.size);
- schedule_termrequest(user, payload, term->termrequest_buffer.size);
+ char *sequence = xmemdup(term->termrequest_buffer.items, term->termrequest_buffer.size);
+ schedule_termrequest(user, sequence, term->termrequest_buffer.size);
}
return 1;
}
@@ -361,8 +384,8 @@ static int on_apc(VTermStringFragment frag, void *user)
}
kv_concat_len(term->termrequest_buffer, frag.str, frag.len);
if (frag.final) {
- char *payload = xmemdup(term->termrequest_buffer.items, term->termrequest_buffer.size);
- schedule_termrequest(user, payload, term->termrequest_buffer.size);
+ char *sequence = xmemdup(term->termrequest_buffer.items, term->termrequest_buffer.size);
+ schedule_termrequest(user, sequence, term->termrequest_buffer.size);
}
return 1;
}