diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c index be078bf626..16df5aae18 100644 --- a/src/nvim/api/deprecated.c +++ b/src/nvim/api/deprecated.c @@ -234,7 +234,7 @@ Integer nvim_buf_set_virtual_text(Buffer buffer, Integer src_id, Integer line, A uint32_t ns_id = src2ns(&src_id); int width; - VirtText virt_text = parse_virt_text(chunks, err, &width); + VirtText virt_text = parse_virt_text(chunks, err, &width, false); if (ERROR_SET(err)) { return 0; } diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c index a0d47d3280..6441eee9c2 100644 --- a/src/nvim/api/extmark.c +++ b/src/nvim/api/extmark.c @@ -669,7 +669,7 @@ Integer nvim_buf_set_extmark(Buffer buf, Integer ns_id, Integer line, Integer co } if (HAS_KEY(opts, set_extmark, virt_text)) { - virt_text.data.virt_text = parse_virt_text(opts->virt_text, err, &virt_text.width); + virt_text.data.virt_text = parse_virt_text(opts->virt_text, err, &virt_text.width, false); if (ERROR_SET(err)) { goto error; } @@ -742,7 +742,7 @@ Integer nvim_buf_set_extmark(Buffer buf, Integer ns_id, Integer line, Integer co goto error; }); int dummig; - VirtText jtem = parse_virt_text(a.items[j].data.array, err, &dummig); + VirtText jtem = parse_virt_text(a.items[j].data.array, err, &dummig, false); kv_push(virt_lines.data.virt_lines, ((struct virt_line){ jtem, virt_lines_flags })); if (ERROR_SET(err)) { goto error; @@ -1192,7 +1192,7 @@ static bool extmark_get_index_from_obj(buf_T *buf, Integer ns_id, Object obj, in } } -VirtText parse_virt_text(Array chunks, Error *err, int *width) +VirtText parse_virt_text(Array chunks, Error *err, int *width, bool untab) { VirtText virt_text = KV_INITIAL_VALUE; int w = 0; @@ -1230,7 +1230,7 @@ VirtText parse_virt_text(Array chunks, Error *err, int *width) } } - char *text = transstr(str.size > 0 ? str.data : "", false); // allocates + char *text = transstr(str.size > 0 ? str.data : "", untab); // allocates w += (int)mb_string2cells(text); kv_push(virt_text, ((VirtTextChunk){ .text = text, .hl_id = hl_id })); diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c index 2bc34a8da6..a7d16e1872 100644 --- a/src/nvim/api/win_config.c +++ b/src/nvim/api/win_config.c @@ -15,6 +15,7 @@ #include "nvim/autocmd_defs.h" #include "nvim/buffer.h" #include "nvim/buffer_defs.h" +#include "nvim/charset.h" #include "nvim/decoration_defs.h" #include "nvim/drawscreen.h" #include "nvim/errors.h" @@ -1021,38 +1022,27 @@ static void parse_bordertext(Object bordertext, BorderTextType bordertext_type, return; }); - bool *is_present; - VirtText *chunks; - int *width; - switch (bordertext_type) { - case kBorderTextTitle: - is_present = &fconfig->title; - chunks = &fconfig->title_chunks; - width = &fconfig->title_width; - break; - case kBorderTextFooter: - is_present = &fconfig->footer; - chunks = &fconfig->footer_chunks; - width = &fconfig->footer_width; - break; - } + bool is_title = bordertext_type == kBorderTextTitle; + bool *is_present = is_title ? &fconfig->title : &fconfig->footer; + VirtText *chunks = is_title ? &fconfig->title_chunks : &fconfig->footer_chunks; + int *width = is_title ? &fconfig->title_width : &fconfig->footer_width; if (bordertext.type == kObjectTypeString) { if (bordertext.data.string.size == 0) { *is_present = false; return; } + char *text = transstr(bordertext.data.string.data, true); kv_init(*chunks); - kv_push(*chunks, ((VirtTextChunk){ .text = xstrdup(bordertext.data.string.data), - .hl_id = -1 })); - *width = (int)mb_string2cells(bordertext.data.string.data); - *is_present = true; - return; + kv_push(*chunks, ((VirtTextChunk){ .text = text, .hl_id = -1 })); + *width = (int)mb_string2cells(text); + } else { + *chunks = parse_virt_text(bordertext.data.array, err, width, true); + if (ERROR_SET(err)) { + return; + } } - *width = 0; - *chunks = parse_virt_text(bordertext.data.array, err, width); - *is_present = true; } diff --git a/src/nvim/fold.c b/src/nvim/fold.c index a39d4419f6..e8fc675f1b 100644 --- a/src/nvim/fold.c +++ b/src/nvim/fold.c @@ -1737,7 +1737,7 @@ char *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume, foldinfo_T foldinfo Object obj = eval_foldtext(wp); if (obj.type == kObjectTypeArray) { Error err = ERROR_INIT; - *vt = parse_virt_text(obj.data.array, &err, NULL); + *vt = parse_virt_text(obj.data.array, &err, NULL, false); if (!ERROR_SET(&err)) { *buf = NUL; text = buf; diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index 8978ccd783..f906d083a8 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -3056,6 +3056,45 @@ describe('float window', function() eq({ { '🦄', '' }, { 'BB', { 'B0', 'B1', '' } } }, api.nvim_win_get_config(win).title) eq({ { '🦄', '' }, { 'BB', { 'B0', 'B1', '' } } }, api.nvim_win_get_config(win).footer) + api.nvim_win_set_config(win, { border = 'single', title = 'a\tb', footer = 'A\tB' }) + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:----------------------------------------]|*6 + [3:----------------------------------------]| + ## grid 2 + ^ | + {0:~ }|*5 + ## grid 3 + | + ## grid 4 + {5:┌}{11:a^Ib}{5:─────┐}| + {5:│}{1: halloj! }{5:│}| + {5:│}{1: BORDAA }{5:│}| + {5:└}{11:A^IB}{5:─────┘}| + ]], + float_pos = { [4] = { 1001, 'NW', 1, 2, 5, true, 50, 1, 2, 5 } }, + win_viewport = { + [2] = { win = 1000, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1, sum_scroll_delta = 0 }, + [4] = { win = 1001, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 2, sum_scroll_delta = 0 }, + }, + }) + else + screen:expect([[ + ^ | + {0:~ }| + {0:~ }{5:┌}{11:a^Ib}{5:─────┐}{0: }| + {0:~ }{5:│}{1: halloj! }{5:│}{0: }| + {0:~ }{5:│}{1: BORDAA }{5:│}{0: }| + {0:~ }{5:└}{11:A^IB}{5:─────┘}{0: }| + | + ]]) + end + + api.nvim_win_set_config(win, { title = { { 'a\tb' } }, footer = { { 'A\tB' } } }) + screen:expect_unchanged() + -- making it a split should not leak memory api.nvim_win_set_config(win, { vertical = true }) if multigrid then