fix(column): handle unprintable chars in 'statuscolumn' (#24198)

This commit is contained in:
zeertzjq 2023-06-29 11:37:55 +08:00 committed by GitHub
parent d90f5ab9ac
commit 7d0a23973b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 81 additions and 38 deletions

View File

@ -747,6 +747,11 @@ static void get_statuscol_display_info(statuscol_T *stcp, winlinevars_T *wlv)
} }
// Skip over empty highlight sections // Skip over empty highlight sections
} while (wlv->n_extra == 0 && stcp->textp < stcp->text_end); } while (wlv->n_extra == 0 && stcp->textp < stcp->text_end);
if (wlv->n_extra > 0) {
static char transbuf[MAX_NUMBERWIDTH * MB_MAXBYTES + 1];
wlv->n_extra = (int)transstr_buf(wlv->p_extra, wlv->n_extra, transbuf, sizeof transbuf, true);
wlv->p_extra = transbuf;
}
} }
static void handle_breakindent(win_T *wp, winlinevars_T *wlv) static void handle_breakindent(win_T *wp, winlinevars_T *wlv)

View File

@ -3,6 +3,7 @@ local Screen = require('test.functional.ui.screen')
local clear = helpers.clear local clear = helpers.clear
local command = helpers.command local command = helpers.command
local eq = helpers.eq local eq = helpers.eq
local exec = helpers.exec
local eval = helpers.eval local eval = helpers.eval
local exec_lua = helpers.exec_lua local exec_lua = helpers.exec_lua
local feed = helpers.feed local feed = helpers.feed
@ -440,17 +441,22 @@ describe('statuscolumn', function()
end) end)
for _, model in ipairs(mousemodels) do for _, model in ipairs(mousemodels) do
it("works with 'statuscolumn' clicks with mousemodel=" .. model, function() describe('with mousemodel=' .. model, function()
before_each(function()
command('set mousemodel=' .. model) command('set mousemodel=' .. model)
command([[ exec([[
function! MyClickFunc(minwid, clicks, button, mods) function! MyClickFunc(minwid, clicks, button, mods)
let g:testvar = printf("%d %d %s %d", a:minwid, a:clicks, a:button, getmousepos().line) let g:testvar = printf("%d %d %s %d", a:minwid, a:clicks, a:button, getmousepos().line)
if a:mods !=# ' ' if a:mods !=# ' '
let g:testvar ..= '(' .. a:mods .. ')' let g:testvar ..= '(' .. a:mods .. ')'
endif endif
endfunction endfunction
set stc=%0@MyClickFunc@%=%l%T let g:testvar = ''
]]) ]])
end)
it('clicks work with mousemodel=' .. model, function()
meths.set_option_value('statuscolumn', '%0@MyClickFunc@%=%l%T', {})
meths.input_mouse('left', 'press', '', 0, 0, 0) meths.input_mouse('left', 'press', '', 0, 0, 0)
eq('0 1 l 4', eval("g:testvar")) eq('0 1 l 4', eval("g:testvar"))
meths.input_mouse('left', 'press', '', 0, 0, 0) meths.input_mouse('left', 'press', '', 0, 0, 0)
@ -479,6 +485,38 @@ describe('statuscolumn', function()
meths.input_mouse('right', 'press', '', 0, 13, 0) meths.input_mouse('right', 'press', '', 0, 13, 0)
eq('', eval("g:testvar")) eq('', eval("g:testvar"))
end) end)
it('clicks and highlights work with control characters', function()
meths.set_option_value('statuscolumn', '\t%#NonText#\1%0@MyClickFunc@\t\1%T\t%##\1', {})
screen:expect{grid=[[
{1:^I}{0:^A^I^A^I}{1:^A}aaaaa |
{1:^I}{0:^A^I^A^I}{1:^A}aaaaa |
{1:^I}{0:^A^I^A^I}{1:^A}aaaaa |
{1:^I}{0:^A^I^A^I}{1:^A}aaaaa |
{1:^I}{0:^A^I^A^I}{1:^A}^aaaaa |
{1:^I}{0:^A^I^A^I}{1:^A}aaaaa |
{1:^I}{0:^A^I^A^I}{1:^A}aaaaa |
{1:^I}{0:^A^I^A^I}{1:^A}aaaaa |
{1:^I}{0:^A^I^A^I}{1:^A}aaaaa |
{1:^I}{0:^A^I^A^I}{1:^A}aaaaa |
{1:^I}{0:^A^I^A^I}{1:^A}aaaaa |
{1:^I}{0:^A^I^A^I}{1:^A}aaaaa |
{1:^I}{0:^A^I^A^I}{1:^A}aaaaa |
|
]], attr_ids={
[0] = {foreground = Screen.colors.Blue, bold = true}; -- NonText
[1] = {foreground = Screen.colors.Brown}; -- LineNr
}}
meths.input_mouse('right', 'press', '', 0, 4, 3)
eq('', eval("g:testvar"))
meths.input_mouse('left', 'press', '', 0, 5, 8)
eq('', eval("g:testvar"))
meths.input_mouse('right', 'press', '', 0, 6, 4)
eq('0 1 r 10', eval("g:testvar"))
meths.input_mouse('left', 'press', '', 0, 7, 7)
eq('0 1 l 11', eval("g:testvar"))
end)
end)
end end
it('click labels do not leak memory', function() it('click labels do not leak memory', function()