diff options
Diffstat (limited to 'test/functional/ui')
-rw-r--r-- | test/functional/ui/fold_spec.lua | 22 | ||||
-rw-r--r-- | test/functional/ui/highlight_spec.lua | 34 | ||||
-rw-r--r-- | test/functional/ui/mouse_spec.lua | 73 | ||||
-rw-r--r-- | test/functional/ui/multigrid_spec.lua | 1524 | ||||
-rw-r--r-- | test/functional/ui/options_spec.lua | 1 | ||||
-rw-r--r-- | test/functional/ui/popupmenu_spec.lua | 370 | ||||
-rw-r--r-- | test/functional/ui/screen.lua | 284 | ||||
-rw-r--r-- | test/functional/ui/syntax_conceal_spec.lua | 496 | ||||
-rw-r--r-- | test/functional/ui/wildmode_spec.lua | 2 |
9 files changed, 2712 insertions, 94 deletions
diff --git a/test/functional/ui/fold_spec.lua b/test/functional/ui/fold_spec.lua index 39a5c10bb7..943cbcef56 100644 --- a/test/functional/ui/fold_spec.lua +++ b/test/functional/ui/fold_spec.lua @@ -1,8 +1,10 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local clear, feed, eq = helpers.clear, helpers.feed, helpers.eq +local command = helpers.command local feed_command = helpers.feed_command local insert = helpers.insert +local funcs = helpers.funcs local meths = helpers.meths describe("folded lines", function() @@ -26,6 +28,26 @@ describe("folded lines", function() screen:detach() end) + it("highlighting with relative line numbers", function() + command("set relativenumber foldmethod=marker") + feed_command("set foldcolumn=2") + funcs.setline(1, '{{{1') + funcs.setline(2, 'line 1') + funcs.setline(3, '{{{1') + funcs.setline(4, 'line 2') + feed("j") + screen:expect([[ + {7:+ }{5: 1 +-- 2 lines: ·························}| + {7:+ }{5: 0 ^+-- 2 lines: ·························}| + {7: }{1:~ }| + {7: }{1:~ }| + {7: }{1:~ }| + {7: }{1:~ }| + {7: }{1:~ }| + :set foldcolumn=2 | + ]]) + end) + it("works with multibyte text", function() -- Currently the only allowed value of 'maxcombine' eq(6, meths.get_option('maxcombine')) diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua index 96f6b43320..39170337d7 100644 --- a/test/functional/ui/highlight_spec.lua +++ b/test/functional/ui/highlight_spec.lua @@ -322,6 +322,40 @@ describe('highlight', function() screen:attach() end) + it('visual', function() + screen:detach() + screen = Screen.new(20,4) + screen:attach() + screen:set_default_attr_ids({ + [1] = {background = Screen.colors.LightGrey}, + [2] = {bold = true, foreground = Screen.colors.Blue1}, + [3] = {bold = true}, + }) + insert([[ + line1 foo bar + ]]) + + -- Non-blinking block cursor: does NOT highlight char-at-cursor. + command('set guicursor=a:block-blinkon0') + feed('gg$vhhh') + screen:expect([[ + line1 foo^ {1:bar} | + | + {2:~ }| + {3:-- VISUAL --} | + ]]) + + -- Vertical cursor: highlights char-at-cursor. #8983 + command('set guicursor=a:block-blinkon175') + feed('<esc>gg$vhhh') + screen:expect([[ + line1 foo{1:^ bar} | + | + {2:~ }| + {3:-- VISUAL --} | + ]]) + end) + it('cterm=standout gui=standout', function() screen:detach() screen = Screen.new(20,5) diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua index c531f838c1..3890f0f7ba 100644 --- a/test/functional/ui/mouse_spec.lua +++ b/test/functional/ui/mouse_spec.lua @@ -741,10 +741,11 @@ describe('ui/mouse/input', function() screen:set_default_attr_ids({ [0] = {bold=true, foreground=Screen.colors.Blue}, c = { foreground = Screen.colors.LightGrey, background = Screen.colors.DarkGray }, + sm = {bold = true}, }) feed('ggdG') - feed_command('set concealcursor=n') + feed_command('set concealcursor=ni') feed_command('set nowrap') feed_command('set shiftwidth=2 tabstop=4 list listchars=tab:>-') feed_command('syntax match NonText "\\*" conceal') @@ -973,6 +974,76 @@ describe('ui/mouse/input', function() ]]) end) -- level 2 - non wrapped + it('(level 2) click on non-wrapped lines (insert mode)', function() + feed_command('let &conceallevel=2', 'echo') + + feed('<esc>i<LeftMouse><20,0>') + screen:expect([[ + Section{0:>>--->--->---}^t1 | + {0:>--->--->---} t2 t3 t4 | + {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}| + | + {0:~ }| + {0:~ }| + {sm:-- INSERT --} | + ]]) + + feed('<LeftMouse><14,1>') + screen:expect([[ + Section{0:>>--->--->---}t1 | + {0:>--->--->---} ^t2 t3 t4 | + {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}| + | + {0:~ }| + {0:~ }| + {sm:-- INSERT --} | + ]]) + + feed('<LeftMouse><18,1>') + screen:expect([[ + Section{0:>>--->--->---}t1 | + {0:>--->--->---} t2 t^3 t4 | + {c:>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}| + | + {0:~ }| + {0:~ }| + {sm:-- INSERT --} | + ]]) + + feed('<LeftMouse><0,2>') -- Weirdness + screen:expect([[ + Section{0:>>--->--->---}t1 | + {0:>--->--->---} t2 t3 t4 | + {c:^>} 私は猫が大好き{0:>---}{c:X} ✨{0:>}| + | + {0:~ }| + {0:~ }| + {sm:-- INSERT --} | + ]]) + + feed('<LeftMouse><8,2>') + screen:expect([[ + Section{0:>>--->--->---}t1 | + {0:>--->--->---} t2 t3 t4 | + {c:>} 私は猫^が大好き{0:>---}{c:X} ✨{0:>}| + | + {0:~ }| + {0:~ }| + {sm:-- INSERT --} | + ]]) + + feed('<LeftMouse><20,2>') + screen:expect([[ + Section{0:>>--->--->---}t1 | + {0:>--->--->---} t2 t3 t4 | + {c:>} 私は猫が大好き{0:>---}{c:^X} ✨{0:>}| + | + {0:~ }| + {0:~ }| + {sm:-- INSERT --} | + ]]) + end) -- level 2 - non wrapped (insert mode) + it('(level 2) click on wrapped lines', function() feed_command('let &conceallevel=2', 'let &wrap=1', 'echo') diff --git a/test/functional/ui/multigrid_spec.lua b/test/functional/ui/multigrid_spec.lua new file mode 100644 index 0000000000..a5d4e34000 --- /dev/null +++ b/test/functional/ui/multigrid_spec.lua @@ -0,0 +1,1524 @@ +local helpers = require('test.functional.helpers')(after_each) +local Screen = require('test.functional.ui.screen') +local clear = helpers.clear +local feed, command, insert = helpers.feed, helpers.command, helpers.insert +local eq = helpers.eq + + +describe('multigrid screen', function() + local screen + + before_each(function() + clear{headless=false, args={'--cmd', 'set laststatus=2'}} + screen = Screen.new(53,14) + screen:attach({ext_multigrid=true}) + screen:set_default_attr_ids({ + [1] = {bold = true, foreground = Screen.colors.Blue1}, + [2] = {foreground = Screen.colors.Magenta}, + [3] = {foreground = Screen.colors.Brown, bold = true}, + [4] = {foreground = Screen.colors.SlateBlue}, + [5] = {bold = true, foreground = Screen.colors.SlateBlue}, + [6] = {foreground = Screen.colors.Cyan4}, + [7] = {bold = true}, + [8] = {underline = true, bold = true, foreground = Screen.colors.SlateBlue}, + [9] = {foreground = Screen.colors.SlateBlue, underline = true}, + [10] = {foreground = Screen.colors.Red}, + [11] = {bold = true, reverse = true}, + [12] = {reverse = true}, + [13] = {foreground = Screen.colors.DarkBlue, background = Screen.colors.LightGrey}, + [14] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, + [15] = {bold = true, foreground = Screen.colors.SeaGreen4}, + [16] = {background = Screen.colors.LightGrey, underline = true}, + [17] = {background = Screen.colors.LightGrey, underline = true, bold = true, foreground = Screen.colors.Magenta}, + [18] = {bold = true, foreground = Screen.colors.Magenta}, + [19] = {foreground = Screen.colors.Brown}, + }) + end) + + after_each(function() + screen:detach() + end) + + it('default initial screen', function() + screen:expect([[ + ## grid 1 + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {11:[No Name] }| + | + ## grid 2 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + end) + + it('positions windows correctly', function() + command('vsplit') + screen:expect([[ + ## grid 1 + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + {11:[No Name] }{12:[No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]], nil, nil, function() + eq({ + [2] = { win = 1000, startrow = 0, startcol = 27, width = 26, height = 12 }, + [3] = { win = 1001, startrow = 0, startcol = 0, width = 26, height = 12 } + }, screen.win_position) + end) + command('wincmd l') + command('split') + screen:expect([[ + ## grid 1 + [3:--------------------------]{12:│}[4:--------------------------]| + [3:--------------------------]{12:│}[4:--------------------------]| + [3:--------------------------]{12:│}[4:--------------------------]| + [3:--------------------------]{12:│}[4:--------------------------]| + [3:--------------------------]{12:│}[4:--------------------------]| + [3:--------------------------]{12:│}[4:--------------------------]| + [3:--------------------------]{12:│}{11:[No Name] }| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + {12:[No Name] [No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 4 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]], nil, nil, function() + eq({ + [2] = { win = 1000, startrow = 7, startcol = 27, width = 26, height = 5 }, + [3] = { win = 1001, startrow = 0, startcol = 0, width = 26, height = 12 }, + [4] = { win = 1002, startrow = 0, startcol = 27, width = 26, height = 6 } + }, screen.win_position) + end) + command('wincmd h') + command('q') + screen:expect([[ + ## grid 1 + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + {11:[No Name] }| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {12:[No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 4 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]], nil, nil, function() + eq({ + [2] = { win = 1000, startrow = 7, startcol = 0, width = 53, height = 5 }, + [4] = { win = 1002, startrow = 0, startcol = 0, width = 53, height = 6 } + }, screen.win_position) + end) + end) + + describe('split', function () + describe('horizontally', function () + it('allocates grids', function () + command('sp') + screen:expect([[ + ## grid 1 + [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]| + {11:[No Name] }| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {12:[No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + end) + + it('resizes grids', function () + command('sp') + command('resize 8') + screen:expect([[ + ## grid 1 + [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]| + {11:[No Name] }| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {12:[No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + ## grid 3 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + end) + + it('splits vertically', function() + command('sp') + command('vsp') + command('vsp') + screen:expect([[ + ## grid 1 + [5:--------------------]{12:│}[4:----------------]{12:│}[3:---------------]| + [5:--------------------]{12:│}[4:----------------]{12:│}[3:---------------]| + [5:--------------------]{12:│}[4:----------------]{12:│}[3:---------------]| + [5:--------------------]{12:│}[4:----------------]{12:│}[3:---------------]| + [5:--------------------]{12:│}[4:----------------]{12:│}[3:---------------]| + [5:--------------------]{12:│}[4:----------------]{12:│}[3:---------------]| + {11:[No Name] }{12:[No Name] [No Name] }| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {12:[No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 4 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 5 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + insert('hello') + screen:expect([[ + ## grid 1 + [5:--------------------]{12:│}[4:----------------]{12:│}[3:---------------]| + [5:--------------------]{12:│}[4:----------------]{12:│}[3:---------------]| + [5:--------------------]{12:│}[4:----------------]{12:│}[3:---------------]| + [5:--------------------]{12:│}[4:----------------]{12:│}[3:---------------]| + [5:--------------------]{12:│}[4:----------------]{12:│}[3:---------------]| + [5:--------------------]{12:│}[4:----------------]{12:│}[3:---------------]| + {11:[No Name] [+] }{12:[No Name] [+] [No Name] [+] }| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {12:[No Name] [+] }| + | + ## grid 2 + hello | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + hello | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 4 + hello | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 5 + hell^o | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + end) + it('closes splits', function () + command('sp') + screen:expect([[ + ## grid 1 + [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]| + [3:-----------------------------------------------------]| + {11:[No Name] }| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {12:[No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + command('q') + screen:expect([[ + ## grid 1 + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {11:[No Name] }| + | + ## grid 2 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + end) + end) + + describe('vertically', function () + it('allocates grids', function () + command('vsp') + screen:expect([[ + ## grid 1 + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + {11:[No Name] }{12:[No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + end) + it('resizes grids', function () + command('vsp') + command('vertical resize 10') + -- see "Note 1" for info about why there are two vseps + screen:expect([[ + ## grid 1 + [3:----------]{12:│}[2:------------------------------------------]| + [3:----------]{12:│}[2:------------------------------------------]| + [3:----------]{12:│}[2:------------------------------------------]| + [3:----------]{12:│}[2:------------------------------------------]| + [3:----------]{12:│}[2:------------------------------------------]| + [3:----------]{12:│}[2:------------------------------------------]| + [3:----------]{12:│}[2:------------------------------------------]| + [3:----------]{12:│}[2:------------------------------------------]| + [3:----------]{12:│}[2:------------------------------------------]| + [3:----------]{12:│}[2:------------------------------------------]| + [3:----------]{12:│}[2:------------------------------------------]| + [3:----------]{12:│}[2:------------------------------------------]| + {11:<No Name] }{12:[No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + end) + it('splits horizontally', function () + command('vsp') + command('sp') + screen:expect([[ + ## grid 1 + [4:--------------------------]{12:│}[2:--------------------------]| + [4:--------------------------]{12:│}[2:--------------------------]| + [4:--------------------------]{12:│}[2:--------------------------]| + [4:--------------------------]{12:│}[2:--------------------------]| + [4:--------------------------]{12:│}[2:--------------------------]| + [4:--------------------------]{12:│}[2:--------------------------]| + {11:[No Name] }{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + {12:[No Name] [No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 4 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + insert('hello') + screen:expect([[ + ## grid 1 + [4:--------------------------]{12:│}[2:--------------------------]| + [4:--------------------------]{12:│}[2:--------------------------]| + [4:--------------------------]{12:│}[2:--------------------------]| + [4:--------------------------]{12:│}[2:--------------------------]| + [4:--------------------------]{12:│}[2:--------------------------]| + [4:--------------------------]{12:│}[2:--------------------------]| + {11:[No Name] [+] }{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + {12:[No Name] [+] [No Name] [+] }| + | + ## grid 2 + hello | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + hello | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 4 + hell^o | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + end) + it('closes splits', function () + command('vsp') + screen:expect([[ + ## grid 1 + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + {11:[No Name] }{12:[No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + command('q') + screen:expect([[ + ## grid 1 + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {11:[No Name] }| + | + ## grid 2 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + end) + end) + end) + + describe('on resize', function () + it('rebuilds all grids', function () + screen:try_resize(25, 6) + screen:expect([[ + ## grid 1 + [2:-------------------------]| + [2:-------------------------]| + [2:-------------------------]| + [2:-------------------------]| + {11:[No Name] }| + | + ## grid 2 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + end) + + it('has minimum width/height values', function() + screen:try_resize(1, 1) + screen:expect([[ + ## grid 1 + [2:------------]| + {11:[No Name] }| + | + ## grid 2 + ^ | + ]]) + + feed('<esc>:ls') + screen:expect([[ + ## grid 1 + [2:------------]| + {11:[No Name] }| + :ls^ | + ## grid 2 + | + ]]) + end) + end) + + describe('grid of smaller inner size', function() + it('is rendered correctly', function() + screen:try_resize_grid(2, 8, 5) + screen:expect([[ + ## grid 1 + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {11:[No Name] }| + | + ## grid 2 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + end) + end) + + describe('grid of bigger inner size', function() + it('is rendered correctly', function() + screen:try_resize_grid(2, 80, 20) + screen:expect([[ + ## grid 1 + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {11:[No Name] }| + | + ## grid 2 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + end) + end) + + + describe('with resized grid', function() + before_each(function() + screen:try_resize_grid(2, 60, 20) + end) + it('gets written till grid width', function() + insert(('a'):rep(60).."\n") + screen:expect([[ + ## grid 1 + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {11:[No Name] [+] }| + | + ## grid 2 + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + end) + + it('wraps with grid width', function() + insert(('b'):rep(80).."\n") + screen:expect([[ + ## grid 1 + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {11:[No Name] [+] }| + | + ## grid 2 + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb| + bbbbbbbbbbbbbbbbbbbb | + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + end) + + it('displays messages with default grid width', function() + command('echomsg "this is a very very very very very very very very'.. + ' long message"') + screen:expect([[ + ## grid 1 + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {11:[No Name] }| + this is a very very very...ry very very long message | + ## grid 2 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + end) + + it('creates folds with grid width', function() + insert('this is a fold\nthis is inside fold\nthis is outside fold') + feed('kzfgg') + screen:expect([[ + ## grid 1 + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {11:[No Name] [+] }| + | + ## grid 2 + {13:^+-- 2 lines: this is a fold································}| + this is outside fold | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + end) + end) + + it('multiline messages scroll over windows', function() + command('sp') + command('vsp') + screen:expect([[ + ## grid 1 + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + {11:[No Name] }{12:[No Name] }| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {12:[No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 4 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + + feed(":echoerr 'very' | echoerr 'much' | echoerr 'fail'<cr>") + screen:expect([[ + ## grid 1 + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + {11:[No Name] }{12:[No Name] }| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {11: }| + {14:very} | + {14:much} | + {14:fail} | + {15:Press ENTER or type command to continue}^ | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 4 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + + feed('<cr>') + screen:expect([[ + ## grid 1 + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + {11:[No Name] }{12:[No Name] }| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {12:[No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 4 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + + command([[ + func! ErrMsg() + for i in range(11) + echoerr "error ".i + endfor + endfunc]]) + feed(":call ErrMsg()<cr>") + screen:expect([[ + ## grid 1 + {14:Error detected while processing function ErrMsg:} | + {19:line 2:} | + {14:error 0} | + {14:error 1} | + {14:error 2} | + {14:error 3} | + {14:error 4} | + {14:error 5} | + {14:error 6} | + {14:error 7} | + {14:error 8} | + {14:error 9} | + {14:error 10} | + {15:Press ENTER or type command to continue}^ | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 4 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + + feed("<c-c>") + screen:expect([[ + ## grid 1 + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + [4:--------------------------]{12:│}[3:--------------------------]| + {11:[No Name] }{12:[No Name] }| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + [2:-----------------------------------------------------]| + {12:[No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 4 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + end) + + it('handles switich tabs', function() + command('vsp') + screen:expect([[ + ## grid 1 + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + {11:[No Name] }{12:[No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + + + command('tabnew') + -- note the old grids aren't resized yet + screen:expect([[ + ## grid 1 + {16: }{17:2}{16: [No Name] }{7: [No Name] }{12: }{16:X}| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + {11:[No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 4 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + + command('sp') + screen:expect([[ + ## grid 1 + {16: }{17:2}{16: [No Name] }{7: }{18:2}{7: [No Name] }{12: }{16:X}| + [5:-----------------------------------------------------]| + [5:-----------------------------------------------------]| + [5:-----------------------------------------------------]| + [5:-----------------------------------------------------]| + [5:-----------------------------------------------------]| + {11:[No Name] }| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + {12:[No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 4 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 5 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + + command('tabnext') + screen:expect([[ + ## grid 1 + {7: }{18:2}{7: [No Name] }{16: }{17:2}{16: [No Name] }{12: }{16:X}| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + {11:[No Name] }{12:[No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 4 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 5 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + + command('tabnext') + screen:expect([[ + ## grid 1 + {16: }{17:2}{16: [No Name] }{7: }{18:2}{7: [No Name] }{12: }{16:X}| + [5:-----------------------------------------------------]| + [5:-----------------------------------------------------]| + [5:-----------------------------------------------------]| + [5:-----------------------------------------------------]| + [5:-----------------------------------------------------]| + {11:[No Name] }| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + [4:-----------------------------------------------------]| + {12:[No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 4 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 5 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + + command('tabclose') + screen:expect([[ + ## grid 1 + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + [3:--------------------------]{12:│}[2:--------------------------]| + {11:[No Name] }{12:[No Name] }| + | + ## grid 2 + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ]]) + end) +end) diff --git a/test/functional/ui/options_spec.lua b/test/functional/ui/options_spec.lua index 32e8faf7d3..c26fa5e29b 100644 --- a/test/functional/ui/options_spec.lua +++ b/test/functional/ui/options_spec.lua @@ -26,6 +26,7 @@ describe('ui receives option updates', function() ext_wildmenu=false, ext_linegrid=false, ext_hlstate=false, + ext_multigrid=false, } clear(...) diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 606c7c1e26..9424931de4 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -2,6 +2,9 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local clear, feed = helpers.clear, helpers.feed local source = helpers.source +local insert = helpers.insert +local meths = helpers.meths +local command = helpers.command describe('ui/ext_popupmenu', function() local screen @@ -14,22 +17,25 @@ describe('ui/ext_popupmenu', function() [2] = {bold = true}, [3] = {reverse = true}, [4] = {bold = true, reverse = true}, - [5] = {bold = true, foreground = Screen.colors.SeaGreen} + [5] = {bold = true, foreground = Screen.colors.SeaGreen}, + [6] = {background = Screen.colors.WebGray}, + [7] = {background = Screen.colors.LightMagenta}, }) - end) - - it('works', function() source([[ function! TestComplete() abort - call complete(1, ['foo', 'bar', 'spam']) + call complete(1, [{'word':'foo', 'abbr':'fo', 'menu':'the foo', 'info':'foo-y', 'kind':'x'}, 'bar', 'spam']) return '' endfunction ]]) - local expected = { - {'foo', '', '', ''}, - {'bar', '', '', ''}, - {'spam', '', '', ''}, - } + end) + + local expected = { + {'fo', 'x', 'the foo', 'foo-y'}, + {'bar', '', '', ''}, + {'spam', '', '', ''}, + } + + it('works', function() feed('o<C-r>=TestComplete()<CR>') screen:expect{grid=[[ | @@ -91,8 +97,277 @@ describe('ui/ext_popupmenu', function() {2:-- INSERT --} | ]]} end) + + it('can be controlled by API', function() + feed('o<C-r>=TestComplete()<CR>') + screen:expect{grid=[[ + | + foo^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]], popupmenu={ + items=expected, + pos=0, + anchor={1,0}, + }} + + meths.select_popupmenu_item(1,false,false,{}) + screen:expect{grid=[[ + | + foo^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]], popupmenu={ + items=expected, + pos=1, + anchor={1,0}, + }} + + meths.select_popupmenu_item(2,true,false,{}) + screen:expect{grid=[[ + | + spam^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]], popupmenu={ + items=expected, + pos=2, + anchor={1,0}, + }} + + meths.select_popupmenu_item(0,true,true,{}) + screen:expect([[ + | + foo^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + + feed('<c-w><C-r>=TestComplete()<CR>') + screen:expect{grid=[[ + | + foo^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]], popupmenu={ + items=expected, + pos=0, + anchor={1,0}, + }} + + meths.select_popupmenu_item(-1,false,false,{}) + screen:expect{grid=[[ + | + foo^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]], popupmenu={ + items=expected, + pos=-1, + anchor={1,0}, + }} + + meths.select_popupmenu_item(1,true,false,{}) + screen:expect{grid=[[ + | + bar^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]], popupmenu={ + items=expected, + pos=1, + anchor={1,0}, + }} + + meths.select_popupmenu_item(-1,true,false,{}) + screen:expect{grid=[[ + | + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]], popupmenu={ + items=expected, + pos=-1, + anchor={1,0}, + }} + + meths.select_popupmenu_item(0,true,false,{}) + screen:expect{grid=[[ + | + foo^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]], popupmenu={ + items=expected, + pos=0, + anchor={1,0}, + }} + + meths.select_popupmenu_item(-1,true,true,{}) + screen:expect([[ + | + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + command('imap <f1> <cmd>call nvim_select_popupmenu_item(2,v:true,v:false,{})<cr>') + command('imap <f2> <cmd>call nvim_select_popupmenu_item(-1,v:false,v:false,{})<cr>') + command('imap <f3> <cmd>call nvim_select_popupmenu_item(1,v:false,v:true,{})<cr>') + feed('<C-r>=TestComplete()<CR>') + screen:expect{grid=[[ + | + foo^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]], popupmenu={ + items=expected, + pos=0, + anchor={1,0}, + }} + + feed('<f1>') + screen:expect{grid=[[ + | + spam^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]], popupmenu={ + items=expected, + pos=2, + anchor={1,0}, + }} + + feed('<f2>') + screen:expect{grid=[[ + | + spam^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]], popupmenu={ + items=expected, + pos=-1, + anchor={1,0}, + }} + + feed('<f3>') + screen:expect([[ + | + bar^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + -- also should work for builtin popupmenu + screen:set_option('ext_popupmenu', false) + feed('<C-r>=TestComplete()<CR>') + screen:expect([[ + | + foo^ | + {6:fo x the foo }{1: }| + {7:bar }{1: }| + {7:spam }{1: }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + feed('<f1>') + screen:expect([[ + | + spam^ | + {7:fo x the foo }{1: }| + {7:bar }{1: }| + {6:spam }{1: }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + feed('<f2>') + screen:expect([[ + | + spam^ | + {7:fo x the foo }{1: }| + {7:bar }{1: }| + {7:spam }{1: }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + feed('<f3>') + screen:expect([[ + | + bar^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + end) end) + describe('popup placement', function() local screen before_each(function() @@ -257,4 +532,79 @@ describe('popup placement', function() {2:-- }{5:match 1 of 10} | ]]) end) + + it('works with vsplits', function() + insert('aaa aab aac\n') + feed(':vsplit<cr>') + screen:expect([[ + aaa aab aac {3:│}aaa aab aac| + ^ {3:│} | + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {4:[No Name] [+] }{3:<Name] [+] }| + :vsplit | + ]]) + + feed('ibbb a<c-x><c-n>') + screen:expect([[ + aaa aab aac {3:│}aaa aab aac| + bbb aaa^ {3:│}bbb aaa | + {1:~ }{s: aaa }{1: }{3:│}{1:~ }| + {1:~ }{n: aab }{1: }{3:│}{1:~ }| + {1:~ }{n: aac }{1: }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {4:[No Name] [+] }{3:<Name] [+] }| + {2:-- }{5:match 1 of 3} | + ]]) + + feed('<esc><c-w><c-w>oc a<c-x><c-n>') + screen:expect([[ + aaa aab aac{3:│}aaa aab aac | + bbb aaa {3:│}bbb aaa | + c aaa {3:│}c aaa^ | + {1:~ }{3:│}{1:~}{s: aaa }{1: }| + {1:~ }{3:│}{1:~}{n: aab }{1: }| + {1:~ }{3:│}{1:~}{n: aac }{1: }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {1:~ }{3:│}{1:~ }| + {3:<Name] [+] }{4:[No Name] [+] }| + {2:-- }{5:match 1 of 3} | + ]]) + end) end) diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua index 75eb5bb4e3..69f4a44dd8 100644 --- a/test/functional/ui/screen.lua +++ b/test/functional/ui/screen.lua @@ -75,9 +75,11 @@ local global_helpers = require('test.helpers') local deepcopy = global_helpers.deepcopy local shallowcopy = global_helpers.shallowcopy local helpers = require('test.functional.helpers')(nil) -local request, run, uimeths = helpers.request, helpers.run, helpers.uimeths +local request, run_session = helpers.request, helpers.run_session local eq = helpers.eq local dedent = helpers.dedent +local get_session = helpers.get_session +local create_callindex = helpers.create_callindex local inspect = require('inspect') @@ -155,6 +157,8 @@ function Screen.new(width, height) cmdline_block = {}, wildmenu_items = nil, wildmenu_selected = nil, + win_position = {}, + _session = nil, _default_attr_ids = nil, _default_attr_ignore = nil, _mouse_enabled = true, @@ -165,11 +169,19 @@ function Screen.new(width, height) _new_attrs = false, _width = width, _height = height, + _grids = {}, _cursor = { - row = 1, col = 1 + grid = 1, row = 1, col = 1 }, - _busy = false + _busy = false, }, Screen) + local function ui(method, ...) + local status, rv = self._session:request('nvim_ui_'..method, ...) + if not status then + error(rv[2]) + end + end + self.uimeths = create_callindex(ui) return self end @@ -189,34 +201,50 @@ function Screen:set_hlstate_cterm(val) self._hlstate_cterm = val end -function Screen:attach(options) +function Screen:attach(options, session) + if session == nil then + session = get_session() + end if options == nil then options = {} end if options.ext_linegrid == nil then options.ext_linegrid = true end + + self._session = session self._options = options self._clear_attrs = (options.ext_linegrid and {{},{}}) or {} self:_handle_resize(self._width, self._height) - uimeths.attach(self._width, self._height, options) + self.uimeths.attach(self._width, self._height, options) if self._options.rgb == nil then -- nvim defaults to rgb=true internally, -- simplify test code by doing the same. self._options.rgb = true end + if self._options.ext_multigrid then + self._options.ext_linegrid = true + end + self._session = session end function Screen:detach() - uimeths.detach() + self.uimeths.detach() + self._session = nil end function Screen:try_resize(columns, rows) - uimeths.try_resize(columns, rows) + self._width = columns + self._height = rows + self.uimeths.try_resize(columns, rows) +end + +function Screen:try_resize_grid(grid, columns, rows) + self.uimeths.try_resize_grid(grid, columns, rows) end function Screen:set_option(option, value) - uimeths.set_option(option, value) + self.uimeths.set_option(option, value) self._options[option] = value end @@ -321,7 +349,6 @@ function Screen:expect(expected, attr_ids, attr_ignore) -- value. grid = dedent(grid:gsub('\n[ ]+$', ''), 0) for row in grid:gmatch('[^\n]+') do - row = row:sub(1, #row - 1) -- Last char must be the screen delimiter. table.insert(expected_rows, row) end end @@ -341,19 +368,11 @@ function Screen:expect(expected, attr_ids, attr_ignore) end end - if grid ~= nil and self._height ~= #expected_rows then - return ("Expected screen state's row count(" .. #expected_rows - .. ') differs from configured height(' .. self._height .. ') of Screen.') - end - if self._options.ext_hlstate and self._new_attrs then attr_state.id_to_index = self:hlstate_check_attrs(attr_state.ids or {}) end - local actual_rows = {} - for i = 1, self._height do - actual_rows[i] = self:_row_repr(self._rows[i], attr_state) - end + local actual_rows = self:render(not expected.any, attr_state) if expected.any ~= nil then -- Search for `any` anywhere in the screen lines. @@ -362,13 +381,17 @@ function Screen:expect(expected, attr_ids, attr_ignore) return ( 'Failed to match any screen lines.\n' .. 'Expected (anywhere): "' .. expected.any .. '"\n' - .. 'Actual:\n |' .. table.concat(actual_rows, '|\n |') .. '|\n\n') + .. 'Actual:\n |' .. table.concat(actual_rows, '\n |') .. '\n\n') end end if grid ~= nil then -- `expected` must match the screen lines exactly. - for i = 1, self._height do + if #actual_rows ~= #expected_rows then + return "Expected screen state's row count(" .. #expected_rows + .. ') differs from configured height(' .. #actual_rows .. ') of Screen.' + end + for i = 1, #actual_rows do if expected_rows[i] ~= actual_rows[i] then local msg_expected_rows = {} for j = 1, #expected_rows do @@ -378,8 +401,8 @@ function Screen:expect(expected, attr_ids, attr_ignore) actual_rows[i] = '*' .. actual_rows[i] return ( 'Row ' .. tostring(i) .. ' did not match.\n' - ..'Expected:\n |'..table.concat(msg_expected_rows, '|\n |')..'|\n' - ..'Actual:\n |'..table.concat(actual_rows, '|\n |')..'|\n\n'..[[ + ..'Expected:\n |'..table.concat(msg_expected_rows, '\n |')..'\n' + ..'Actual:\n |'..table.concat(actual_rows, '\n |')..'\n\n'..[[ To print the expect() call that would assert the current screen state, use screen:snapshot_util(). In case of non-deterministic failures, use screen:redraw_debug() to show all intermediate screen states. ]]) @@ -465,7 +488,7 @@ function Screen:_wait(check, flags) if not err then success_seen = true if did_miminal_timeout then - helpers.stop() + self._session:stop() end elseif success_seen and #args > 0 then failure_after_success = true @@ -474,7 +497,7 @@ function Screen:_wait(check, flags) return true end - run(nil, notification_cb, nil, minimal_timeout) + run_session(self._session, nil, notification_cb, nil, minimal_timeout) if not did_flush then err = "no flush received" elseif not checked then @@ -487,7 +510,7 @@ function Screen:_wait(check, flags) if not success_seen then did_miminal_timeout = true - run(nil, notification_cb, nil, timeout-minimal_timeout) + run_session(self._session, nil, notification_cb, nil, timeout-minimal_timeout) end local did_warn = false @@ -547,7 +570,7 @@ function Screen:sleep(ms) assert(method == 'redraw') self:_redraw(args) end - run(nil, notification_cb, nil, ms) + run_session(self._session, nil, notification_cb, nil, ms) end function Screen:_redraw(updates) @@ -579,6 +602,22 @@ function Screen:set_on_event_handler(callback) end function Screen:_handle_resize(width, height) + self:_handle_grid_resize(1, width, height) + self._scroll_region = { + top = 1, bot = height, left = 1, right = width + } + self._grid = self._grids[1] +end + +local function min(x,y) + if x < y then + return x + else + return y + end +end + +function Screen:_handle_grid_resize(grid, width, height) local rows = {} for _ = 1, height do local cols = {} @@ -587,22 +626,36 @@ function Screen:_handle_resize(width, height) end table.insert(rows, cols) end - self._cursor.row = 1 - self._cursor.col = 1 - self._rows = rows - self._width = width - self._height = height - self._scroll_region = { - top = 1, bot = height, left = 1, right = width + if grid > 1 and self._grids[grid] ~= nil then + local old = self._grids[grid] + for i = 1, min(height,old.height) do + for j = 1, min(width,old.width) do + rows[i][j] = old.rows[i][j] + end + end + end + + if self._cursor.grid == grid then + self._cursor.row = 1 + self._cursor.col = 1 + end + self._grids[grid] = { + rows=rows, + width=width, + height=height, } end -function Screen:_handle_flush() +function Screen:_handle_win_scroll_over_start() + self.scroll_over = true + self.scroll_over_pos = self._grids[1].height end -function Screen:_handle_grid_resize(grid, width, height) - assert(grid == 1) - self:_handle_resize(width, height) +function Screen:_handle_win_scroll_over_reset() + self.scroll_over = false +end + +function Screen:_handle_flush() end function Screen:_reset() @@ -641,20 +694,27 @@ function Screen:_handle_clear() -- newer clients, to check we remain compatible with both kind of clients, -- ensure the scroll region is in a reset state. local expected_region = { - top = 1, bot = self._height, left = 1, right = self._width + top = 1, bot = self._grid.height, left = 1, right = self._grid.width } eq(expected_region, self._scroll_region) - self:_clear_block(1, self._height, 1, self._width) + self:_handle_grid_clear(1) end function Screen:_handle_grid_clear(grid) - assert(grid == 1) - self:_clear_block(1, self._height, 1, self._width) + self:_clear_block(self._grids[grid], 1, self._grids[grid].height, 1, self._grids[grid].width) +end + +function Screen:_handle_grid_destroy(grid) + self._grids[grid] = nil + if self._options.ext_multigrid then + assert(self.win_position[grid]) + self.win_position[grid] = nil + end end function Screen:_handle_eol_clear() local row, col = self._cursor.row, self._cursor.col - self:_clear_block(row, row, col, self._scroll_region.right) + self:_clear_block(self._grid, row, row, col, self._grid.width) end function Screen:_handle_cursor_goto(row, col) @@ -663,7 +723,7 @@ function Screen:_handle_cursor_goto(row, col) end function Screen:_handle_grid_cursor_goto(grid, row, col) - assert(grid == 1) + self._cursor.grid = grid self._cursor.row = row + 1 self._cursor.col = col + 1 end @@ -704,13 +764,18 @@ function Screen:_handle_scroll(count) self:_handle_grid_scroll(1, top-1, bot, left-1, right, count, 0) end -function Screen:_handle_grid_scroll(grid, top, bot, left, right, rows, cols) +function Screen:_handle_grid_scroll(g, top, bot, left, right, rows, cols) + if self.scroll_over and g == 1 and top < self.scroll_over_pos then + self.scroll_over_pos = top + end + top = top+1 left = left+1 - assert(grid == 1) assert(cols == 0) + local grid = self._grids[g] local start, stop, step + if rows > 0 then start = top stop = bot - rows @@ -723,8 +788,8 @@ function Screen:_handle_grid_scroll(grid, top, bot, left, right, rows, cols) -- shift scroll region for i = start, stop, step do - local target = self._rows[i] - local source = self._rows[i + rows] + local target = grid.rows[i] + local source = grid.rows[i + rows] for j = left, right do target[j].text = source[j].text target[j].attrs = source[j].attrs @@ -734,7 +799,7 @@ function Screen:_handle_grid_scroll(grid, top, bot, left, right, rows, cols) -- clear invalid rows for i = stop + step, stop + rows, step do - self:_clear_row_section(i, left, right) + self:_clear_row_section(grid, i, left, right) end end @@ -744,13 +809,35 @@ function Screen:_handle_hl_attr_define(id, rgb_attrs, cterm_attrs, info) self._new_attrs = true end +function Screen:_handle_win_pos(grid, win, startrow, startcol, width, height) + self.win_position[grid] = { + win = win, + startrow = startrow, + startcol = startcol, + width = width, + height = height + } +end + +function Screen:_handle_win_hide(grid) + self.win_position[grid] = nil +end + +function Screen:get_hl(val) + if self._options.ext_newgrid then + return self._attr_table[val][1] + else + return val + end +end + function Screen:_handle_highlight_set(attrs) self._attrs = attrs end function Screen:_handle_put(str) assert(not self._options.ext_linegrid) - local cell = self._rows[self._cursor.row][self._cursor.col] + local cell = self._grid.rows[self._cursor.row][self._cursor.col] cell.text = str cell.attrs = self._attrs cell.hl_id = -1 @@ -759,8 +846,7 @@ end function Screen:_handle_grid_line(grid, row, col, items) assert(self._options.ext_linegrid) - assert(grid == 1) - local line = self._rows[row+1] + local line = self._grids[grid].rows[row+1] local colpos = col+1 local hl = self._clear_attrs local hl_id = 0 @@ -887,45 +973,68 @@ function Screen:_handle_wildmenu_hide() self.wildmenu_items, self.wildmenu_pos = nil, nil end -function Screen:_clear_block(top, bot, left, right) +function Screen:_clear_block(grid, top, bot, left, right) for i = top, bot do - self:_clear_row_section(i, left, right) + self:_clear_row_section(grid, i, left, right) end end -function Screen:_clear_row_section(rownum, startcol, stopcol) - local row = self._rows[rownum] +function Screen:_clear_row_section(grid, rownum, startcol, stopcol) + local row = grid.rows[rownum] for i = startcol, stopcol do row[i].text = ' ' row[i].attrs = self._clear_attrs end end -function Screen:_row_repr(row, attr_state) +function Screen:_row_repr(gridnr, rownr, attr_state, cursor) local rv = {} local current_attr_id - for i = 1, self._width do - 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) - if current_attr_id and attr_id ~= current_attr_id then - -- close current attribute bracket, add it before any whitespace - -- up to the current cell - -- table.insert(rv, backward_find_meaningful(rv, i), '}') - table.insert(rv, '}') - current_attr_id = nil - end - if not current_attr_id and attr_id then - -- open a new attribute bracket - table.insert(rv, '{' .. attr_id .. ':') - current_attr_id = attr_id + local i = 1 + local has_windows = self._options.ext_multigrid and gridnr == 1 + if self.scroll_over and self.scroll_over_pos < rownr then + has_windows = false + end + local row = self._grids[gridnr].rows[rownr] + while i <= #row do + local did_window = false + if has_windows then + for id,pos in pairs(self.win_position) do + if i-1 == pos.startcol and pos.startrow <= rownr-1 and rownr-1 < pos.startrow + pos.height then + if current_attr_id then + -- close current attribute bracket + table.insert(rv, '}') + current_attr_id = nil + end + table.insert(rv, '['..id..':'..string.rep('-',pos.width)..']') + i = i + pos.width + did_window = true + end + end end - if not self._busy and self._rows[self._cursor.row] == row and self._cursor.col == i then - table.insert(rv, '^') + + 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) + if current_attr_id and attr_id ~= current_attr_id then + -- close current attribute bracket + table.insert(rv, '}') + current_attr_id = nil + end + if not current_attr_id and attr_id then + -- open a new attribute bracket + table.insert(rv, '{' .. attr_id .. ':') + current_attr_id = attr_id + end + if not self._busy and cursor and self._cursor.col == i then + table.insert(rv, '^') + end + table.insert(rv, row[i].text) + i = i + 1 end - table.insert(rv, row[i].text) end if current_attr_id then table.insert(rv, '}') @@ -997,7 +1106,23 @@ function Screen:redraw_debug(attrs, ignore, timeout) if timeout == nil then timeout = 250 end - run(nil, notification_cb, nil, timeout) + run_session(self._session, nil, notification_cb, nil, timeout) +end + +function Screen:render(headers, attr_state, preview) + headers = headers and self._options.ext_multigrid + local rv = {} + for igrid,grid in pairs(self._grids) do + if headers then + table.insert(rv, "## grid "..igrid) + end + for i = 1, grid.height do + local cursor = self._cursor.grid == igrid and self._cursor.row == i + local prefix = (headers or preview) and " " or "" + table.insert(rv, prefix..self:_row_repr(igrid, i, attr_state, cursor).."|") + end + end + return rv end function Screen:print_snapshot(attrs, ignore) @@ -1020,10 +1145,7 @@ function Screen:print_snapshot(attrs, ignore) attr_state.id_to_index = self:hlstate_check_attrs(attr_state.ids) end - local lines = {} - for i = 1, self._height do - table.insert(lines, " "..self:_row_repr(self._rows[i], attr_state).."|") - end + local lines = self:render(true, attr_state, true) local ext_state = self:_extstate_repr(attr_state) local keys = false diff --git a/test/functional/ui/syntax_conceal_spec.lua b/test/functional/ui/syntax_conceal_spec.lua index e7a7004c1e..d678784dc9 100644 --- a/test/functional/ui/syntax_conceal_spec.lua +++ b/test/functional/ui/syntax_conceal_spec.lua @@ -12,7 +12,11 @@ describe('Screen', function() screen:attach() screen:set_default_attr_ids( { [0] = {bold=true, foreground=Screen.colors.Blue}, - [1] = {foreground = Screen.colors.LightGrey, background = Screen.colors.DarkGray} + [1] = {foreground = Screen.colors.LightGrey, background = Screen.colors.DarkGray}, + [2] = {bold = true, reverse = true}, + [3] = {reverse = true}, + [4] = {bold = true}, + [5] = {background = Screen.colors.Yellow}, } ) end) @@ -329,4 +333,494 @@ describe('Screen', function() ]]) end) end) -- conceallevel + + + describe("cursor movement", function() + before_each(function() + command("syn keyword concealy barf conceal cchar=b") + command("set cole=2") + feed('5Ofoo barf bar barf eggs<esc>') + screen:expect([[ + 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 barf bar barf egg^s | + | + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + + end) + + it('between windows', function() + command("split") + screen:expect([[ + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + foo barf bar barf egg^s | + | + {2:[No Name] [+] }| + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + | + {3:[No Name] [+] }| + | + ]]) + feed('<c-w>w') + + screen:expect([[ + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + | + {3:[No Name] [+] }| + foo {1:b} bar {1:b} eggs | + foo barf bar barf egg^s | + | + {2:[No Name] [+] }| + | + ]]) + end) + + it('in insert mode', function() + feed('i') + screen:expect([[ + 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 barf bar barf egg^s | + | + {0:~ }| + {0:~ }| + {0:~ }| + {4:-- INSERT --} | + ]]) + + feed('<up>') + screen:expect([[ + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + foo barf bar barf egg^s | + foo {1:b} bar {1:b} eggs | + | + {0:~ }| + {0:~ }| + {0:~ }| + {4:-- INSERT --} | + ]]) + end) + + it('between modes cocu=iv', function() + command('set cocu=iv') + feed('gg') + screen:expect([[ + ^foo barf bar barf 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 | + | + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + + feed('i') + screen:expect([[ + ^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 | + | + {0:~ }| + {0:~ }| + {0:~ }| + {4:-- INSERT --} | + ]]) + + feed('<esc>') + screen:expect([[ + ^foo barf bar barf 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 | + | + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + + feed('v') + screen:expect([[ + ^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 | + | + {0:~ }| + {0:~ }| + {0:~ }| + {4:-- VISUAL --} | + ]]) + + feed('<esc>') + screen:expect([[ + ^foo barf bar barf 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 | + | + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + + end) + + it('between modes cocu=n', function() + command('set cocu=n') + feed('gg') + screen:expect([[ + ^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 | + | + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + + feed('i') + screen:expect([[ + ^foo barf bar barf 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 | + | + {0:~ }| + {0:~ }| + {0:~ }| + {4:-- INSERT --} | + ]]) + + feed('<esc>') + screen:expect([[ + ^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 | + | + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + + + feed('v') + screen:expect([[ + ^foo barf bar barf 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 | + | + {0:~ }| + {0:~ }| + {0:~ }| + {4:-- VISUAL --} | + ]]) + + feed('<esc>') + screen:expect([[ + ^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 | + | + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + end) + + it('and open line', function() + feed('o') + screen:expect([[ + 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 | + ^ | + | + {0:~ }| + {0:~ }| + {4:-- INSERT --} | + ]]) + end) + + it('and open line cocu=i', function() + command('set cocu=i') + feed('o') + screen:expect([[ + 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 | + ^ | + | + {0:~ }| + {0:~ }| + {4:-- INSERT --} | + ]]) + end) + + describe('with incsearch', function() + before_each(function() + command('set incsearch hlsearch') + feed('2GA x<esc>3GA xy<esc>gg') + screen:expect([[ + ^foo barf bar barf eggs | + foo {1:b} bar {1:b} eggs x | + foo {1:b} bar {1:b} eggs xy | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + | + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + end) + + it('cocu=', function() + feed('/') + screen:expect([[ + foo barf bar barf eggs | + foo {1:b} bar {1:b} eggs x | + foo {1:b} bar {1:b} eggs xy | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + | + {0:~ }| + {0:~ }| + {0:~ }| + /^ | + ]]) + + feed('x') + screen:expect([[ + foo {1:b} bar {1:b} eggs | + foo barf bar barf eggs {3:x} | + foo {1:b} bar {1:b} eggs {5:x}y | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + | + {0:~ }| + {0:~ }| + {0:~ }| + /x^ | + ]]) + + feed('y') + screen:expect([[ + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs x | + foo barf bar barf eggs {3:xy} | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + | + {0:~ }| + {0:~ }| + {0:~ }| + /xy^ | + ]]) + + feed('<c-w>') + screen:expect([[ + foo barf bar barf eggs | + foo {1:b} bar {1:b} eggs x | + foo {1:b} bar {1:b} eggs xy | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + | + {0:~ }| + {0:~ }| + {0:~ }| + /^ | + ]]) + end) + + it('cocu=c', function() + command('set cocu=c') + + feed('/') + -- NB: we don't do this redraw. Probably best to still skip it, + -- to avoid annoying distraction from the cmdline + screen:expect([[ + foo barf bar barf eggs | + foo {1:b} bar {1:b} eggs x | + foo {1:b} bar {1:b} eggs xy | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + | + {0:~ }| + {0:~ }| + {0:~ }| + /^ | + ]]) + + feed('x') + screen:expect([[ + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs {3:x} | + foo {1:b} bar {1:b} eggs {5:x}y | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + | + {0:~ }| + {0:~ }| + {0:~ }| + /x^ | + ]]) + + feed('y') + screen:expect([[ + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs x | + foo {1:b} bar {1:b} eggs {3:xy} | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + | + {0:~ }| + {0:~ }| + {0:~ }| + /xy^ | + ]]) + + feed('<c-w>') + screen:expect([[ + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs x | + foo {1:b} bar {1:b} eggs xy | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + | + {0:~ }| + {0:~ }| + {0:~ }| + /^ | + ]]) + + feed('<esc>') + screen:expect([[ + ^foo barf bar barf eggs | + foo {1:b} bar {1:b} eggs x | + foo {1:b} bar {1:b} eggs xy | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + | + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + end) + + it('cocu=n', function() + command('set cocu=n') + screen:expect([[ + ^foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs x | + foo {1:b} bar {1:b} eggs xy | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + | + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + + feed('/') + -- NB: we don't do this redraw. Probably best to still skip it, + -- to avoid annoying distraction from the cmdline + screen:expect([[ + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs x | + foo {1:b} bar {1:b} eggs xy | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + | + {0:~ }| + {0:~ }| + {0:~ }| + /^ | + ]]) + + feed('x') + screen:expect([[ + foo {1:b} bar {1:b} eggs | + foo barf bar barf eggs {3:x} | + foo {1:b} bar {1:b} eggs {5:x}y | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + | + {0:~ }| + {0:~ }| + {0:~ }| + /x^ | + ]]) + + feed('<c-w>') + screen:expect([[ + foo barf bar barf eggs | + foo {1:b} bar {1:b} eggs x | + foo {1:b} bar {1:b} eggs xy | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + | + {0:~ }| + {0:~ }| + {0:~ }| + /^ | + ]]) + + feed('<esc>') + screen:expect([[ + ^foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs x | + foo {1:b} bar {1:b} eggs xy | + foo {1:b} bar {1:b} eggs | + foo {1:b} bar {1:b} eggs | + | + {0:~ }| + {0:~ }| + {0:~ }| + | + ]]) + end) + end) + end) end) diff --git a/test/functional/ui/wildmode_spec.lua b/test/functional/ui/wildmode_spec.lua index 8931d9245b..ffe71cfadf 100644 --- a/test/functional/ui/wildmode_spec.lua +++ b/test/functional/ui/wildmode_spec.lua @@ -165,7 +165,7 @@ describe("'wildmenu'", function() feed([[:<Tab>]]) -- Invoke wildmenu. -- Check only the last 2 lines, because the shell output is -- system-dependent. - expect_stay_unchanged{any='! # & < = > @ > \n:!^'} + expect_stay_unchanged{any='! # & < = > @ > |\n:!^'} end) end) |