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
} 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)

View File

@ -3,6 +3,7 @@ local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local command = helpers.command
local eq = helpers.eq
local exec = helpers.exec
local eval = helpers.eval
local exec_lua = helpers.exec_lua
local feed = helpers.feed
@ -440,44 +441,81 @@ describe('statuscolumn', function()
end)
for _, model in ipairs(mousemodels) do
it("works with 'statuscolumn' clicks with mousemodel=" .. model, function()
command('set mousemodel=' .. model)
command([[
function! MyClickFunc(minwid, clicks, button, mods)
let g:testvar = printf("%d %d %s %d", a:minwid, a:clicks, a:button, getmousepos().line)
if a:mods !=# ' '
let g:testvar ..= '(' .. a:mods .. ')'
endif
endfunction
set stc=%0@MyClickFunc@%=%l%T
]])
meths.input_mouse('left', 'press', '', 0, 0, 0)
eq('0 1 l 4', eval("g:testvar"))
meths.input_mouse('left', 'press', '', 0, 0, 0)
eq('0 2 l 4', eval("g:testvar"))
meths.input_mouse('left', 'press', '', 0, 0, 0)
eq('0 3 l 4', eval("g:testvar"))
meths.input_mouse('left', 'press', '', 0, 0, 0)
eq('0 4 l 4', eval("g:testvar"))
meths.input_mouse('right', 'press', '', 0, 3, 0)
eq('0 1 r 7', eval("g:testvar"))
meths.input_mouse('right', 'press', '', 0, 3, 0)
eq('0 2 r 7', eval("g:testvar"))
meths.input_mouse('right', 'press', '', 0, 3, 0)
eq('0 3 r 7', eval("g:testvar"))
meths.input_mouse('right', 'press', '', 0, 3, 0)
eq('0 4 r 7', eval("g:testvar"))
command('set laststatus=2 winbar=%f')
command('let g:testvar=""')
-- Check that winbar click doesn't register as statuscolumn click
meths.input_mouse('right', 'press', '', 0, 0, 0)
eq('', eval("g:testvar"))
-- Check that statusline click doesn't register as statuscolumn click
meths.input_mouse('right', 'press', '', 0, 12, 0)
eq('', eval("g:testvar"))
-- Check that cmdline click doesn't register as statuscolumn click
meths.input_mouse('right', 'press', '', 0, 13, 0)
eq('', eval("g:testvar"))
describe('with mousemodel=' .. model, function()
before_each(function()
command('set mousemodel=' .. model)
exec([[
function! MyClickFunc(minwid, clicks, button, mods)
let g:testvar = printf("%d %d %s %d", a:minwid, a:clicks, a:button, getmousepos().line)
if a:mods !=# ' '
let g:testvar ..= '(' .. a:mods .. ')'
endif
endfunction
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)
eq('0 1 l 4', eval("g:testvar"))
meths.input_mouse('left', 'press', '', 0, 0, 0)
eq('0 2 l 4', eval("g:testvar"))
meths.input_mouse('left', 'press', '', 0, 0, 0)
eq('0 3 l 4', eval("g:testvar"))
meths.input_mouse('left', 'press', '', 0, 0, 0)
eq('0 4 l 4', eval("g:testvar"))
meths.input_mouse('right', 'press', '', 0, 3, 0)
eq('0 1 r 7', eval("g:testvar"))
meths.input_mouse('right', 'press', '', 0, 3, 0)
eq('0 2 r 7', eval("g:testvar"))
meths.input_mouse('right', 'press', '', 0, 3, 0)
eq('0 3 r 7', eval("g:testvar"))
meths.input_mouse('right', 'press', '', 0, 3, 0)
eq('0 4 r 7', eval("g:testvar"))
command('set laststatus=2 winbar=%f')
command('let g:testvar = ""')
-- Check that winbar click doesn't register as statuscolumn click
meths.input_mouse('right', 'press', '', 0, 0, 0)
eq('', eval("g:testvar"))
-- Check that statusline click doesn't register as statuscolumn click
meths.input_mouse('right', 'press', '', 0, 12, 0)
eq('', eval("g:testvar"))
-- Check that cmdline click doesn't register as statuscolumn click
meths.input_mouse('right', 'press', '', 0, 13, 0)
eq('', eval("g:testvar"))
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