aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-09-22 17:56:05 +0800
committerGitHub <noreply@github.com>2023-09-22 17:56:05 +0800
commitb7763d7f6b7fdcabe06658c664457df8bc147563 (patch)
treeb85dad8a556924e09c4c4fa549e171ea634f1a75 /src
parent64e8a3c4d19eab40888fbac36b96e97bd9d68c42 (diff)
downloadrneovim-b7763d7f6b7fdcabe06658c664457df8bc147563.tar.gz
rneovim-b7763d7f6b7fdcabe06658c664457df8bc147563.tar.bz2
rneovim-b7763d7f6b7fdcabe06658c664457df8bc147563.zip
fix(api): get virtual text with multiple hl properly (#25307)
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/extmark.c57
-rw-r--r--src/nvim/api/win_config.c18
2 files changed, 40 insertions, 35 deletions
diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c
index 1e44c66974..91e197bea7 100644
--- a/src/nvim/api/extmark.c
+++ b/src/nvim/api/extmark.c
@@ -113,6 +113,36 @@ static Object hl_group_name(int hl_id, bool hl_name)
}
}
+Array virt_text_to_array(VirtText vt, bool hl_name)
+{
+ Array chunks = ARRAY_DICT_INIT;
+ Array hl_array = ARRAY_DICT_INIT;
+ for (size_t i = 0; i < kv_size(vt); i++) {
+ char *text = kv_A(vt, i).text;
+ int hl_id = kv_A(vt, i).hl_id;
+ if (text == NULL) {
+ if (hl_id > 0) {
+ ADD(hl_array, hl_group_name(hl_id, hl_name));
+ }
+ continue;
+ }
+ Array chunk = ARRAY_DICT_INIT;
+ ADD(chunk, CSTR_TO_OBJ(text));
+ if (hl_array.size > 0) {
+ if (hl_id > 0) {
+ ADD(hl_array, hl_group_name(hl_id, hl_name));
+ }
+ ADD(chunk, ARRAY_OBJ(hl_array));
+ hl_array = (Array)ARRAY_DICT_INIT;
+ } else if (hl_id > 0) {
+ ADD(chunk, hl_group_name(hl_id, hl_name));
+ }
+ ADD(chunks, ARRAY_OBJ(chunk));
+ }
+ assert(hl_array.size == 0);
+ return chunks;
+}
+
static Array extmark_to_array(const ExtmarkInfo *extmark, bool id, bool add_dict, bool hl_name)
{
Array rv = ARRAY_DICT_INIT;
@@ -145,16 +175,7 @@ static Array extmark_to_array(const ExtmarkInfo *extmark, bool id, bool add_dict
}
if (kv_size(decor->virt_text)) {
- Array chunks = ARRAY_DICT_INIT;
- for (size_t i = 0; i < decor->virt_text.size; i++) {
- Array chunk = ARRAY_DICT_INIT;
- VirtTextChunk *vtc = &decor->virt_text.items[i];
- ADD(chunk, CSTR_TO_OBJ(vtc->text));
- if (vtc->hl_id > 0) {
- ADD(chunk, hl_group_name(vtc->hl_id, hl_name));
- }
- ADD(chunks, ARRAY_OBJ(chunk));
- }
+ Array chunks = virt_text_to_array(decor->virt_text, hl_name);
PUT(dict, "virt_text", ARRAY_OBJ(chunks));
PUT(dict, "virt_text_hide", BOOLEAN_OBJ(decor->virt_text_hide));
if (decor->virt_text_pos == kVTWinCol) {
@@ -171,19 +192,9 @@ static Array extmark_to_array(const ExtmarkInfo *extmark, bool id, bool add_dict
if (kv_size(decor->virt_lines)) {
Array all_chunks = ARRAY_DICT_INIT;
bool virt_lines_leftcol = false;
- for (size_t i = 0; i < decor->virt_lines.size; i++) {
- Array chunks = ARRAY_DICT_INIT;
- VirtText *vt = &decor->virt_lines.items[i].line;
- virt_lines_leftcol = decor->virt_lines.items[i].left_col;
- for (size_t j = 0; j < vt->size; j++) {
- Array chunk = ARRAY_DICT_INIT;
- VirtTextChunk *vtc = &vt->items[j];
- ADD(chunk, CSTR_TO_OBJ(vtc->text));
- if (vtc->hl_id > 0) {
- ADD(chunk, hl_group_name(vtc->hl_id, hl_name));
- }
- ADD(chunks, ARRAY_OBJ(chunk));
- }
+ for (size_t i = 0; i < kv_size(decor->virt_lines); i++) {
+ virt_lines_leftcol = kv_A(decor->virt_lines, i).left_col;
+ Array chunks = virt_text_to_array(kv_A(decor->virt_lines, i).line, hl_name);
ADD(all_chunks, ARRAY_OBJ(chunks));
}
PUT(dict, "virt_lines", ARRAY_OBJ(all_chunks));
diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c
index ebdbd896a5..ea0b7ce512 100644
--- a/src/nvim/api/win_config.c
+++ b/src/nvim/api/win_config.c
@@ -259,34 +259,28 @@ void nvim_win_set_config(Window window, Dict(float_config) *config, Error *err)
Dictionary config_put_bordertext(Dictionary config, FloatConfig *fconfig,
BorderTextType bordertext_type)
{
- VirtText chunks;
+ VirtText vt;
AlignTextPos align;
char *field_name;
char *field_pos_name;
switch (bordertext_type) {
case kBorderTextTitle:
- chunks = fconfig->title_chunks;
+ vt = fconfig->title_chunks;
align = fconfig->title_pos;
field_name = "title";
field_pos_name = "title_pos";
break;
case kBorderTextFooter:
- chunks = fconfig->footer_chunks;
+ vt = fconfig->footer_chunks;
align = fconfig->footer_pos;
field_name = "footer";
field_pos_name = "footer_pos";
break;
+ default:
+ abort();
}
- Array bordertext = ARRAY_DICT_INIT;
- for (size_t i = 0; i < chunks.size; i++) {
- Array tuple = ARRAY_DICT_INIT;
- ADD(tuple, CSTR_TO_OBJ(chunks.items[i].text));
- if (chunks.items[i].hl_id > 0) {
- ADD(tuple, CSTR_TO_OBJ(syn_id2name(chunks.items[i].hl_id)));
- }
- ADD(bordertext, ARRAY_OBJ(tuple));
- }
+ Array bordertext = virt_text_to_array(vt, true);
PUT(config, field_name, ARRAY_OBJ(bordertext));
char *pos;