commit 04022c70f3fd56096d90d0c4789b4ea7d06c4470
parent 81d9c29d694b88d20533adaf1c3b1721386652aa
Author: zeertzjq <zeertzjq@outlook.com>
Date: Sat, 4 Oct 2025 11:30:07 +0800
refactor(terminal): remove an unnecessary xmemdupz() for OSC 8 (#36012)
Instead, NUL-terminate the StringBuilder when needed.
Also deduplicate xmemdup() calls for schedule_termrequest().
Diffstat:
1 file changed, 17 insertions(+), 22 deletions(-)
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
@@ -268,24 +268,25 @@ static void emit_termrequest(void **argv)
xfree(pending_send);
}
-static void schedule_termrequest(Terminal *term, char *sequence, size_t sequence_length)
+static void schedule_termrequest(Terminal *term)
{
term->pending.send = xmalloc(sizeof(StringBuilder));
kv_init(*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);
+ multiqueue_put(main_loop.events, emit_termrequest, term,
+ xmemdup(term->termrequest_buffer.items, term->termrequest_buffer.size),
+ (void *)(intptr_t)term->termrequest_buffer.size, term->pending.send,
+ (void *)(intptr_t)line, (void *)(intptr_t)term->cursor.col);
}
-static int parse_osc8(const char *str, size_t len, int *attr)
+static int parse_osc8(const char *str, int *attr)
FUNC_ATTR_NONNULL_ALL
{
// Parse the URI from the OSC 8 sequence and add the URL to our URL set.
// Skip the ID, we don't use it (for now)
size_t i = 0;
- for (; i < len; i++) {
+ for (; str[i] != NUL; i++) {
if (str[i] == ';') {
break;
}
@@ -299,16 +300,13 @@ static int parse_osc8(const char *str, size_t len, int *attr)
// Move past the semicolon
i++;
- if (i >= len) {
+ if (str[i] == NUL) {
// Empty OSC 8, no URL
*attr = 0;
return 1;
}
- char *url = xmemdupz(str + i, len - i);
- *attr = hl_add_url(0, url);
- xfree(url);
-
+ *attr = hl_add_url(0, str + i);
return 1;
}
@@ -331,20 +329,19 @@ static int on_osc(int command, VTermStringFragment frag, void *user)
}
kv_concat_len(term->termrequest_buffer, frag.str, frag.len);
if (frag.final) {
+ if (has_event(EVENT_TERMREQUEST)) {
+ schedule_termrequest(term);
+ }
if (command == 8) {
+ kv_push(term->termrequest_buffer, NUL);
+ const size_t off = STRLEN_LITERAL("\x1b]8;");
int attr = 0;
- const int off = STRLEN_LITERAL("\x1b]8;");
- if (parse_osc8(term->termrequest_buffer.items + off,
- term->termrequest_buffer.size - off, &attr)) {
+ if (parse_osc8(term->termrequest_buffer.items + off, &attr)) {
VTermState *state = vterm_obtain_state(term->vt);
VTermValue value = { .number = attr };
vterm_state_set_penattr(state, VTERM_ATTR_URI, VTERM_VALUETYPE_INT, &value);
}
}
- if (has_event(EVENT_TERMREQUEST)) {
- char *sequence = xmemdup(term->termrequest_buffer.items, term->termrequest_buffer.size);
- schedule_termrequest(user, sequence, term->termrequest_buffer.size);
- }
}
return 1;
}
@@ -366,8 +363,7 @@ 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 *sequence = xmemdup(term->termrequest_buffer.items, term->termrequest_buffer.size);
- schedule_termrequest(user, sequence, term->termrequest_buffer.size);
+ schedule_termrequest(term);
}
return 1;
}
@@ -389,8 +385,7 @@ static int on_apc(VTermStringFragment frag, void *user)
}
kv_concat_len(term->termrequest_buffer, frag.str, frag.len);
if (frag.final) {
- char *sequence = xmemdup(term->termrequest_buffer.items, term->termrequest_buffer.size);
- schedule_termrequest(user, sequence, term->termrequest_buffer.size);
+ schedule_termrequest(term);
}
return 1;
}