diff options
author | oni-link <knil.ino@gmail.com> | 2019-06-24 00:01:02 +0200 |
---|---|---|
committer | Justin M. Keyes <justinkz@gmail.com> | 2019-06-24 00:01:01 +0200 |
commit | 0bdeec8ef02bcd497f6df77b2a00420c948c9438 (patch) | |
tree | 237ac0b457654991ecde9a7a211c954b4d68e60c | |
parent | 9ce34050e549baf2c85e23fc3370f3ffebc773ad (diff) | |
download | rneovim-0bdeec8ef02bcd497f6df77b2a00420c948c9438.tar.gz rneovim-0bdeec8ef02bcd497f6df77b2a00420c948c9438.tar.bz2 rneovim-0bdeec8ef02bcd497f6df77b2a00420c948c9438.zip |
screen: Adjust buffer sizes for multiple sign columns #10314
* screen: Fix to draw signs with combining characters.
The buffer size for signs can be too small, because the upper length
limit of a sign can be 56 bytes. If combining characters are only two
bytes in size, this reduces to 32 bytes.
* screen: Adjust buffer size to maximal sign column count
-rw-r--r-- | src/nvim/screen.c | 20 | ||||
-rw-r--r-- | test/functional/ui/fold_spec.lua | 16 | ||||
-rw-r--r-- | test/functional/ui/sign_spec.lua | 24 |
3 files changed, 56 insertions, 4 deletions
diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 45c82d70d1..f349304468 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -1775,7 +1775,9 @@ static void fold_line(win_T *wp, long fold_count, foldinfo_T *foldinfo, linenr_T if (len > len_max) { len = len_max; } - copy_text_attr(off + col, (char_u *)" ", len, + char_u space_buf[18] = " "; + assert((size_t)len_max <= sizeof(space_buf)); + copy_text_attr(off + col, space_buf, len, win_hl_attr(wp, HLF_FL)); col += len; } @@ -2061,7 +2063,8 @@ win_line ( int row; // row in the window, excl w_winrow ScreenGrid *grid = &wp->w_grid; // grid specfic to the window - char_u extra[18]; // line number and 'fdc' must fit in here + char_u extra[57]; // sign, line number and 'fdc' must + // fit in here int n_extra = 0; // number of extra chars char_u *p_extra = NULL; // string of extra chars, plus NUL char_u *p_extra_free = NULL; // p_extra needs to be freed @@ -2712,15 +2715,24 @@ win_line ( sign_idx, count); if (text_sign != 0) { p_extra = sign_get_text(text_sign); - int symbol_blen = (int)STRLEN(p_extra); if (p_extra != NULL) { + int symbol_blen = (int)STRLEN(p_extra); + c_extra = NUL; c_final = NUL; + + // TODO(oni-link): Is sign text already extended to + // full cell width? + assert((size_t)win_signcol_width(wp) + >= mb_string2cells(p_extra)); // symbol(s) bytes + (filling spaces) (one byte each) n_extra = symbol_blen + (win_signcol_width(wp) - mb_string2cells(p_extra)); + + assert(sizeof(extra) > (size_t)symbol_blen); memset(extra, ' ', sizeof(extra)); - STRNCPY(extra, p_extra, STRLEN(p_extra)); + memcpy(extra, p_extra, symbol_blen); + p_extra = extra; p_extra[n_extra] = NUL; } diff --git a/test/functional/ui/fold_spec.lua b/test/functional/ui/fold_spec.lua index 5fa299bed9..c5ef718883 100644 --- a/test/functional/ui/fold_spec.lua +++ b/test/functional/ui/fold_spec.lua @@ -28,6 +28,22 @@ describe("folded lines", function() screen:detach() end) + it("work with more than one signcolumn", function() + command("set signcolumn=yes:9") + feed("i<cr><esc>") + feed("vkzf") + screen:expect([[ + {5: ^+-- 2 lines: ·············}| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]) + end) + it("highlighting with relative line numbers", function() command("set relativenumber foldmethod=marker") feed_command("set foldcolumn=2") diff --git a/test/functional/ui/sign_spec.lua b/test/functional/ui/sign_spec.lua index 2b38a2a58d..68e675b8e5 100644 --- a/test/functional/ui/sign_spec.lua +++ b/test/functional/ui/sign_spec.lua @@ -31,6 +31,30 @@ describe('Signs', function() end) describe(':sign place', function() + it('allows signs with combining characters', function() + feed('ia<cr>b<cr><esc>') + command('sign define piet1 text=𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄ texthl=Search') + command('sign define piet2 text=𠜎̀́̂̃̄̅ texthl=Search') + command('sign place 1 line=1 name=piet1 buffer=1') + command('sign place 2 line=2 name=piet2 buffer=1') + screen:expect([[ + {1:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}a | + {1:𠜎̀́̂̃̄̅}b | + {2: }^ | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + end) + it('shadows previously placed signs', function() feed('ia<cr>b<cr>c<cr><esc>') command('sign define piet text=>> texthl=Search') |