diff options
Diffstat (limited to 'test/functional/ui')
26 files changed, 929 insertions, 363 deletions
diff --git a/test/functional/ui/bufhl_spec.lua b/test/functional/ui/bufhl_spec.lua index bcccef84b6..f589bb0e83 100644 --- a/test/functional/ui/bufhl_spec.lua +++ b/test/functional/ui/bufhl_spec.lua @@ -31,13 +31,12 @@ describe('Buffer highlighting', function() [14] = {background = Screen.colors.Gray90}, [15] = {background = Screen.colors.Gray90, bold = true, foreground = Screen.colors.Brown}, [16] = {foreground = Screen.colors.Magenta, background = Screen.colors.Gray90}, + [17] = {foreground = Screen.colors.Magenta, background = Screen.colors.LightRed}, + [18] = {background = Screen.colors.LightRed}, + [19] = {foreground = Screen.colors.Blue1, background = Screen.colors.LightRed}, }) end) - after_each(function() - screen:detach() - end) - local add_highlight = curbufmeths.add_highlight local clear_namespace = curbufmeths.clear_namespace @@ -218,6 +217,161 @@ describe('Buffer highlighting', function() | ]]) end) + + it('and adjusting columns', function() + -- insert before + feed('ggiquite <esc>') + screen:expect{grid=[[ + quite^ a {5:longer} example | + in {6:order} to {7:de}{5:monstr}{7:ate} | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]} + + feed('u') + screen:expect{grid=[[ + ^a {5:longer} example | + in {6:order} to {7:de}{5:monstr}{7:ate} | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {1:~ }| + {1:~ }| + 1 change; before #2 {MATCH:.*}| + ]]} + + -- change/insert in the middle + feed('+fesAAAA') + screen:expect{grid=[[ + a {5:longer} example | + in {6:ordAAAA^r} to {7:de}{5:monstr}{7:ate} | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {1:~ }| + {1:~ }| + {7:-- INSERT --} | + ]]} + + feed('<esc>tdD') + screen:expect{grid=[[ + a {5:longer} example | + in {6:ordAAAAr} t^o | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]} + + feed('u') + screen:expect{grid=[[ + a {5:longer} example | + in {6:ordAAAAr} to^ demonstrate | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {1:~ }| + {1:~ }| + 1 change; before #4 {MATCH:.*}| + ]]} + + feed('u') + screen:expect{grid=[[ + a {5:longer} example | + in {6:ord^er} to demonstrate | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {1:~ }| + {1:~ }| + 1 change; before #3 {MATCH:.*}| + ]]} + end) + + it('and joining lines', function() + feed('ggJJJ') + screen:expect{grid=[[ + a {5:longer} example in {6:order} to {7:de}{5:monstr}{7:ate}| + {7: combin}{8:ing hi}{7:ghlights^ }{8:from diff}{7:erent sou}| + {7:rces} | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]} + + -- TODO(bfredl): perhaps better undo + feed('uuu') + screen:expect{grid=[[ + ^a longer example | + in order to demonstrate | + combining highlights | + from different sources | + {1:~ }| + {1:~ }| + {1:~ }| + 1 more line; before #2 {MATCH:.*}| + ]]} + end) + + it('and splitting lines', function() + feed('2Gtti<cr>') + screen:expect{grid=[[ + a {5:longer} example | + in {6:order} | + ^ to {7:de}{5:monstr}{7:ate} | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {1:~ }| + {7:-- INSERT --} | + ]]} + + -- TODO(bfredl): keep both "parts" after split, requires proper extmark ranges + feed('<esc>tsi<cr>') + screen:expect{grid=[[ + a {5:longer} example | + in {6:order} | + to {7:de}{5:mo} | + ^nstrate | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {7:-- INSERT --} | + ]]} + + -- TODO(bfredl): perhaps better undo + feed('<esc>u') + screen:expect{grid=[[ + a {5:longer} example | + in {6:order} | + to demo{7:^nstrat}{8:e} | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {1:~ }| + 1 line less; before #3 {MATCH:.*}| + ]]} + + feed('<esc>u') + screen:expect{grid=[[ + a {5:longer} example | + in order^ to demonstrate | + {7:combin}{8:ing}{9: hi}ghlights | + {9:from }{8:diff}{7:erent} sources | + {1:~ }| + {1:~ }| + {1:~ }| + 1 line less; before #2 {MATCH:.*}| + ]]} + end) end) it('prioritizes latest added highlight', function() @@ -387,6 +541,22 @@ describe('Buffer highlighting', function() ]]) end) + it('can be retrieved', function() + local get_virtual_text = curbufmeths.get_virtual_text + local line_count = curbufmeths.line_count + + local s1 = {{'Köttbullar', 'Comment'}, {'Kräuterbutter'}} + local s2 = {{'こんにちは', 'Comment'}} + + set_virtual_text(-1, 0, s1, {}) + eq(s1, get_virtual_text(0)) + + set_virtual_text(-1, line_count(), s2, {}) + eq(s2, get_virtual_text(line_count())) + + eq({}, get_virtual_text(line_count() + 9000)) + end) + it('is not highlighted by visual selection', function() feed("ggVG") screen:expect([[ @@ -516,6 +686,32 @@ describe('Buffer highlighting', function() | ]]) end) + + it('works with color column', function() + eq(-1, set_virtual_text(-1, 3, {{"暗x事", "Comment"}}, {})) + screen:expect{grid=[[ + ^1 + 2 {3:=}{2: 3} | + 3 + {11:ERROR:} invalid syntax | + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| + , 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s| + x = 4 {12:暗x事} | + {1:~ }| + {1:~ }| + | + ]]} + + command("set colorcolumn=9") + screen:expect{grid=[[ + ^1 + 2 {3:=}{2: }{17:3} | + 3 + {11:ERROR:} invalid syntax | + 5, 5, 5,{18: }5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5| + , 5, 5, 5, 5, 5, 5, Lorem ipsum dolor s| + x = 4 {12:暗}{19:x}{12:事} | + {1:~ }| + {1:~ }| + | + ]]} + end) end) it('and virtual text use the same namespace counter', function() diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua index 052414a43d..9c746b99bd 100644 --- a/test/functional/ui/cmdline_highlight_spec.lua +++ b/test/functional/ui/cmdline_highlight_spec.lua @@ -362,7 +362,7 @@ describe('Command-line coloring', function() {EOB:~ }| :e^ | ]]) - eq('', meths.command_output('messages')) + eq('', meths.exec('messages', true)) end) it('silences :echon', function() set_color_cb('Echoning') @@ -377,7 +377,7 @@ describe('Command-line coloring', function() {EOB:~ }| :e^ | ]]) - eq('', meths.command_output('messages')) + eq('', meths.exec('messages', true)) end) it('silences :echomsg', function() set_color_cb('Echomsging') @@ -392,7 +392,7 @@ describe('Command-line coloring', function() {EOB:~ }| :e^ | ]]) - eq('', meths.command_output('messages')) + eq('', meths.exec('messages', true)) end) it('does the right thing when throwing', function() set_color_cb('Throwing') @@ -857,7 +857,7 @@ describe('Ex commands coloring', function() ]]) feed('<CR>') eq('Error detected while processing :\nE605: Exception not caught: 42\nE749: empty buffer', - meths.command_output('messages')) + meths.exec('messages', true)) end) it('errors out when failing to get callback', function() meths.set_var('Nvim_color_cmdline', 42) diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua index f9769c706f..21c01b3458 100644 --- a/test/functional/ui/cmdline_spec.lua +++ b/test/functional/ui/cmdline_spec.lua @@ -25,10 +25,6 @@ local function test_cmdline(linegrid) screen = new_screen({rgb=true, ext_cmdline=true, ext_linegrid=linegrid}) end) - after_each(function() - screen:detach() - end) - it('works', function() feed(':') screen:expect{grid=[[ @@ -779,7 +775,7 @@ local function test_cmdline(linegrid) }}} -- This used to send an invalid event where pos where larger than the total - -- lenght of content. Checked in _handle_cmdline_show. + -- length of content. Checked in _handle_cmdline_show. feed('<esc>') screen:expect([[ ^ | @@ -804,10 +800,6 @@ describe('cmdline redraw', function() screen = new_screen({rgb=true}) end) - after_each(function() - screen:detach() - end) - it('with timer', function() feed(':012345678901234567890123456789') screen:expect{grid=[[ @@ -829,8 +821,7 @@ describe('cmdline redraw', function() it('with <Cmd>', function() if 'openbsd' == helpers.uname() then - pending('FIXME #10804', function() end) - return + pending('FIXME #10804') end command('cmap a <Cmd>call sin(0)<CR>') -- no-op feed(':012345678901234567890123456789') diff --git a/test/functional/ui/cursor_spec.lua b/test/functional/ui/cursor_spec.lua index 67aba919b0..8ad4182f41 100644 --- a/test/functional/ui/cursor_spec.lua +++ b/test/functional/ui/cursor_spec.lua @@ -13,10 +13,6 @@ describe('ui/cursor', function() screen:attach() end) - after_each(function() - screen:detach() - end) - it("'guicursor' is published as a UI event", function() local expected_mode_info = { [1] = { diff --git a/test/functional/ui/diff_spec.lua b/test/functional/ui/diff_spec.lua index 8eb2bbf779..252991aca7 100644 --- a/test/functional/ui/diff_spec.lua +++ b/test/functional/ui/diff_spec.lua @@ -3,6 +3,8 @@ local Screen = require('test.functional.ui.screen') local feed = helpers.feed local clear = helpers.clear +local command = helpers.command +local insert = helpers.insert local write_file = helpers.write_file describe('Diff mode screen', function() @@ -957,3 +959,75 @@ int main(int argc, char **argv) end) end) end) + +it('win_update redraws lines properly', function() + local screen + clear() + screen = Screen.new(50, 10) + screen:attach() + screen:set_default_attr_ids({ + [1] = {bold = true, foreground = Screen.colors.Blue1}, + [2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, + [3] = {background = Screen.colors.Red, foreground = Screen.colors.Grey100, special = Screen.colors.Yellow}, + [4] = {bold = true, foreground = Screen.colors.SeaGreen4}, + [5] = {special = Screen.colors.Yellow}, + [6] = {special = Screen.colors.Yellow, bold = true, foreground = Screen.colors.SeaGreen4}, + [7] = {foreground = Screen.colors.Grey0, background = Screen.colors.Grey100}, + [8] = {foreground = Screen.colors.Gray90, background = Screen.colors.Grey100}, + [9] = {foreground = tonumber('0x00000c'), background = Screen.colors.Grey100}, + [10] = {background = Screen.colors.Grey100, bold = true, foreground = tonumber('0xe5e5ff')}, + [11] = {background = Screen.colors.Grey100, bold = true, foreground = tonumber('0x2b8452')}, + [12] = {bold = true, reverse = true}, + [13] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray}, + [14] = {reverse = true}, + [15] = {background = Screen.colors.LightBlue}, + [16] = {background = Screen.colors.LightCyan1, bold = true, foreground = Screen.colors.Blue1}, + [17] = {bold = true, background = Screen.colors.Red}, + [18] = {background = Screen.colors.LightMagenta}, + }) + + insert([[ + 1 + + + 2 + 1a + ]]) + command("vnew left") + insert([[ + 2 + 2a + 2b + ]]) + command("windo diffthis") + command("windo 1") + screen:expect{grid=[[ + {13: }{16:-----------------------}{14:│}{13: }{15:^1 }| + {13: }{16:-----------------------}{14:│}{13: }{15: }| + {13: }{16:-----------------------}{14:│}{13: }{15: }| + {13: }2 {14:│}{13: }2 | + {13: }{17:2}{18:a }{14:│}{13: }{17:1}{18:a }| + {13: }{15:2b }{14:│}{13: }{16:----------------------}| + {13: } {14:│}{13: } | + {1:~ }{14:│}{1:~ }| + {14:left [+] }{12:[No Name] [+] }| + | + ]]} + feed('<C-e>') + feed('<C-e>') + feed('<C-y>') + feed('<C-y>') + feed('<C-y>') + screen:expect{grid=[[ + {13: }{16:-----------------------}{14:│}{13: }{15:1 }| + {13: }{16:-----------------------}{14:│}{13: }{15: }| + {13: }{16:-----------------------}{14:│}{13: }{15:^ }| + {13: }2 {14:│}{13: }2 | + {13: }{17:2}{18:a }{14:│}{13: }{17:1}{18:a }| + {13: }{15:2b }{14:│}{13: }{16:----------------------}| + {13: } {14:│}{13: } | + {1:~ }{14:│}{1:~ }| + {14:left [+] }{12:[No Name] [+] }| + | + ]]} +end) diff --git a/test/functional/ui/embed_spec.lua b/test/functional/ui/embed_spec.lua index f3cd223f53..8218c8e12d 100644 --- a/test/functional/ui/embed_spec.lua +++ b/test/functional/ui/embed_spec.lua @@ -50,8 +50,7 @@ local function test_embed(ext_linegrid) it("doesn't erase output when setting color scheme", function() if 'openbsd' == helpers.uname() then - pending('FIXME #10804', function() end) - return + pending('FIXME #10804') end startup('--cmd', 'echoerr "foo"', '--cmd', 'color default', '--cmd', 'echoerr "bar"') screen:expect([[ diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index dbaf6f802b..7a5569c14b 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -2,9 +2,11 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local os = require('os') local clear, feed = helpers.clear, helpers.feed +local assert_alive = helpers.assert_alive local command, feed_command = helpers.command, helpers.feed_command local eval = helpers.eval local eq = helpers.eq +local exec_lua = helpers.exec_lua local insert = helpers.insert local meths = helpers.meths local curbufmeths = helpers.curbufmeths @@ -12,7 +14,7 @@ local funcs = helpers.funcs local run = helpers.run local pcall_err = helpers.pcall_err -describe('floating windows', function() +describe('floatwin', function() before_each(function() clear() end) @@ -39,6 +41,7 @@ describe('floating windows', function() [19] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.WebGray}, [20] = {bold = true, foreground = Screen.colors.Brown}, [21] = {background = Screen.colors.Gray90}, + [22] = {background = Screen.colors.LightRed}, } it('behavior', function() @@ -55,6 +58,31 @@ describe('floating windows', function() eq(1000, funcs.win_getid()) end) + it('closed immediately by autocmd #11383', function() + eq('Error executing lua: [string "<nvim>"]:4: Window was closed immediately', + pcall_err(exec_lua, [[ + local a = vim.api + local function crashes(contents) + local buf = a.nvim_create_buf(false, true) + local floatwin = a.nvim_open_win(buf, true, { + relative = 'cursor'; + style = 'minimal'; + row = 0; col = 0; + height = #contents; + width = 10; + }) + a.nvim_buf_set_lines(buf, 0, -1, true, contents) + local winnr = vim.fn.win_id2win(floatwin) + a.nvim_command('wincmd p') + a.nvim_command('autocmd CursorMoved * ++once '..winnr..'wincmd c') + return buf, floatwin + end + crashes{'foo'} + crashes{'bar'} + ]])) + assert_alive() + end) + local function with_ext_multigrid(multigrid) local screen before_each(function() @@ -398,6 +426,7 @@ describe('floating windows', function() it("can use 'minimal' style", function() command('set number') command('set signcolumn=yes') + command('set colorcolumn=1') command('set cursorline') command('set foldcolumn=1') command('hi NormalFloat guibg=#333333') @@ -414,9 +443,9 @@ describe('floating windows', function() [2:----------------------------------------]| [3:----------------------------------------]| ## grid 2 - {19: }{20: 1 }{21:^x }| - {19: }{14: 2 }y | - {19: }{14: 3 } | + {19: }{20: 1 }{22:^x}{21: }| + {19: }{14: 2 }{22:y} | + {19: }{14: 3 }{22: } | {0:~ }| {0:~ }| {0:~ }| @@ -430,9 +459,9 @@ describe('floating windows', function() ]], float_pos={[4] = {{id = 1001}, "NW", 1, 4, 10, true}}} else screen:expect{grid=[[ - {19: }{20: 1 }{21:^x }| - {19: }{14: 2 }y | - {19: }{14: 3 } {15:x } | + {19: }{20: 1 }{22:^x}{21: }| + {19: }{14: 2 }{22:y} | + {19: }{14: 3 }{22: } {15:x } | {0:~ }{15:y }{0: }| {0:~ }{15: }{0: }| {0:~ }{15: }{0: }| @@ -454,9 +483,9 @@ describe('floating windows', function() [2:----------------------------------------]| [3:----------------------------------------]| ## grid 2 - {19: }{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{21:^x }| - {19: }{14: 2 }y | - {19: }{14: 3 } | + {19: }{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{22:^x}{21: }| + {19: }{14: 2 }{22:y} | + {19: }{14: 3 }{22: } | {0:~ }| {0:~ }| {0:~ }| @@ -471,9 +500,9 @@ describe('floating windows', function() else screen:expect([[ - {19: }{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{21:^x }| - {19: }{14: 2 }y | - {19: }{14: 3 } {17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{15:x } | + {19: }{17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{20: 1 }{22:^x}{21: }| + {19: }{14: 2 }{22:y} | + {19: }{14: 3 }{22: } {17:𐌢̀́̂̃̅̄𐌢̀́̂̃̅̄}{15:x } | {0:~ }{19: }{15:y }{0: }| {0:~ }{19: }{15: }{0: }| {0:~ }{15: }{0: }| @@ -495,9 +524,9 @@ describe('floating windows', function() [2:----------------------------------------]| [3:----------------------------------------]| ## grid 2 - {19: }{20: 1 }{21:^x }| - {19: }{14: 2 }y | - {19: }{14: 3 } | + {19: }{20: 1 }{22:^x}{21: }| + {19: }{14: 2 }{22:y} | + {19: }{14: 3 }{22: } | {0:~ }| {0:~ }| {0:~ }| @@ -511,9 +540,9 @@ describe('floating windows', function() ]], float_pos={[4] = {{id = 1001}, "NW", 1, 4, 10, true}}} else screen:expect([[ - {19: }{20: 1 }{21:^x }| - {19: }{14: 2 }y | - {19: }{14: 3 } {15: } | + {19: }{20: 1 }{22:^x}{21: }| + {19: }{14: 2 }{22:y} | + {19: }{14: 3 }{22: } {15: } | {0:~ }{15: }{0: }| {0:~ }{15: }{0: }| {0:~ }{15: }{0: }| diff --git a/test/functional/ui/fold_spec.lua b/test/functional/ui/fold_spec.lua index c5ef718883..eb81aba131 100644 --- a/test/functional/ui/fold_spec.lua +++ b/test/functional/ui/fold_spec.lua @@ -24,10 +24,6 @@ describe("folded lines", function() }) end) - after_each(function() - screen:detach() - end) - it("work with more than one signcolumn", function() command("set signcolumn=yes:9") feed("i<cr><esc>") diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua index f40f658275..d7791a3107 100644 --- a/test/functional/ui/highlight_spec.lua +++ b/test/functional/ui/highlight_spec.lua @@ -35,7 +35,6 @@ describe('highlight: `:syntax manual`', function() end) after_each(function() - screen:detach() os.remove('Xtest-functional-ui-highlight.tmp.vim') end) @@ -97,10 +96,6 @@ describe('highlight defaults', function() command("set display-=msgsep") end) - after_each(function() - screen:detach() - end) - it('window status bar', function() screen:set_default_attr_ids({ [0] = {bold=true, foreground=Screen.colors.Blue}, @@ -346,17 +341,10 @@ describe('highlight defaults', function() end) describe('highlight', function() - local screen - - before_each(function() - clear() - screen = Screen.new(25,10) - screen:attach() - end) + before_each(clear) it('visual', function() - screen:detach() - screen = Screen.new(20,4) + local screen = Screen.new(20,4) screen:attach() screen:set_default_attr_ids({ [1] = {background = Screen.colors.LightGrey}, @@ -389,8 +377,7 @@ describe('highlight', function() end) it('cterm=standout gui=standout', function() - screen:detach() - screen = Screen.new(20,5) + local screen = Screen.new(20,5) screen:attach() screen:set_default_attr_ids({ [1] = {bold = true, foreground = Screen.colors.Blue1}, @@ -413,8 +400,7 @@ describe('highlight', function() end) it('strikethrough', function() - screen:detach() - screen = Screen.new(25,6) + local screen = Screen.new(25,6) screen:attach() feed_command('syntax on') feed_command('syn keyword TmpKeyword foo') @@ -438,7 +424,56 @@ describe('highlight', function() }) end) + it('nocombine', function() + local screen = Screen.new(25,6) + screen:set_default_attr_ids{ + [1] = {foreground = Screen.colors.SlateBlue, underline = true}, + [2] = {bold = true, foreground = Screen.colors.Blue1}, + [3] = {underline = true, reverse = true, foreground = Screen.colors.SlateBlue}, + [4] = {background = Screen.colors.Yellow, reverse = true, foreground = Screen.colors.SlateBlue}, + [5] = {foreground = Screen.colors.Red}, + } + screen:attach() + feed_command('syntax on') + feed_command('hi! Underlined cterm=underline gui=underline') + feed_command('syn keyword Underlined foobar') + feed_command('hi Search cterm=inverse,nocombine gui=inverse,nocombine') + insert([[ + foobar + foobar + ]]) + screen:expect{grid=[[ + {1:foobar} | + {1:foobar} | + ^ | + {2:~ }| + {2:~ }| + | + ]]} + + feed('/foo') + screen:expect{grid=[[ + {3:foo}{1:bar} | + {4:foo}{1:bar} | + | + {2:~ }| + {2:~ }| + /foo^ | + ]]} + feed('<cr>') + screen:expect{grid=[[ + {4:^foo}{1:bar} | + {4:foo}{1:bar} | + | + {2:~ }| + {2:~ }| + {5:search hit...uing at TOP} | + ]]} + end) + it('guisp (special/undercurl)', function() + local screen = Screen.new(25,10) + screen:attach() feed_command('syntax on') feed_command('syn keyword TmpKeyword neovim') feed_command('syn keyword TmpKeyword1 special') @@ -494,10 +529,6 @@ describe("'listchars' highlight", function() screen:attach() end) - after_each(function() - screen:detach() - end) - it("'cursorline' and 'cursorcolumn'", function() screen:set_default_attr_ids({ [0] = {bold=true, foreground=Screen.colors.Blue}, @@ -657,6 +688,30 @@ describe("'listchars' highlight", function() ]]) end) + it("'listchar' with wrap", function() + screen:set_default_attr_ids({ + [0] = {bold=true, foreground=Screen.colors.Blue}, + }) + feed_command('set wrap') + feed_command('set listchars=eol:¬,precedes:< list') + feed('90ia<esc>') + screen:expect([[ + {0:<}aaaaaaaaaaaaaaaaaaa| + aaaaaaaaaaaaaaaaaaaa| + aaaaaaaaaaaaaaaaaaaa| + aaaaaaaaa^a{0:¬} | + | + ]]) + feed('0') + screen:expect([[ + ^aaaaaaaaaaaaaaaaaaaa| + aaaaaaaaaaaaaaaaaaaa| + aaaaaaaaaaaaaaaaaaaa| + aaaaaaaaaaaaaaaaaaaa| + | + ]]) + end) + it("'listchar' in visual mode", function() screen:set_default_attr_ids({ [1] = {background=Screen.colors.Grey90}, diff --git a/test/functional/ui/hlstate_spec.lua b/test/functional/ui/hlstate_spec.lua index d1c115587e..2a567b28ee 100644 --- a/test/functional/ui/hlstate_spec.lua +++ b/test/functional/ui/hlstate_spec.lua @@ -181,11 +181,11 @@ describe('ext_hlstate detailed highlights', function() it("work with :terminal", function() screen:set_default_attr_ids({ [1] = {{}, {{hi_name = "TermCursorNC", ui_name = "TermCursorNC", kind = "ui"}}}, - [2] = {{foreground = 52479}, {{kind = "term"}}}, - [3] = {{bold = true, foreground = 52479}, {{kind = "term"}}}, - [4] = {{foreground = 52479}, {2, 1}}, - [5] = {{foreground = 4259839}, {{kind = "term"}}}, - [6] = {{foreground = 4259839}, {5, 1}}, + [2] = {{foreground = tonumber('0x00ccff'), fg_indexed=true}, {{kind = "term"}}}, + [3] = {{bold = true, foreground = tonumber('0x00ccff'), fg_indexed=true}, {{kind = "term"}}}, + [4] = {{foreground = tonumber('0x00ccff'), fg_indexed=true}, {2, 1}}, + [5] = {{foreground = tonumber('0x40ffff'), fg_indexed=true}, {{kind = "term"}}}, + [6] = {{foreground = tonumber('0x40ffff'), fg_indexed=true}, {5, 1}}, [7] = {{}, {{hi_name = "MsgArea", ui_name = "MsgArea", kind = "ui"}}}, }) command('enew | call termopen(["'..nvim_dir..'/tty-test"])') @@ -259,7 +259,7 @@ describe('ext_hlstate detailed highlights', function() it("can use independent cterm and rgb colors", function() -- tell test module to save all attributes (doesn't change nvim options) - screen:set_hlstate_cterm(true) + screen:set_rgb_cterm(true) screen:set_default_attr_ids({ [1] = {{bold = true, foreground = Screen.colors.Blue1}, {foreground = 12}, {{hi_name = "NonText", ui_name = "EndOfBuffer", kind = "ui"}}}, diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua index 351c4b4bcf..b841574643 100644 --- a/test/functional/ui/inccommand_spec.lua +++ b/test/functional/ui/inccommand_spec.lua @@ -88,14 +88,14 @@ local function common_setup(screen, inccommand, text) }) end - command("set inccommand=" .. (inccommand and inccommand or "")) + command("set inccommand=" .. (inccommand or "")) if text then insert(text) end end -describe(":substitute, inccommand=split", function() +describe(":substitute, inccommand=split interactivity", function() before_each(function() clear() common_setup(nil, "split", default_text) @@ -556,7 +556,6 @@ describe(":substitute, 'inccommand' preserves undo", function() ]]) end end - screen:detach() end) it('with undolevels=2', function() @@ -647,7 +646,6 @@ describe(":substitute, 'inccommand' preserves undo", function() Already ...t change | ]]) end - screen:detach() end end) @@ -713,7 +711,6 @@ describe(":substitute, 'inccommand' preserves undo", function() Already ...t change | ]]) end - screen:detach() end) end) @@ -726,19 +723,15 @@ describe(":substitute, inccommand=split", function() common_setup(screen, "split", default_text .. default_text) end) - after_each(function() - screen:detach() - end) - it("preserves 'modified' buffer flag", function() feed_command("set nomodified") feed(":%s/tw") screen:expect([[ Inc substitution on | {12:tw}o lines | + Inc substitution on | + {12:tw}o lines | | - {15:~ }| - {15:~ }| {11:[No Name] }| |2| {12:tw}o lines | |4| {12:tw}o lines | @@ -786,6 +779,59 @@ describe(":substitute, inccommand=split", function() {15:~ }| :silent tabedit %s/tw/to^ | ]]) + feed('<Esc>') + + -- leading colons + feed(':::%s/tw/to') + screen:expect{any=[[{12:to}o lines]]} + feed('<Esc>') + screen:expect{any=[[two lines]]} + end) + + it("ignores new-window modifiers when splitting the preview window", function() + -- one modifier + feed(':topleft %s/tw/to') + screen:expect([[ + Inc substitution on | + {12:to}o lines | + Inc substitution on | + {12:to}o lines | + | + {11:[No Name] [+] }| + |2| {12:to}o lines | + |4| {12:to}o lines | + {15:~ }| + {15:~ }| + {15:~ }| + {15:~ }| + {15:~ }| + {10:[Preview] }| + :topleft %s/tw/to^ | + ]]) + feed('<Esc>') + screen:expect{any=[[two lines]]} + + -- multiple modifiers + feed(':topleft vert %s/tw/to') + screen:expect([[ + Inc substitution on | + {12:to}o lines | + Inc substitution on | + {12:to}o lines | + | + {11:[No Name] [+] }| + |2| {12:to}o lines | + |4| {12:to}o lines | + {15:~ }| + {15:~ }| + {15:~ }| + {15:~ }| + {15:~ }| + {10:[Preview] }| + :topleft vert %s/tw/to^ | + ]]) + feed('<Esc>') + screen:expect{any=[[two lines]]} end) it('shows split window when typing the pattern', function() @@ -793,9 +839,9 @@ describe(":substitute, inccommand=split", function() screen:expect([[ Inc substitution on | {12:tw}o lines | + Inc substitution on | + {12:tw}o lines | | - {15:~ }| - {15:~ }| {11:[No Name] [+] }| |2| {12:tw}o lines | |4| {12:tw}o lines | @@ -814,9 +860,9 @@ describe(":substitute, inccommand=split", function() screen:expect([[ Inc substitution on | o lines | + Inc substitution on | + o lines | | - {15:~ }| - {15:~ }| {11:[No Name] [+] }| |2| o lines | |4| o lines | @@ -833,9 +879,9 @@ describe(":substitute, inccommand=split", function() screen:expect([[ Inc substitution on | {12:x}o lines | + Inc substitution on | + {12:x}o lines | | - {15:~ }| - {15:~ }| {11:[No Name] [+] }| |2| {12:x}o lines | |4| {12:x}o lines | @@ -852,9 +898,9 @@ describe(":substitute, inccommand=split", function() screen:expect([[ Inc substitution on | o lines | + Inc substitution on | + o lines | | - {15:~ }| - {15:~ }| {11:[No Name] [+] }| |2| o lines | |4| o lines | @@ -874,9 +920,9 @@ describe(":substitute, inccommand=split", function() screen:expect([[ Inc substitution on | {12:XX}o lines | + Inc substitution on | + {12:XX}o lines | | - {15:~ }| - {15:~ }| {11:[No Name] [+] }| |2| {12:XX}o lines | |4| {12:XX}o lines | @@ -938,11 +984,11 @@ describe(":substitute, inccommand=split", function() feed(":%s/tw") -- 'cursorline' is NOT active during preview. screen:expect([[ + Inc substitution on | {12:tw}o lines | Inc substitution on | {12:tw}o lines | | - {15:~ }| {11:[No Name] [+] }| |2| {12:tw}o lines | |4| {12:tw}o lines | @@ -1241,10 +1287,6 @@ describe("inccommand=nosplit", function() common_setup(screen, "nosplit", default_text .. default_text) end) - after_each(function() - if screen then screen:detach() end - end) - it("works with :smagic, :snomagic", function() feed_command("set hlsearch") insert("Line *.3.* here") @@ -1719,10 +1761,6 @@ describe("'inccommand' split windows", function() common_setup(screen, "split", default_text) end - after_each(function() - screen:detach() - end) - it('work after more splits', function() refresh() @@ -2205,11 +2243,11 @@ describe(":substitute", function() feed("/KKK") screen:expect([[ + T T123 T T123 T2T TT T23423424| + x | afa {12:KKK}adf la;lkd {12:KKK}alx | | {15:~ }| - {15:~ }| - {15:~ }| {11:[No Name] [+] }| |3| afa {12:KKK}adf la;lkd {12:KKK}alx | {15:~ }| @@ -2485,11 +2523,11 @@ describe(":substitute", function() wait() feed([[:%s/\(some\)\@<lt>!thing/one/]]) screen:expect([[ + something | every{12:one} | someone | {15:~ }| {15:~ }| - {15:~ }| {11:[No Name] [+] }| |2| every{12:one} | {15:~ }| @@ -2527,11 +2565,11 @@ describe(":substitute", function() wait() feed([[:%s/some\(thing\)\@!/every/]]) screen:expect([[ + something | + everything | {12:every}one | {15:~ }| {15:~ }| - {15:~ }| - {15:~ }| {11:[No Name] [+] }| |3| {12:every}one | {15:~ }| @@ -2544,6 +2582,49 @@ describe(":substitute", function() :%s/some\(thing\)\@!/every/^ | ]]) end) + + it("doesn't prompt to swap cmd range", function() + screen = Screen.new(50, 8) -- wide to avoid hit-enter prompt + common_setup(screen, "split", default_text) + feed(':2,1s/tw/MO/g') + + -- substitution preview should have been made, without prompting + screen:expect([[ + {12:MO}o lines | + {11:[No Name] [+] }| + |2| {12:MO}o lines | + {15:~ }| + {15:~ }| + {15:~ }| + {10:[Preview] }| + :2,1s/tw/MO/g^ | + ]]) + + -- but should be prompted on hitting enter + feed('<CR>') + screen:expect([[ + {12:MO}o lines | + {11:[No Name] [+] }| + |2| {12:MO}o lines | + {15:~ }| + {15:~ }| + {15:~ }| + {10:[Preview] }| + {13:Backwards range given, OK to swap (y/n)?}^ | + ]]) + + feed('y') + screen:expect([[ + Inc substitution on | + ^MOo lines | + | + {15:~ }| + {15:~ }| + {15:~ }| + {15:~ }| + {13:Backwards range given, OK to swap (y/n)?}y | + ]]) + end) end) it(':substitute with inccommand during :terminal activity', function() diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua index 875e4092a6..25b38b1feb 100644 --- a/test/functional/ui/messages_spec.lua +++ b/test/functional/ui/messages_spec.lua @@ -122,7 +122,7 @@ describe('ui/ext_messages', function() feed('G$x') screen:expect{grid=[[ line 1 | - {IGNORE}| + {MATCH:.*}| {1:~ }| {1:~ }| {1:~ }| @@ -747,7 +747,7 @@ describe('ui/ext_messages', function() {1:~ }| {1:~ }| ]], messages={{ - content = {{'E5105: Error while calling lua chunk: [string "<VimL compiled string>"]:1: such\nmultiline\nerror', 2}}, + content = {{'E5108: Error executing lua [string ":lua"]:1: such\nmultiline\nerror', 2}}, kind = "lua_error" }}} end) @@ -810,6 +810,7 @@ describe('ui/builtin messages', function() [4] = {bold = true, foreground = Screen.colors.SeaGreen4}, [5] = {foreground = Screen.colors.Blue1}, [6] = {bold = true, foreground = Screen.colors.Magenta}, + [7] = {background = Screen.colors.Grey20}, }) end) @@ -860,7 +861,7 @@ describe('ui/builtin messages', function() -- screen size doesn't affect internal output #10285 eq('ErrorMsg xxx ctermfg=15 ctermbg=1 guifg=White guibg=Red', - meths.command_output("hi ErrorMsg")) + meths.exec("hi ErrorMsg", true)) end) it(':syntax list langGroup output', function() @@ -899,9 +900,44 @@ vimComment xxx match /\s"[^\-:.%#=*].*$/ms=s+1,lc=1 excludenl contains=@vim match /\<endif\s\+".*$/ms=s+5,lc=5 contains=@vimCommentGroup,vimCommentString match /\<else\s\+".*$/ms=s+4,lc=4 contains=@vimCommentGroup,vimCommentString links to Comment]], - meths.command_output('syntax list vimComment')) + meths.exec('syntax list vimComment', true)) -- luacheck: pop end) + + it('supports ruler with laststatus=0', function() + command("set ruler laststatus=0") + screen:expect{grid=[[ + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + 0,0-1 All | + ]]} + + command("hi MsgArea guibg=#333333") + screen:expect{grid=[[ + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {7: 0,0-1 All }| + ]]} + + command("set rulerformat=%15(%c%V\\ %p%%%)") + screen:expect{grid=[[ + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {7: 0,0-1 100% }| + ]]} + end) end) describe('ui/ext_messages', function() @@ -930,7 +966,7 @@ describe('ui/ext_messages', function() {1:~ }| {1:~ }| {1:~ }| - {IGNORE}| + {MATCH:.*}| {1:~ }| {1:~ }Nvim is open source and freely distributable{1: }| {1:~ }https://neovim.io/#chat{1: }| @@ -940,8 +976,8 @@ describe('ui/ext_messages', function() {1:~ }type :q{5:<Enter>} to exit {1: }| {1:~ }type :help{5:<Enter>} for help {1: }| {1:~ }| - {IGNORE}| - {IGNORE}| + {MATCH:.*}| + {MATCH:.*}| {1:~ }| {1:~ }| {1:~ }| @@ -986,7 +1022,7 @@ describe('ui/ext_messages', function() | | | - {IGNORE}| + {MATCH:.*}| | Nvim is open source and freely distributable | https://neovim.io/#chat | @@ -996,8 +1032,8 @@ describe('ui/ext_messages', function() type :q{5:<Enter>} to exit | type :help{5:<Enter>} for help | | - {IGNORE}| - {IGNORE}| + {MATCH:.*}| + {MATCH:.*}| | | | @@ -1089,7 +1125,7 @@ aliquip ex ea commodo consequat.]]) it('can be quit', function() screen:try_resize(25,5) - feed(':echon join(map(range(0, &lines*2), "v:val"), "\\n")<cr>') + feed(':echon join(map(range(0, &lines*10), "v:val"), "\\n")<cr>') screen:expect{grid=[[ 0 | 1 | @@ -1110,97 +1146,96 @@ aliquip ex ea commodo consequat.]]) it('handles wrapped lines with line scroll', function() feed(':lua error(_G.x)<cr>') screen:expect{grid=[[ - {2:E5105: Error while calling lua chun}| - {2:k: [string "<VimL compiled string>"}| - {2:]:1: Lorem ipsum dolor sit amet, co}| - {2:nsectetur} | + {2:E5108: Error executing lua [string }| + {2:":lua"]:1: Lorem ipsum dolor sit am}| + {2:et, consectetur} | {2:adipisicing elit, sed do eiusmod te}| {2:mpor} | {2:incididunt ut labore et dolore magn}| + {2:a aliqua.} | {4:-- More --}^ | ]]} feed('j') screen:expect{grid=[[ - {2:k: [string "<VimL compiled string>"}| - {2:]:1: Lorem ipsum dolor sit amet, co}| - {2:nsectetur} | + {2:":lua"]:1: Lorem ipsum dolor sit am}| + {2:et, consectetur} | {2:adipisicing elit, sed do eiusmod te}| {2:mpor} | {2:incididunt ut labore et dolore magn}| {2:a aliqua.} | + {2:Ut enim ad minim veniam, quis nostr}| {4:-- More --}^ | ]]} feed('k') screen:expect{grid=[[ - {2:E5105: Error while calling lua chun}| - {2:k: [string "<VimL compiled string>"}| - {2:]:1: Lorem ipsum dolor sit amet, co}| - {2:nsectetur} | + {2:E5108: Error executing lua [string }| + {2:":lua"]:1: Lorem ipsum dolor sit am}| + {2:et, consectetur} | {2:adipisicing elit, sed do eiusmod te}| {2:mpor} | {2:incididunt ut labore et dolore magn}| + {2:a aliqua.} | {4:-- More --}^ | ]]} feed('j') screen:expect{grid=[[ - {2:k: [string "<VimL compiled string>"}| - {2:]:1: Lorem ipsum dolor sit amet, co}| - {2:nsectetur} | + {2:":lua"]:1: Lorem ipsum dolor sit am}| + {2:et, consectetur} | {2:adipisicing elit, sed do eiusmod te}| {2:mpor} | {2:incididunt ut labore et dolore magn}| {2:a aliqua.} | + {2:Ut enim ad minim veniam, quis nostr}| {4:-- More --}^ | ]]} - end) it('handles wrapped lines with page scroll', function() feed(':lua error(_G.x)<cr>') screen:expect{grid=[[ - {2:E5105: Error while calling lua chun}| - {2:k: [string "<VimL compiled string>"}| - {2:]:1: Lorem ipsum dolor sit amet, co}| - {2:nsectetur} | + {2:E5108: Error executing lua [string }| + {2:":lua"]:1: Lorem ipsum dolor sit am}| + {2:et, consectetur} | {2:adipisicing elit, sed do eiusmod te}| {2:mpor} | {2:incididunt ut labore et dolore magn}| + {2:a aliqua.} | {4:-- More --}^ | ]]} feed('d') screen:expect{grid=[[ - {2:adipisicing elit, sed do eiusmod te}| - {2:mpor} | {2:incididunt ut labore et dolore magn}| {2:a aliqua.} | {2:Ut enim ad minim veniam, quis nostr}| {2:ud xercitation} | {2:ullamco laboris nisi ut} | - {4:-- More --}^ | + {2:aliquip ex ea commodo consequat.} | + {4:Press ENTER or type command to cont}| + {4:inue}^ | ]]} feed('u') screen:expect{grid=[[ - {2:E5105: Error while calling lua chun}| - {2:k: [string "<VimL compiled string>"}| - {2:]:1: Lorem ipsum dolor sit amet, co}| - {2:nsectetur} | + {2:E5108: Error executing lua [string }| + {2:":lua"]:1: Lorem ipsum dolor sit am}| + {2:et, consectetur} | {2:adipisicing elit, sed do eiusmod te}| {2:mpor} | {2:incididunt ut labore et dolore magn}| + {2:a aliqua.} | {4:-- More --}^ | ]]} feed('d') screen:expect{grid=[[ - {2:adipisicing elit, sed do eiusmod te}| {2:mpor} | {2:incididunt ut labore et dolore magn}| {2:a aliqua.} | {2:Ut enim ad minim veniam, quis nostr}| {2:ud xercitation} | {2:ullamco laboris nisi ut} | + {2:aliquip ex ea commodo consequat.} | {4:-- More --}^ | ]]} end) @@ -1210,49 +1245,49 @@ aliquip ex ea commodo consequat.]]) feed(':lua error(_G.x)<cr>') screen:expect{grid=[[ - {3:E5105: Error while calling lua chun}| - {3:k: [string "<VimL compiled string>"}| - {3:]:1: Lorem ipsum dolor sit amet, co}| - {3:nsectetur}{5: }| + {3:E5108: Error executing lua [string }| + {3:":lua"]:1: Lorem ipsum dolor sit am}| + {3:et, consectetur}{5: }| {3:adipisicing elit, sed do eiusmod te}| {3:mpor}{5: }| {3:incididunt ut labore et dolore magn}| + {3:a aliqua.}{5: }| {6:-- More --}{5:^ }| ]]} feed('j') screen:expect{grid=[[ - {3:k: [string "<VimL compiled string>"}| - {3:]:1: Lorem ipsum dolor sit amet, co}| - {3:nsectetur}{5: }| + {3:":lua"]:1: Lorem ipsum dolor sit am}| + {3:et, consectetur}{5: }| {3:adipisicing elit, sed do eiusmod te}| {3:mpor}{5: }| {3:incididunt ut labore et dolore magn}| {3:a aliqua.}{5: }| + {3:Ut enim ad minim veniam, quis nostr}| {6:-- More --}{5:^ }| ]]} feed('k') screen:expect{grid=[[ - {3:E5105: Error while calling lua chun}| - {3:k: [string "<VimL compiled string>"}| - {3:]:1: Lorem ipsum dolor sit amet, co}| - {3:nsectetur}{5: }| + {3:E5108: Error executing lua [string }| + {3:":lua"]:1: Lorem ipsum dolor sit am}| + {3:et, consectetur}{5: }| {3:adipisicing elit, sed do eiusmod te}| {3:mpor}{5: }| {3:incididunt ut labore et dolore magn}| + {3:a aliqua.}{5: }| {6:-- More --}{5:^ }| ]]} feed('j') screen:expect{grid=[[ - {3:k: [string "<VimL compiled string>"}| - {3:]:1: Lorem ipsum dolor sit amet, co}| - {3:nsectetur}{5: }| + {3:":lua"]:1: Lorem ipsum dolor sit am}| + {3:et, consectetur}{5: }| {3:adipisicing elit, sed do eiusmod te}| {3:mpor}{5: }| {3:incididunt ut labore et dolore magn}| {3:a aliqua.}{5: }| + {3:Ut enim ad minim veniam, quis nostr}| {6:-- More --}{5:^ }| ]]} end) @@ -1261,46 +1296,46 @@ aliquip ex ea commodo consequat.]]) command("hi MsgArea guisp=Yellow") feed(':lua error(_G.x)<cr>') screen:expect{grid=[[ - {3:E5105: Error while calling lua chun}| - {3:k: [string "<VimL compiled string>"}| - {3:]:1: Lorem ipsum dolor sit amet, co}| - {3:nsectetur}{5: }| + {3:E5108: Error executing lua [string }| + {3:":lua"]:1: Lorem ipsum dolor sit am}| + {3:et, consectetur}{5: }| {3:adipisicing elit, sed do eiusmod te}| {3:mpor}{5: }| {3:incididunt ut labore et dolore magn}| + {3:a aliqua.}{5: }| {6:-- More --}{5:^ }| ]]} feed('d') screen:expect{grid=[[ - {3:adipisicing elit, sed do eiusmod te}| - {3:mpor}{5: }| {3:incididunt ut labore et dolore magn}| {3:a aliqua.}{5: }| {3:Ut enim ad minim veniam, quis nostr}| {3:ud xercitation}{5: }| {3:ullamco laboris nisi ut}{5: }| - {6:-- More --}{5:^ }| + {3:aliquip ex ea commodo consequat.}{5: }| + {6:Press ENTER or type command to cont}| + {6:inue}{5:^ }| ]]} feed('u') screen:expect{grid=[[ - {3:E5105: Error while calling lua chun}| - {3:k: [string "<VimL compiled string>"}| - {3:]:1: Lorem ipsum dolor sit amet, co}| - {3:nsectetur}{5: }| + {3:E5108: Error executing lua [string }| + {3:":lua"]:1: Lorem ipsum dolor sit am}| + {3:et, consectetur}{5: }| {3:adipisicing elit, sed do eiusmod te}| {3:mpor}{5: }| {3:incididunt ut labore et dolore magn}| + {3:a aliqua.}{5: }| {6:-- More --}{5:^ }| ]]} feed('d') screen:expect{grid=[[ - {3:adipisicing elit, sed do eiusmod te}| {3:mpor}{5: }| {3:incididunt ut labore et dolore magn}| {3:a aliqua.}{5: }| {3:Ut enim ad minim veniam, quis nostr}| {3:ud xercitation}{5: }| {3:ullamco laboris nisi ut}{5: }| + {3:aliquip ex ea commodo consequat.}{5: }| {6:-- More --}{5:^ }| ]]} end) @@ -1437,23 +1472,23 @@ aliquip ex ea commodo consequat.]]) it('can be resized', function() feed(':lua error(_G.x)<cr>') screen:expect{grid=[[ - {2:E5105: Error while calling lua chun}| - {2:k: [string "<VimL compiled string>"}| - {2:]:1: Lorem ipsum dolor sit amet, co}| - {2:nsectetur} | + {2:E5108: Error executing lua [string }| + {2:":lua"]:1: Lorem ipsum dolor sit am}| + {2:et, consectetur} | {2:adipisicing elit, sed do eiusmod te}| {2:mpor} | {2:incididunt ut labore et dolore magn}| + {2:a aliqua.} | {4:-- More --}^ | ]]} -- responds to resize, but text is not reflown screen:try_resize(45, 5) screen:expect{grid=[[ - {2:nsectetur} | {2:adipisicing elit, sed do eiusmod te} | {2:mpor} | {2:incididunt ut labore et dolore magn} | + {2:a aliqua.} | {4:-- More --}^ | ]]} @@ -1461,14 +1496,14 @@ aliquip ex ea commodo consequat.]]) -- text is not reflown; existing lines get cut screen:try_resize(30, 12) screen:expect{grid=[[ - {2:E5105: Error while calling lua}| - {2:k: [string "<VimL compiled str}| - {2:]:1: Lorem ipsum dolor sit ame}| - {2:nsectetur} | + {2:E5108: Error executing lua [st}| + {2:":lua"]:1: Lorem ipsum dolor s}| + {2:et, consectetur} | {2:adipisicing elit, sed do eiusm}| {2:mpore} | {2:incididunt ut labore et dolore}| - {2: magn} | + {2:a aliqua.} | + | | | | @@ -1479,18 +1514,18 @@ aliquip ex ea commodo consequat.]]) -- wrapped at the new screen size. feed('<cr>') screen:expect{grid=[[ - {2:k: [string "<VimL compiled str}| - {2:]:1: Lorem ipsum dolor sit ame}| - {2:nsectetur} | + {2:et, consectetur} | {2:adipisicing elit, sed do eiusm}| {2:mpore} | {2:incididunt ut labore et dolore}| - {2: magna aliqua.} | + {2:a aliqua.} | {2:Ut enim ad minim veniam, quis }| {2:nostrud xercitation} | {2:ullamco laboris nisi ut} | {2:aliquip ex ea commodo consequa}| - {4:-- More --}^ | + {2:t.} | + {4:Press ENTER or type command to}| + {4: continue}^ | ]]} feed('q') diff --git a/test/functional/ui/mode_spec.lua b/test/functional/ui/mode_spec.lua index 200f6eecdb..9390f268b3 100644 --- a/test/functional/ui/mode_spec.lua +++ b/test/functional/ui/mode_spec.lua @@ -3,6 +3,7 @@ local Screen = require('test.functional.ui.screen') local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert local command = helpers.command +local retry = helpers.retry describe('ui mode_change event', function() local screen @@ -61,30 +62,36 @@ describe('ui mode_change event', function() | ]], mode="normal"} + local matchtime = 0 command("set showmatch") - command("set matchtime=2") -- tenths of seconds - feed('a(stuff') - screen:expect{grid=[[ - word(stuff^ | - {0:~ }| - {0:~ }| - {2:-- INSERT --} | - ]], mode="insert"} - - feed(')') - screen:expect{grid=[[ - word^(stuff) | - {0:~ }| - {0:~ }| - {2:-- INSERT --} | - ]], mode="showmatch"} - - screen:expect{grid=[[ - word(stuff)^ | - {0:~ }| - {0:~ }| - {2:-- INSERT --} | - ]], mode="insert"} + retry(nil, nil, function() + matchtime = matchtime + 1 + local screen_timeout = 1000 * matchtime -- fail faster for retry. + + command("set matchtime=" .. matchtime) -- tenths of seconds + feed('a(stuff') + screen:expect{grid=[[ + word(stuff^ | + {0:~ }| + {0:~ }| + {2:-- INSERT --} | + ]], mode="insert", timeout=screen_timeout} + + feed(')') + screen:expect{grid=[[ + word^(stuff) | + {0:~ }| + {0:~ }| + {2:-- INSERT --} | + ]], mode="showmatch", timeout=screen_timeout} + + screen:expect{grid=[[ + word(stuff)^ | + {0:~ }| + {0:~ }| + {2:-- INSERT --} | + ]], mode="insert", timeout=screen_timeout} + end) end) it('works in replace mode', function() diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua index 3bd6b81ff1..d857b57a31 100644 --- a/test/functional/ui/mouse_spec.lua +++ b/test/functional/ui/mouse_spec.lua @@ -12,7 +12,10 @@ describe('ui/mouse/input', function() clear() meths.set_option('mouse', 'a') meths.set_option('list', true) - meths.set_option('listchars', 'eol:$') + -- NB: this is weird, but mostly irrelevant to the test + -- So I didn't bother to change it + command('set listchars=eol:$') + command('setl listchars=nbsp:x') screen = Screen.new(25, 5) screen:attach() screen:set_default_attr_ids({ @@ -26,6 +29,8 @@ describe('ui/mouse/input', function() }, [4] = {reverse = true}, [5] = {bold = true, reverse = true}, + [6] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, + [7] = {bold = true, foreground = Screen.colors.SeaGreen4}, }) command("set display-=msgsep") feed('itesting<cr>mouse<cr>support and selection<esc>') @@ -38,10 +43,6 @@ describe('ui/mouse/input', function() ]]) end) - after_each(function() - screen:detach() - end) - it('single left click moves cursor', function() feed('<LeftMouse><2,1>') screen:expect([[ @@ -419,9 +420,9 @@ describe('ui/mouse/input', function() meths.set_option('showtabline', 2) screen:expect([[ {fill:test-test2 }| + testing | mouse | support and selectio^n | - {0:~ }| | ]]) meths.set_var('reply', {}) @@ -539,9 +540,9 @@ describe('ui/mouse/input', function() feed_command('tabprevious') -- go to first tab screen:expect([[ {sel: + foo }{tab: + bar }{fill: }{tab:X}| + testing | mouse | support and selectio^n | - {0:~ }| :tabprevious | ]]) feed('<LeftMouse><10,0><LeftRelease>') -- go to second tab @@ -620,12 +621,12 @@ describe('ui/mouse/input', function() meths.set_option('tags', './non-existent-tags-file') feed('<C-LeftMouse><0,0>') screen:expect([[ - E433: No tags file | - E426: tag not found: test| - ing | - Press ENTER or type comma| - nd to continue^ | - ]],nil,true) + {6:E433: No tags file} | + {6:E426: tag not found: test}| + {6:ing} | + {7:Press ENTER or type comma}| + {7:nd to continue}^ | + ]]) feed('<cr>') end) @@ -814,7 +815,8 @@ describe('ui/mouse/input', function() feed_command('set concealcursor=ni') feed_command('set nowrap') - feed_command('set shiftwidth=2 tabstop=4 list listchars=tab:>-') + feed_command('set shiftwidth=2 tabstop=4 list') + feed_command('setl listchars=tab:>-') feed_command('syntax match NonText "\\*" conceal') feed_command('syntax match NonText "cats" conceal cchar=X') feed_command('syntax match NonText "x" conceal cchar=>') diff --git a/test/functional/ui/multibyte_spec.lua b/test/functional/ui/multibyte_spec.lua index 3e63353ad2..8122cb08a3 100644 --- a/test/functional/ui/multibyte_spec.lua +++ b/test/functional/ui/multibyte_spec.lua @@ -21,10 +21,6 @@ describe("multibyte rendering", function() }) end) - after_each(function() - screen:detach() - end) - it("works with composed char at start of line", function() insert([[ ̊ @@ -131,10 +127,6 @@ describe('multibyte rendering: statusline', function() command('set laststatus=2') end) - after_each(function() - screen:detach() - end) - it('last char shows (multibyte)', function() command('set statusline=你好') screen:expect([[ diff --git a/test/functional/ui/multigrid_spec.lua b/test/functional/ui/multigrid_spec.lua index 30a5b63d89..01ffe80be3 100644 --- a/test/functional/ui/multigrid_spec.lua +++ b/test/functional/ui/multigrid_spec.lua @@ -37,10 +37,6 @@ describe('ext_multigrid', function() }) end) - after_each(function() - screen:detach() - end) - it('default initial screen', function() screen:expect{grid=[[ ## grid 1 diff --git a/test/functional/ui/options_spec.lua b/test/functional/ui/options_spec.lua index 93192934c7..581e196bbb 100644 --- a/test/functional/ui/options_spec.lua +++ b/test/functional/ui/options_spec.lua @@ -5,7 +5,7 @@ local command = helpers.command local eq = helpers.eq local shallowcopy = helpers.shallowcopy -describe('ui receives option updates', function() +describe('UI receives option updates', function() local screen local function reset(opts, ...) @@ -40,10 +40,6 @@ describe('ui receives option updates', function() return defaults end - after_each(function() - screen:detach() - end) - it("for defaults", function() local expected = reset() screen:expect(function() @@ -51,6 +47,33 @@ describe('ui receives option updates', function() end) end) + it('on attach #11372', function() + clear() + local evs = {} + screen = Screen.new(20,5) + -- Override mouse_on/mouse_off handlers. + function screen:_handle_mouse_on() + table.insert(evs, 'mouse_on') + end + function screen:_handle_mouse_off() + table.insert(evs, 'mouse_off') + end + screen:attach() + screen:expect(function() + eq({'mouse_off'}, evs) + end) + command("set mouse=nvi") + screen:expect(function() + eq({'mouse_off','mouse_on'}, evs) + end) + screen:detach() + eq({'mouse_off','mouse_on'}, evs) + screen:attach() + screen:expect(function() + eq({'mouse_off','mouse_on','mouse_on'}, evs) + end) + end) + it("when setting options", function() local expected = reset() local defaults = shallowcopy(expected) diff --git a/test/functional/ui/output_spec.lua b/test/functional/ui/output_spec.lua index c028f44b44..9b1e803649 100644 --- a/test/functional/ui/output_spec.lua +++ b/test/functional/ui/output_spec.lua @@ -10,6 +10,7 @@ local iswin = helpers.iswin local clear = helpers.clear local command = helpers.command local nvim_dir = helpers.nvim_dir +local set_shell_powershell = helpers.set_shell_powershell describe("shell command :!", function() local screen @@ -30,7 +31,6 @@ describe("shell command :!", function() after_each(function() child_session.feed_data("\3") -- Ctrl-C - screen:detach() end) it("displays output without LF/EOF. #4646 #4569 #3772", function() @@ -51,8 +51,7 @@ describe("shell command :!", function() it("throttles shell-command output greater than ~10KB", function() if 'openbsd' == helpers.uname() then - pending('FIXME #10804', function() end) - return + pending('FIXME #10804') end child_session.feed_data(":!"..nvim_dir.."/shell-test REP 30001 foo\n") @@ -96,8 +95,7 @@ describe("shell command :!", function() it('handles control codes', function() if iswin() then - pending('missing printf', function() end) - return + pending('missing printf') end local screen = Screen.new(50, 4) screen:attach() @@ -230,4 +228,23 @@ describe("shell command :!", function() ]]) end) end) + if iswin() or eval('executable("pwsh")') == 1 then + it('powershell supports literal strings', function() + set_shell_powershell() + local screen = Screen.new(30, 4) + screen:attach() + feed_command([[!'Write-Output $a']]) + screen:expect{any='\nWrite%-Output %$a', timeout=10000} + feed_command([[!$a = 1; Write-Output '$a']]) + screen:expect{any='\n%$a', timeout=10000} + feed_command([[!"Write-Output $a"]]) + screen:expect{any='\nWrite%-Output', timeout=10000} + feed_command([[!$a = 1; Write-Output "$a"]]) + screen:expect{any='\n1', timeout=10000} + feed_command(iswin() + and [[!& 'C:\\Windows\\system32\\cmd.exe' /c 'echo $a']] + or [[!& '/bin/sh' -c 'echo ''$a''']]) + screen:expect{any='\n%$a', timeout=10000} + end) + end end) diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index ae2136f451..fabcc05ce6 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -516,6 +516,7 @@ describe('ui/ext_popupmenu', function() {1:~ }| :sign ^ | ]]) + eq(0, funcs.wildmenumode()) feed('<tab>') screen:expect{grid=[[ @@ -530,6 +531,7 @@ describe('ui/ext_popupmenu', function() {1:~ }| :sign define^ | ]], popupmenu={items=wild_expected, pos=0, anchor={1, 9, 6}}} + eq(1, funcs.wildmenumode()) feed('<left>') screen:expect{grid=[[ @@ -589,6 +591,7 @@ describe('ui/ext_popupmenu', function() :sign unplace^ | ]], popupmenu={items=wild_expected, pos=5, anchor={1, 9, 6}}} feed('<esc>') + eq(0, funcs.wildmenumode()) -- check positioning with multibyte char in pattern command("e långfile1") @@ -1488,20 +1491,20 @@ describe('builtin popupmenu', function() command("split") screen:expect([[ + xx | choice^ | - {1:~ }| {n:word }{1: }| {s:choice }{4: }| {n:text } | - {n:thing }{1: }| + {n:thing } | {3:[No Name] [+] }| {2:-- INSERT --} | ]]) meths.input_mouse('wheel', 'down', '', 0, 6, 15) screen:expect{grid=[[ + xx | choice^ | - {1:~ }| {n:word }{1: }| {s:choice }{4: }| {n:text } | diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua index 06a2ac3ca2..64f784afe3 100644 --- a/test/functional/ui/screen.lua +++ b/test/functional/ui/screen.lua @@ -66,12 +66,12 @@ -- [1] = {reverse = true, bold = true}, -- [2] = {reverse = true} -- }) --- screen:set_default_attr_ignore( {{}, {bold=true, foreground=NonText}} ) -- -- To help write screen tests, see Screen:snapshot_util(). -- To debug screen tests, see Screen:redraw_debug(). local helpers = require('test.functional.helpers')(nil) +local busted = require('busted') local deepcopy = helpers.deepcopy local shallowcopy = helpers.shallowcopy local concat_tables = helpers.concat_tables @@ -169,12 +169,11 @@ function Screen.new(width, height) ruler = {}, hl_groups = {}, _default_attr_ids = nil, - _default_attr_ignore = nil, _mouse_enabled = true, _attrs = {}, - _hl_info = {}, + _hl_info = {[0]={}}, _attr_table = {[0]={{},{}}}, - _clear_attrs = {}, + _clear_attrs = nil, _new_attrs = false, _width = width, _height = height, @@ -202,12 +201,8 @@ function Screen:get_default_attr_ids() return deepcopy(self._default_attr_ids) end -function Screen:set_default_attr_ignore(attr_ignore) - self._default_attr_ignore = attr_ignore -end - -function Screen:set_hlstate_cterm(val) - self._hlstate_cterm = val +function Screen:set_rgb_cterm(val) + self._rgb_cterm = val end function Screen:attach(options, session) @@ -223,7 +218,7 @@ function Screen:attach(options, session) self._session = session self._options = options - self._clear_attrs = (options.ext_linegrid and {{},{}}) or {} + self._clear_attrs = (not options.ext_linegrid) and {} or nil self:_handle_resize(self._width, self._height) self.uimeths.attach(self._width, self._height, options) if self._options.rgb == nil then @@ -265,7 +260,7 @@ local ext_keys = { -- Asserts that the screen state eventually matches an expected state. -- -- Can be called with positional args: --- screen:expect(grid, [attr_ids, attr_ignore]) +-- screen:expect(grid, [attr_ids]) -- screen:expect(condition) -- or keyword args (supports more options): -- screen:expect{grid=[[...]], cmdline={...}, condition=function() ... end} @@ -274,7 +269,7 @@ local ext_keys = { -- grid: Expected screen state (string). Each line represents a screen -- row. Last character of each row (typically "|") is stripped. -- Common indentation is stripped. --- Lines containing only "{IGNORE}|" are skipped. +-- "{MATCH:x}|" lines are matched against Lua pattern `x`. -- attr_ids: Expected text attributes. Screen rows are transformed according -- to this table, as follows: each substring S composed of -- characters having the same attributes will be substituted by @@ -282,8 +277,6 @@ local ext_keys = { -- attributes in the final state are an error. -- Use screen:set_default_attr_ids() to define attributes for many -- expect() calls. --- attr_ignore: Ignored text attributes, or `true` to ignore all. By default --- nothing is ignored. -- condition: Function asserting some arbitrary condition. Return value is -- ignored, throw an error (use eq() or similar) to signal failure. -- any: Lua pattern string expected to match a screen line. NB: the @@ -318,13 +311,13 @@ local ext_keys = { -- cmdline_block: Expected ext_cmdline block (for function definitions) -- wildmenu_items: Expected items for ext_wildmenu -- wildmenu_pos: Expected position for ext_wildmenu -function Screen:expect(expected, attr_ids, attr_ignore, ...) +function Screen:expect(expected, attr_ids, ...) local grid, condition = nil, nil local expected_rows = {} assert(next({...}) == nil, "invalid args to expect()") if type(expected) == "table" then - assert(not (attr_ids ~= nil or attr_ignore ~= nil)) - local is_key = {grid=true, attr_ids=true, attr_ignore=true, condition=true, + assert(not (attr_ids ~= nil)) + local is_key = {grid=true, attr_ids=true, condition=true, any=true, mode=true, unchanged=true, intermediate=true, reset=true, timeout=true, request_cb=true, hl_groups=true} for _, v in ipairs(ext_keys) do @@ -337,14 +330,13 @@ function Screen:expect(expected, attr_ids, attr_ignore, ...) end grid = expected.grid attr_ids = expected.attr_ids - attr_ignore = expected.attr_ignore condition = expected.condition assert(not (expected.any ~= nil and grid ~= nil)) elseif type(expected) == "string" then grid = expected expected = {} elseif type(expected) == "function" then - assert(not (attr_ids ~= nil or attr_ignore ~= nil)) + assert(not (attr_ids ~= nil)) condition = expected expected = {} else @@ -361,10 +353,9 @@ function Screen:expect(expected, attr_ids, attr_ignore, ...) end local attr_state = { ids = attr_ids or self._default_attr_ids, - ignore = attr_ignore or self._default_attr_ignore, } - if self._options.ext_hlstate then - attr_state.id_to_index = self:hlstate_check_attrs(attr_state.ids or {}) + if self._options.ext_linegrid then + attr_state.id_to_index = self:linegrid_check_attrs(attr_state.ids or {}) end self._new_attrs = false self:_wait(function() @@ -375,8 +366,8 @@ function Screen:expect(expected, attr_ids, attr_ignore, ...) end end - if self._options.ext_hlstate and self._new_attrs then - attr_state.id_to_index = self:hlstate_check_attrs(attr_state.ids or {}) + if self._options.ext_linegrid and self._new_attrs then + attr_state.id_to_index = self:linegrid_check_attrs(attr_state.ids or {}) end local actual_rows = self:render(not expected.any, attr_state) @@ -399,9 +390,10 @@ function Screen:expect(expected, attr_ids, attr_ignore, ...) err_msg = "Expected screen height " .. #expected_rows .. ' differs from actual height ' .. #actual_rows .. '.' end - for i = 1, #expected_rows do - msg_expected_rows[i] = expected_rows[i] - if expected_rows[i] ~= actual_rows[i] and expected_rows[i] ~= "{IGNORE}|" then + for i, row in ipairs(expected_rows) do + msg_expected_rows[i] = row + local m = (row ~= actual_rows[i] and row:match('{MATCH:(.*)}') or nil) + if row ~= actual_rows[i] and (not m or not actual_rows[i]:match(m)) then msg_expected_rows[i] = '*' .. msg_expected_rows[i] if i <= #actual_rows then actual_rows[i] = '*' .. actual_rows[i] @@ -584,7 +576,7 @@ asynchronous (feed(), nvim_input()) and synchronous API calls. if err then - assert(false, err) + busted.fail(err, 3) elseif did_warn then local tb = debug.traceback() local index = string.find(tb, '\n%s*%[C]') @@ -614,17 +606,12 @@ function Screen:_redraw(updates) for i = 2, #update do local handler_name = '_handle_'..method local handler = self[handler_name] - if handler ~= nil then - local status, res = pcall(handler, self, unpack(update[i])) - if not status then - error(handler_name..' failed' - ..'\n payload: '..inspect(update) - ..'\n error: '..tostring(res)) - end - else - assert(self._on_event, - "Add Screen:"..handler_name.." or call Screen:set_on_event_handler") - self._on_event(method, update[i]) + assert(handler ~= nil, "missing handler: Screen:"..handler_name) + local status, res = pcall(handler, self, unpack(update[i])) + if not status then + error(handler_name..' failed' + ..'\n payload: '..inspect(update) + ..'\n error: '..tostring(res)) end end if k == #updates and method == "flush" then @@ -634,10 +621,6 @@ function Screen:_redraw(updates) return did_flush end -function Screen:set_on_event_handler(callback) - self._on_event = callback -end - function Screen:_handle_resize(width, height) self:_handle_grid_resize(1, width, height) self._scroll_region = { @@ -898,19 +881,16 @@ function Screen:_handle_grid_line(grid, row, col, items) assert(self._options.ext_linegrid) local line = self._grids[grid].rows[row+1] local colpos = col+1 - local hl = self._clear_attrs local hl_id = 0 for _,item in ipairs(items) do local text, hl_id_cell, count = unpack(item) if hl_id_cell ~= nil then hl_id = hl_id_cell - hl = self._attr_table[hl_id] end for _ = 1, (count or 1) do local cell = line[colpos] cell.text = text cell.hl_id = hl_id - cell.attrs = hl colpos = colpos+1 end end @@ -1070,6 +1050,7 @@ function Screen:_clear_row_section(grid, rownum, startcol, stopcol, invalid) for i = startcol, stopcol do row[i].text = (invalid and '�' or ' ') row[i].attrs = self._clear_attrs + row[i].hl_id = 0 end end @@ -1100,11 +1081,7 @@ function Screen:_row_repr(gridnr, rownr, attr_state, cursor) end if not did_window then - local attrs = row[i].attrs - if self._options.ext_linegrid then - attrs = attrs[(self._options.rgb and 1) or 2] - end - local attr_id = self:_get_attr_id(attr_state, attrs, row[i].hl_id) + local attr_id = self:_get_attr_id(attr_state, row[i].attrs, row[i].hl_id) if current_attr_id and attr_id ~= current_attr_id then -- close current attribute bracket table.insert(rv, '}') @@ -1261,8 +1238,8 @@ function Screen:get_snapshot(attrs, ignore) attr_state.ids[i] = a end end - if self._options.ext_hlstate then - attr_state.id_to_index = self:hlstate_check_attrs(attr_state.ids) + if self._options.ext_linegrid then + attr_state.id_to_index = self:linegrid_check_attrs(attr_state.ids) end local lines = self:render(true, attr_state, true) @@ -1299,8 +1276,8 @@ function Screen:print_snapshot(attrs, ignore) local attrstrs = {} for i, a in pairs(attr_state.ids) do local dict - if self._options.ext_hlstate then - dict = self:_pprint_hlstate(a) + if self._options.ext_linegrid then + dict = self:_pprint_hlitem(a) else dict = "{"..self:_pprint_attrs(a).."}" end @@ -1328,37 +1305,41 @@ function Screen:_insert_hl_id(attr_state, hl_id) return attr_state.id_to_index[hl_id] end local raw_info = self._hl_info[hl_id] - local info = {} - if #raw_info > 1 then - for i, item in ipairs(raw_info) do - info[i] = self:_insert_hl_id(attr_state, item.id) - end - else - info[1] = {} - for k, v in pairs(raw_info[1]) do - if k ~= "id" then - info[1][k] = v + local info = nil + if self._options.ext_hlstate then + info = {} + if #raw_info > 1 then + for i, item in ipairs(raw_info) do + info[i] = self:_insert_hl_id(attr_state, item.id) + end + else + info[1] = {} + for k, v in pairs(raw_info[1]) do + if k ~= "id" then + info[1][k] = v + end end end end local entry = self._attr_table[hl_id] local attrval - if self._hlstate_cterm then + if self._rgb_cterm then attrval = {entry[1], entry[2], info} -- unpack() doesn't work - else + elseif self._options.ext_hlstate then attrval = {entry[1], info} + else + attrval = self._options.rgb and entry[1] or entry[2] end - table.insert(attr_state.ids, attrval) attr_state.id_to_index[hl_id] = #attr_state.ids return #attr_state.ids end -function Screen:hlstate_check_attrs(attrs) +function Screen:linegrid_check_attrs(attrs) local id_to_index = {} - for i = 1,#self._attr_table do + for i, def_attr in pairs(self._attr_table) do local iinfo = self._hl_info[i] local matchinfo = {} if #iinfo > 1 then @@ -1370,13 +1351,17 @@ function Screen:hlstate_check_attrs(attrs) end for k,v in pairs(attrs) do local attr, info, attr_rgb, attr_cterm - if self._hlstate_cterm then + if self._rgb_cterm then attr_rgb, attr_cterm, info = unpack(v) attr = {attr_rgb, attr_cterm} - else + info = info or {} + elseif self._options.ext_hlstate then attr, info = unpack(v) + else + attr = v + info = {} end - if self:_equal_attr_def(attr, self._attr_table[i]) then + if self:_equal_attr_def(attr, def_attr) then if #info == #matchinfo then local match = false if #info == 1 then @@ -1397,24 +1382,32 @@ function Screen:hlstate_check_attrs(attrs) end end end + if self:_equal_attr_def(self._rgb_cterm and {{}, {}} or {}, def_attr) and #self._hl_info[i] == 0 then + id_to_index[i] = "" + end end return id_to_index end -function Screen:_pprint_hlstate(item) +function Screen:_pprint_hlitem(item) -- print(inspect(item)) - local attrdict = "{"..self:_pprint_attrs(item[1]).."}, " + local multi = self._rgb_cterm or self._options.ext_hlstate + local cterm = (not self._rgb_cterm and not self._options.rgb) + local attrdict = "{"..self:_pprint_attrs(multi and item[1] or item, cterm).."}" local attrdict2, hlinfo - if self._hlstate_cterm then - attrdict2 = "{"..self:_pprint_attrs(item[2]).."}, " + local descdict = "" + if self._rgb_cterm then + attrdict2 = ", {"..self:_pprint_attrs(item[2], true).."}" hlinfo = item[3] else attrdict2 = "" hlinfo = item[2] end - local descdict = "{"..self:_pprint_hlinfo(hlinfo).."}" - return "{"..attrdict..attrdict2..descdict.."}" + if self._options.ext_hlstate then + descdict = ", {"..self:_pprint_hlinfo(hlinfo).."}" + end + return (multi and "{" or "")..attrdict..attrdict2..descdict..(multi and "}" or "") end function Screen:_pprint_hlinfo(states) @@ -1434,13 +1427,15 @@ function Screen:_pprint_hlinfo(states) end -function Screen:_pprint_attrs(attrs) +function Screen:_pprint_attrs(attrs, cterm) local items = {} for f, v in pairs(attrs) do local desc = tostring(v) if f == "foreground" or f == "background" or f == "special" then if Screen.colornames[v] ~= nil then desc = "Screen.colors."..Screen.colornames[v] + elseif cterm then + desc = tostring(v) else desc = string.format("tonumber('0x%06x')",v) end @@ -1464,9 +1459,11 @@ function Screen:_get_attr_id(attr_state, attrs, hl_id) return end - if self._options.ext_hlstate then + if self._options.ext_linegrid then local id = attr_state.id_to_index[hl_id] - if id ~= nil or hl_id == 0 then + if id == "" then -- sentinel for empty it + return nil + elseif id ~= nil then return id end if attr_state.mutable then @@ -1476,9 +1473,7 @@ function Screen:_get_attr_id(attr_state, attrs, hl_id) end return "UNEXPECTED "..self:_pprint_attrs(self._attr_table[hl_id][1]) else - if self:_equal_attrs(attrs, {}) or - attr_state.ignore == true or - self:_attr_index(attr_state.ignore, attrs) ~= nil then + if self:_equal_attrs(attrs, {}) then -- ignore this attrs return nil end @@ -1497,10 +1492,12 @@ function Screen:_get_attr_id(attr_state, attrs, hl_id) end function Screen:_equal_attr_def(a, b) - if self._hlstate_cterm then + if self._rgb_cterm then return self:_equal_attrs(a[1],b[1]) and self:_equal_attrs(a[2],b[2]) - else + elseif self._options.rgb then return self:_equal_attrs(a,b[1]) + else + return self:_equal_attrs(a,b[2]) end end @@ -1510,7 +1507,8 @@ function Screen:_equal_attrs(a, b) a.italic == b.italic and a.reverse == b.reverse and a.foreground == b.foreground and a.background == b.background and a.special == b.special and a.blend == b.blend and - a.strikethrough == b.strikethrough + a.strikethrough == b.strikethrough and + a.fg_indexed == b.fg_indexed and a.bg_indexed == b.bg_indexed end function Screen:_equal_info(a, b) diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua index 46f0b5060c..150ee2a103 100644 --- a/test/functional/ui/screen_basic_spec.lua +++ b/test/functional/ui/screen_basic_spec.lua @@ -915,6 +915,7 @@ local function screen_tests(linegrid) -- Regression test for #8357 it('does not have artifacts after temporary chars in insert mode', function() + command('set timeoutlen=10000') command('inoremap jk <esc>') feed('ifooj') screen:expect([[ diff --git a/test/functional/ui/searchhl_spec.lua b/test/functional/ui/searchhl_spec.lua index 486de02a09..635ce7392b 100644 --- a/test/functional/ui/searchhl_spec.lua +++ b/test/functional/ui/searchhl_spec.lua @@ -442,7 +442,7 @@ describe('search highlighting', function() feed_command("call matchadd('MyGroup', 'special')") feed_command("call matchadd('MyGroup2', 'text', 0)") - -- searchhl and matchadd matches are exclusive, only the higest priority + -- searchhl and matchadd matches are exclusive, only the highest priority -- is used (and matches with lower priorities are not combined) feed_command("/ial te") screen:expect([[ diff --git a/test/functional/ui/sign_spec.lua b/test/functional/ui/sign_spec.lua index 68e675b8e5..0ed62b21b2 100644 --- a/test/functional/ui/sign_spec.lua +++ b/test/functional/ui/sign_spec.lua @@ -26,10 +26,6 @@ describe('Signs', function() } ) end) - after_each(function() - screen:detach() - end) - describe(':sign place', function() it('allows signs with combining characters', function() feed('ia<cr>b<cr><esc>') diff --git a/test/functional/ui/spell_spec.lua b/test/functional/ui/spell_spec.lua index 913f1b9bed..243b737583 100644 --- a/test/functional/ui/spell_spec.lua +++ b/test/functional/ui/spell_spec.lua @@ -20,10 +20,6 @@ describe("'spell'", function() }) end) - after_each(function() - screen:detach() - end) - it('joins long lines #7937', function() feed_command('set spell') insert([[ diff --git a/test/functional/ui/syntax_conceal_spec.lua b/test/functional/ui/syntax_conceal_spec.lua index 00e94ef94b..d1af0e955c 100644 --- a/test/functional/ui/syntax_conceal_spec.lua +++ b/test/functional/ui/syntax_conceal_spec.lua @@ -1,6 +1,7 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local clear, feed, command = helpers.clear, helpers.feed, helpers.command +local eq = helpers.eq local insert = helpers.insert describe('Screen', function() @@ -17,13 +18,10 @@ describe('Screen', function() [3] = {reverse = true}, [4] = {bold = true}, [5] = {background = Screen.colors.Yellow}, + [6] = {background = Screen.colors.LightGrey}, } ) end) - after_each(function() - screen:detach() - end) - describe("match and conceal", function() before_each(function() @@ -823,5 +821,96 @@ describe('Screen', function() ]]) end) end) + + it('redraws properly with concealcursor in visual mode', function() + command('set concealcursor=v conceallevel=2') + + feed('10Ofoo barf bar barf eggs<esc>') + feed(':3<cr>o a<Esc>ggV') + screen:expect{grid=[[ + ^f{6:oo }{1:b}{6: bar }{1:b}{6: eggs} | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + a | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + {4:-- VISUAL LINE --} | + ]]} + feed(string.rep('j', 15)) + screen:expect{grid=[[ + {6:foo }{1:b}{6: bar }{1:b}{6: eggs} | + {6:foo }{1:b}{6: bar }{1:b}{6: eggs} | + {6:foo }{1:b}{6: bar }{1:b}{6: eggs} | + {6:foo }{1:b}{6: bar }{1:b}{6: eggs} | + {6:foo }{1:b}{6: bar }{1:b}{6: eggs} | + {6:foo }{1:b}{6: bar }{1:b}{6: eggs} | + {6:foo }{1:b}{6: bar }{1:b}{6: eggs} | + {6:foo }{1:b}{6: bar }{1:b}{6: eggs} | + ^f{6:oo }{1:b}{6: bar }{1:b}{6: eggs} | + {4:-- VISUAL LINE --} | + ]]} + feed(string.rep('k', 15)) + screen:expect{grid=[[ + ^f{6:oo }{1:b}{6: bar }{1:b}{6: eggs} | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + a | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + {4:-- VISUAL LINE --} | + ]]} + end) + end) + + it('redraws not too much with conceallevel=1', function() + command('set conceallevel=1') + command('set redrawdebug+=nodelta') + + insert([[ + aaa + bbb + ccc + ]]) + screen:expect{grid=[[ + aaa | + bbb | + ccc | + ^ | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]} + + -- XXX: hack to get notifications, and check only a single line is + -- updated. Could use next_msg() also. + local orig_handle_grid_line = screen._handle_grid_line + local grid_lines = {} + function screen._handle_grid_line(self, grid, row, col, items) + table.insert(grid_lines, {row, col, items}) + orig_handle_grid_line(self, grid, row, col, items) + end + feed('k') + screen:expect{grid=[[ + aaa | + bbb | + ^ccc | + | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]} + eq(grid_lines, {{2, 0, {{'c', 0, 3}}}}) end) end) diff --git a/test/functional/ui/tabline_spec.lua b/test/functional/ui/tabline_spec.lua index dcab9f7ef4..23aae81745 100644 --- a/test/functional/ui/tabline_spec.lua +++ b/test/functional/ui/tabline_spec.lua @@ -10,15 +10,9 @@ describe('ui/ext_tabline', function() clear() screen = Screen.new(25, 5) screen:attach({rgb=true, ext_tabline=true}) - screen:set_on_event_handler(function(name, data) - if name == "tabline_update" then - event_curtab, event_tabs = unpack(data) - end - end) - end) - - after_each(function() - screen:detach() + function screen:_handle_tabline_update(curtab, tabs) + event_curtab, event_tabs = curtab, tabs + end end) it('publishes UI events', function() |