aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-09-22 15:36:24 +0800
committerGitHub <noreply@github.com>2023-09-22 15:36:24 +0800
commit64e8a3c4d19eab40888fbac36b96e97bd9d68c42 (patch)
treed8292fcfe24ce5779a0f27ac1e006e251e3a3ea2
parent34a786bc49598eeafef3fffcb0836d4557e51638 (diff)
downloadrneovim-64e8a3c4d19eab40888fbac36b96e97bd9d68c42.tar.gz
rneovim-64e8a3c4d19eab40888fbac36b96e97bd9d68c42.tar.bz2
rneovim-64e8a3c4d19eab40888fbac36b96e97bd9d68c42.zip
fix(ui): handle virtual text with multiple hl in more cases (#25304)
-rw-r--r--src/nvim/api/extmark.c3
-rw-r--r--src/nvim/decoration.c18
-rw-r--r--src/nvim/drawline.c18
-rw-r--r--src/nvim/drawscreen.c12
-rw-r--r--src/nvim/fold.c9
-rw-r--r--test/functional/ui/float_spec.lua17
-rw-r--r--test/functional/ui/fold_spec.lua45
7 files changed, 69 insertions, 53 deletions
diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c
index faab6e593c..1e44c66974 100644
--- a/src/nvim/api/extmark.c
+++ b/src/nvim/api/extmark.c
@@ -1188,8 +1188,7 @@ VirtText parse_virt_text(Array chunks, Error *err, int *width)
goto free_exit;
}
if (j < arr.size - 1) {
- kv_push(virt_text, ((VirtTextChunk){ .text = NULL,
- .hl_id = hl_id }));
+ kv_push(virt_text, ((VirtTextChunk){ .text = NULL, .hl_id = hl_id }));
}
}
} else {
diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c
index b70f070a51..9d391cde8c 100644
--- a/src/nvim/decoration.c
+++ b/src/nvim/decoration.c
@@ -153,6 +153,24 @@ void clear_virttext(VirtText *text)
*text = (VirtText)KV_INITIAL_VALUE;
}
+/// Get the next chunk of a virtual text item.
+///
+/// @param[in] vt The virtual text item
+/// @param[in,out] pos Position in the virtual text item
+/// @param[in,out] attr Highlight attribute
+///
+/// @return The text of the chunk, or NULL if there are no more chunks
+char *next_virt_text_chunk(VirtText vt, size_t *pos, int *attr)
+{
+ char *text = NULL;
+ for (; text == NULL && *pos < kv_size(vt); (*pos)++) {
+ text = kv_A(vt, *pos).text;
+ int hl_id = kv_A(vt, *pos).hl_id;
+ *attr = hl_combine_attr(*attr, hl_id > 0 ? syn_id2attr(hl_id) : 0);
+ }
+ return text;
+}
+
Decoration *decor_find_virttext(buf_T *buf, int row, uint64_t ns_id)
{
MarkTreeIter itr[1] = { 0 };
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index a5409dbc98..7d64d9fa3c 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -324,24 +324,6 @@ static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int
}
}
-/// Get the next chunk of a virtual text item.
-///
-/// @param[in] vt The virtual text item
-/// @param[in,out] pos Position in the virtual text item
-/// @param[in,out] attr Highlight attribute
-///
-/// @return The text of the chunk, or NULL if there are no more chunks
-static char *next_virt_text_chunk(VirtText vt, size_t *pos, int *attr)
-{
- char *text = NULL;
- for (; text == NULL && *pos < kv_size(vt); (*pos)++) {
- text = kv_A(vt, *pos).text;
- int hl_id = kv_A(vt, *pos).hl_id;
- *attr = hl_combine_attr(*attr, hl_id > 0 ? syn_id2attr(hl_id) : 0);
- }
- return text;
-}
-
static int draw_virt_text_item(buf_T *buf, int col, VirtText vt, HlMode hl_mode, int max_col,
int vcol, bool rl)
{
diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c
index 854c8590e4..1d22b67d40 100644
--- a/src/nvim/drawscreen.c
+++ b/src/nvim/drawscreen.c
@@ -709,13 +709,15 @@ void end_search_hl(void)
screen_search_hl.rm.regprog = NULL;
}
-static void win_redr_bordertext(win_T *wp, ScreenGrid *grid, VirtText text_chunks, int row, int col)
+static void win_redr_bordertext(win_T *wp, ScreenGrid *grid, VirtText vt, int row, int col)
{
- for (size_t i = 0; i < text_chunks.size; i++) {
- char *text = text_chunks.items[i].text;
+ for (size_t i = 0; i < kv_size(vt);) {
+ int attr = 0;
+ char *text = next_virt_text_chunk(vt, &i, &attr);
+ if (text == NULL) {
+ break;
+ }
int cell = (int)mb_string2cells(text);
- int hl_id = text_chunks.items[i].hl_id;
- int attr = hl_id ? syn_id2attr(hl_id) : 0;
grid_puts(grid, text, row, col, attr);
col += cell;
}
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index 1d5ba49301..d874e904d0 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -3344,8 +3344,13 @@ void f_foldtextresult(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
}
if (kv_size(vt) > 0) {
assert(*text == NUL);
- for (size_t i = 0; i < kv_size(vt); i++) {
- char *new_text = concat_str(text, kv_A(vt, i).text);
+ for (size_t i = 0; i < kv_size(vt);) {
+ int attr = 0;
+ char *new_text = next_virt_text_chunk(vt, &i, &attr);
+ if (new_text == NULL) {
+ break;
+ }
+ new_text = concat_str(text, new_text);
xfree(text);
text = new_text;
}
diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua
index 4fea513249..93ca1aef3f 100644
--- a/test/functional/ui/float_spec.lua
+++ b/test/functional/ui/float_spec.lua
@@ -821,7 +821,7 @@ describe('float window', function()
[4] = {bold = true, reverse = true},
[5] = {reverse = true},
[6] = {background = Screen.colors.LightMagenta, bold = true, reverse = true},
- [7] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
+ [7] = {foreground = Screen.colors.White, background = Screen.colors.Red},
[8] = {bold = true, foreground = Screen.colors.SeaGreen4},
[9] = {background = Screen.colors.LightGrey, underline = true},
[10] = {background = Screen.colors.LightGrey, underline = true, bold = true, foreground = Screen.colors.Magenta},
@@ -2512,7 +2512,12 @@ describe('float window', function()
]]}
end
- meths.win_set_config(win, {title= { {"🦄"},{"BB"}},title_pos="right",footer= { {"🦄"},{"BB"}},footer_pos="right"})
+ command('hi B0 guibg=Red guifg=Black')
+ command('hi B1 guifg=White')
+ meths.win_set_config(win, {
+ title = {{"🦄"}, {"BB", {"B0", "B1"}}}, title_pos = "right",
+ footer= {{"🦄"}, {"BB", {"B0", "B1"}}}, footer_pos = "right",
+ })
if multigrid then
screen:expect{grid=[[
## grid 1
@@ -2533,10 +2538,10 @@ describe('float window', function()
## grid 3
|
## grid 4
- {5:╔═════}🦄BB{5:╗}|
+ {5:╔═════}🦄{7:BB}{5:╗}|
{5:║}{1: halloj! }{5:║}|
{5:║}{1: BORDAA }{5:║}|
- {5:╚═════}🦄BB{5:╝}|
+ {5:╚═════}🦄{7:BB}{5:╝}|
]], float_pos={
[4] = { { id = 1001 }, "NW", 1, 2, 5, true }
}, win_viewport={
@@ -2547,10 +2552,10 @@ describe('float window', function()
screen:expect{grid=[[
^ |
{0:~ }|
- {0:~ }{5:╔═════}🦄BB{5:╗}{0: }|
+ {0:~ }{5:╔═════}🦄{7:BB}{5:╗}{0: }|
{0:~ }{5:║}{1: halloj! }{5:║}{0: }|
{0:~ }{5:║}{1: BORDAA }{5:║}{0: }|
- {0:~ }{5:╚═════}🦄BB{5:╝}{0: }|
+ {0:~ }{5:╚═════}🦄{7:BB}{5:╝}{0: }|
|
]]}
end
diff --git a/test/functional/ui/fold_spec.lua b/test/functional/ui/fold_spec.lua
index 5e907f82ba..f42682ba69 100644
--- a/test/functional/ui/fold_spec.lua
+++ b/test/functional/ui/fold_spec.lua
@@ -33,7 +33,7 @@ describe("folded lines", function()
[1] = {bold = true, foreground = Screen.colors.Blue1},
[2] = {reverse = true},
[3] = {bold = true, reverse = true},
- [4] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
+ [4] = {foreground = Screen.colors.White, background = Screen.colors.Red},
[5] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey},
[6] = {background = Screen.colors.Yellow},
[7] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray},
@@ -2938,10 +2938,15 @@ describe("folded lines", function()
screen:try_resize(30, 7)
insert(content1)
command("hi! CursorLine guibg=NONE guifg=Red gui=NONE")
+ command('hi F0 guibg=Red guifg=Black')
+ command('hi F1 guifg=White')
meths.set_option_value('cursorline', true, {})
meths.set_option_value('foldcolumn', '4', {})
- meths.set_option_value('foldtext',
- '[[v:folddashes], ["\t", "Search"], [getline(v:foldstart), "NonText"]]', {})
+ meths.set_option_value('foldtext', '['
+ .. '["▶", ["F0", "F1"]], '
+ .. '[v:folddashes], '
+ .. '["\t", "Search"], '
+ .. '[getline(v:foldstart), "NonText"]]', {})
command('3,4fold')
command('5,6fold')
@@ -2958,7 +2963,7 @@ describe("folded lines", function()
[3:------------------------------]|
## grid 2
{7: }This is a |
- {7:+ }{13:^-}{17: }{18:valid English}{13:·····}|
+ {7:+ }{4:^▶}{13:-}{17: }{18:valid English}{13:·····}|
{1:~ }|
{1:~ }|
{1:~ }|
@@ -2969,7 +2974,7 @@ describe("folded lines", function()
else
screen:expect([[
{7: }This is a |
- {7:+ }{13:^-}{17: }{18:valid English}{13:·····}|
+ {7:+ }{4:^▶}{13:-}{17: }{18:valid English}{13:·····}|
{1:~ }|
{1:~ }|
{1:~ }|
@@ -2977,7 +2982,7 @@ describe("folded lines", function()
|
]])
end
- eq('-\tvalid English', funcs.foldtextresult(2))
+ eq('▶-\tvalid English', funcs.foldtextresult(2))
feed('zo')
if multigrid then
@@ -2993,8 +2998,8 @@ describe("folded lines", function()
## grid 2
{7: }This is a |
{7:- }valid English |
- {7:│+ }{5:--}{19: }{18:sentence composed }|
- {7:│+ }{13:^--}{17: }{18:in his cave.}{13:······}|
+ {7:│+ }{4:▶}{5:--}{19: }{18:sentence composed }|
+ {7:│+ }{4:^▶}{13:--}{17: }{18:in his cave.}{13:······}|
{1:~ }|
{1:~ }|
## grid 3
@@ -3004,15 +3009,15 @@ describe("folded lines", function()
screen:expect([[
{7: }This is a |
{7:- }valid English |
- {7:│+ }{5:--}{19: }{18:sentence composed }|
- {7:│+ }{13:^--}{17: }{18:in his cave.}{13:······}|
+ {7:│+ }{4:▶}{5:--}{19: }{18:sentence composed }|
+ {7:│+ }{4:^▶}{13:--}{17: }{18:in his cave.}{13:······}|
{1:~ }|
{1:~ }|
|
]])
end
- eq('--\tsentence composed by', funcs.foldtextresult(3))
- eq('--\tin his cave.', funcs.foldtextresult(5))
+ eq('▶--\tsentence composed by', funcs.foldtextresult(3))
+ eq('▶--\tin his cave.', funcs.foldtextresult(5))
command('hi! Visual guibg=Red')
feed('V2k')
@@ -3029,8 +3034,8 @@ describe("folded lines", function()
## grid 2
{7: }This is a |
{7:- }^v{14:alid English} |
- {7:│+ }{15:--}{19: }{20:sentence composed }|
- {7:│+ }{15:--}{19: }{20:in his cave.}{15:······}|
+ {7:│+ }{4:▶}{15:--}{19: }{20:sentence composed }|
+ {7:│+ }{4:▶}{15:--}{19: }{20:in his cave.}{15:······}|
{1:~ }|
{1:~ }|
## grid 3
@@ -3040,8 +3045,8 @@ describe("folded lines", function()
screen:expect([[
{7: }This is a |
{7:- }^v{14:alid English} |
- {7:│+ }{15:--}{19: }{20:sentence composed }|
- {7:│+ }{15:--}{19: }{20:in his cave.}{15:······}|
+ {7:│+ }{4:▶}{15:--}{19: }{20:sentence composed }|
+ {7:│+ }{4:▶}{15:--}{19: }{20:in his cave.}{15:······}|
{1:~ }|
{1:~ }|
{11:-- VISUAL LINE --} |
@@ -3062,8 +3067,8 @@ describe("folded lines", function()
## grid 2
a si sihT{7: }|
{14:hsilgnE dila}^v{7: -}|
- {20: desopmoc ecnetnes}{19: }{15:--}{7: +│}|
- {15:······}{20:.evac sih ni}{19: }{15:--}{7: +│}|
+ {20: desopmoc ecnetnes}{19: }{15:--}{4:▶}{7: +│}|
+ {15:······}{20:.evac sih ni}{19: }{15:--}{4:▶}{7: +│}|
{1: ~}|
{1: ~}|
## grid 3
@@ -3073,8 +3078,8 @@ describe("folded lines", function()
screen:expect([[
a si sihT{7: }|
{14:hsilgnE dila}^v{7: -}|
- {20: desopmoc ecnetnes}{19: }{15:--}{7: +│}|
- {15:······}{20:.evac sih ni}{19: }{15:--}{7: +│}|
+ {20: desopmoc ecnetnes}{19: }{15:--}{4:▶}{7: +│}|
+ {15:······}{20:.evac sih ni}{19: }{15:--}{4:▶}{7: +│}|
{1: ~}|
{1: ~}|
{11:-- VISUAL LINE --} |