From 8cb5b995b6e4d86035e6950d92c0c68ab4e46787 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 11 Mar 2023 10:05:47 +0800 Subject: vim-patch:9.0.1397: highlight for popupmenu kind and extra cannot be set (#22619) Problem: Highlight for popupmenu kind and extra cannot be set. Solution: Add PmenuKind, PmenuKindSel, PmenuExtra and PmenuExtraSel highlight groups and use them. (Gianmaria Bajo, closes vim/vim#12114) https://github.com/vim/vim/commit/6a7c7749204b256e779c245b1e999bf852ad7b64 Co-authored-by: Gianmaria Bajo --- test/functional/ui/popupmenu_spec.lua | 62 +++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'test/functional/ui/popupmenu_spec.lua') diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index c681453294..944319c443 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -3490,6 +3490,68 @@ describe('builtin popupmenu', function() pasted | ]]) end) + + describe('"kind" and "menu"', function() + before_each(function() + screen:try_resize(30, 8) + exec([[ + func CompleteFunc( findstart, base ) + if a:findstart + return 0 + endif + return { + \ 'words': [ + \ { 'word': 'aword1', 'menu': 'extra text 1', 'kind': 'W', }, + \ { 'word': 'aword2', 'menu': 'extra text 2', 'kind': 'W', }, + \ { 'word': 'aword3', 'menu': 'extra text 3', 'kind': 'W', }, + \]} + endfunc + set completeopt=menu + set completefunc=CompleteFunc + ]]) + end) + + -- oldtest: Test_pum_highlights_default() + it('default highlight groups', function() + feed('iaw') + screen:expect([[ + aword1^ | + {s:aword1 W extra text 1 }{1: }| + {n:aword2 W extra text 2 }{1: }| + {n:aword3 W extra text 3 }{1: }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- }{5:match 1 of 3} | + ]]) + end) + + -- oldtest: Test_pum_highlights_custom() + it('custom highlight groups', function() + exec([[ + hi PmenuKind guifg=Red guibg=Magenta + hi PmenuKindSel guifg=Red guibg=Grey + hi PmenuExtra guifg=White guibg=Magenta + hi PmenuExtraSel guifg=Black guibg=Grey + ]]) + local attrs = screen:get_default_attr_ids() + attrs.kn = {foreground = Screen.colors.Red, background = Screen.colors.Magenta} + attrs.ks = {foreground = Screen.colors.Red, background = Screen.colors.Grey} + attrs.xn = {foreground = Screen.colors.White, background = Screen.colors.Magenta} + attrs.xs = {foreground = Screen.colors.Black, background = Screen.colors.Grey} + feed('iaw') + screen:expect([[ + aword1^ | + {s:aword1 }{ks:W }{xs:extra text 1 }{1: }| + {n:aword2 }{kn:W }{xn:extra text 2 }{1: }| + {n:aword3 }{kn:W }{xn:extra text 3 }{1: }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- }{5:match 1 of 3} | + ]], attrs) + end) + end) end) describe('builtin popupmenu with ui/ext_multigrid', function() -- cgit From 040d9da5c8f4d56e0482758223ea7bb04dc90cc0 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 23 Apr 2023 00:30:52 +0800 Subject: vim-patch:9.0.1476: lines put in non-current window are not displayed (#23265) Problem: Lines put in non-current window are not displayed. (Marius Gedminas) Solution: Don't increment the topline when inserting just above it. (closes vim/vim#12212) https://github.com/vim/vim/commit/e7f05a8780426dc7af247419c6d02d5f1e896689 Co-authored-by: Bram Moolenaar --- test/functional/ui/popupmenu_spec.lua | 103 +++++++++++++++++----------------- 1 file changed, 51 insertions(+), 52 deletions(-) (limited to 'test/functional/ui/popupmenu_spec.lua') diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 944319c443..cfcf83ba42 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -1372,11 +1372,11 @@ describe('builtin popupmenu', function() U{n: qui }{s: }eniam, quis nostrud | e{n: officia }{s: }co laboris nisi ut aliquip ex | {4:[No}{n: deserunt }{s: }{4: }| - L{n: mollit }{s: }sit amet, consectetur | - a{n: anim }{s: }sed do eiusmod tempor | - i{n: id }{s: }re et dolore magna aliqua. | - U{n: est }{s: }eniam, quis nostrud | - e{n: laborum }{c: }co laboris nisi ut aliquip ex | + Est{n: mollit }{s: } | + L{n: anim }{s: }sit amet, consectetur | + a{n: id }{s: }sed do eiusmod tempor | + i{n: est }{s: }re et dolore magna aliqua. | + U{n: laborum }{c: }eniam, quis nostrud | {3:[No}{s: Est }{c: }{3: }| {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | ]]) @@ -1390,11 +1390,11 @@ describe('builtin popupmenu', function() U{n: qui }{s: }eniam, quis nostrud | e{n: officia }{s: }co laboris nisi ut aliquip ex | {4:[No}{n: deserunt }{s: }{4: }| - U{n: mollit }{s: }eniam, quis nostrud | - e{n: anim }{s: }co laboris nisi ut aliquip ex | - e{n: id }{s: }at. Duis aute irure dolor in | - r{n: est }{s: }oluptate velit esse cillum | - d{n: laborum }{c: }ulla pariatur. Excepteur sint | + i{n: mollit }{s: }re et dolore magna aliqua. | + U{n: anim }{s: }eniam, quis nostrud | + e{n: id }{s: }co laboris nisi ut aliquip ex | + e{n: est }{s: }at. Duis aute irure dolor in | + r{n: laborum }{c: }oluptate velit esse cillum | {3:[No}{s: Est }{c: }{3: }| {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | ]]) @@ -1408,11 +1408,11 @@ describe('builtin popupmenu', function() U{n: enim }veniam, quis nostrud | e{n: exercitation }mco laboris nisi ut aliquip ex | {4:[No}{n: ex }{4: }| - U{n: ea }veniam, quis nostrud | - e{n: esse }mco laboris nisi ut aliquip ex | - e{n: eu }uat. Duis aute irure dolor in | - r{s: est }voluptate velit esse cillum | - dolore eu fugiat nulla pariatur. Excepteur sint | + i{n: ea }ore et dolore magna aliqua. | + U{n: esse }veniam, quis nostrud | + e{n: eu }mco laboris nisi ut aliquip ex | + e{s: est }uat. Duis aute irure dolor in | + reprehenderit in voluptate velit esse cillum | {3:[No Name] [+] }| {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | ]]) @@ -1426,11 +1426,11 @@ describe('builtin popupmenu', function() U{n: enim }veniam, quis nostrud | e{n: exercitation }mco laboris nisi ut aliquip ex | {4:[No}{n: ex }{4: }| - L{n: ea } sit amet, consectetur | - a{n: esse } sed do eiusmod tempor | - i{n: eu }ore et dolore magna aliqua. | - U{s: est }veniam, quis nostrud | - exercitation ullamco laboris nisi ut aliquip ex | + Est{n: ea } | + L{n: esse } sit amet, consectetur | + a{n: eu } sed do eiusmod tempor | + i{s: est }ore et dolore magna aliqua. | + Ut enim ad minim veniam, quis nostrud | {3:[No Name] [+] }| {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | ]]) @@ -1444,11 +1444,11 @@ describe('builtin popupmenu', function() Ut enim ad minim veniam, quis nostrud | exercitation ullamco laboris nisi ut aliquip ex | {4:[No Name] [+] }| + Est es | Lorem ipsum dolor sit amet, consectetur | adipisicing elit, sed do eiusmod tempor | incididunt ut labore et dolore magna aliqua. | Ut enim ad minim veniam, quis nostrud | - exercitation ullamco laboris nisi ut aliquip ex | {3:[No Name] [+] }| {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | ]]) @@ -1462,11 +1462,11 @@ describe('builtin popupmenu', function() Ut enim ad minim veniam, quis nostrud | exercitation ullamco laboris nisi ut aliquip ex | {4:[No Name] [+] }| + incididunt ut labore et dolore magna aliqua. | Ut enim ad minim veniam, quis nostrud | exercitation ullamco laboris nisi ut aliquip ex | ea commodo consequat. Duis aute irure dolor in | reprehenderit in voluptate velit esse cillum | - dolore eu fugiat nulla pariatur. Excepteur sint | {3:[No Name] [+] }| {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | ]]) @@ -1480,11 +1480,11 @@ describe('builtin popupmenu', function() U{n: enim }veniam, quis nostrud | e{n: exercitation }mco laboris nisi ut aliquip ex | {4:[No}{n: ex }{4: }| - U{n: ea }veniam, quis nostrud | - e{n: esse }mco laboris nisi ut aliquip ex | - e{n: eu }uat. Duis aute irure dolor in | - r{s: est }voluptate velit esse cillum | - dolore eu fugiat nulla pariatur. Excepteur sint | + i{n: ea }ore et dolore magna aliqua. | + U{n: esse }veniam, quis nostrud | + e{n: eu }mco laboris nisi ut aliquip ex | + e{s: est }uat. Duis aute irure dolor in | + reprehenderit in voluptate velit esse cillum | {3:[No Name] [+] }| {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | ]]) @@ -1498,11 +1498,11 @@ describe('builtin popupmenu', function() U{n: enim }veniam, quis nostrud | e{n: exercitation }mco laboris nisi ut aliquip ex | {4:[No}{n: ex }{4: }| - U{n: ea }veniam, quis nostrud | - e{n: esse }mco laboris nisi ut aliquip ex | - e{s: eu }uat. Duis aute irure dolor in | - r{n: est }voluptate velit esse cillum | - dolore eu fugiat nulla pariatur. Excepteur sint | + i{n: ea }ore et dolore magna aliqua. | + U{n: esse }veniam, quis nostrud | + e{s: eu }mco laboris nisi ut aliquip ex | + e{n: est }uat. Duis aute irure dolor in | + reprehenderit in voluptate velit esse cillum | {3:[No Name] [+] }| {2:-- Keyword Local completion (^N^P) }{5:match 22 of 65} | ]]) @@ -1516,16 +1516,15 @@ describe('builtin popupmenu', function() U{n: enim }veniam, quis nostrud | e{n: exercitation }mco laboris nisi ut aliquip ex | {4:[No}{n: ex }{4: }| - r{n: ea }voluptate velit esse cillum | - d{n: esse }nulla pariatur. Excepteur sint | - o{s: eu }t non proident, sunt in culpa | - q{n: est }unt mollit anim id est | - laborum. | + e{n: ea }uat. Duis aute irure dolor in | + r{n: esse }voluptate velit esse cillum | + d{s: eu }nulla pariatur. Excepteur sint | + o{n: est }t non proident, sunt in culpa | + qui officia deserunt mollit anim id est | {3:[No Name] [+] }| {2:-- Keyword Local completion (^N^P) }{5:match 22 of 65} | ]]) - funcs.complete(4, {'ea', 'eeeeeeeeeeeeeeeeee', 'ei', 'eo', 'eu', 'ey', 'eå', 'eä', 'eö'}) screen:expect([[ Est eu^ | @@ -1535,11 +1534,11 @@ describe('builtin popupmenu', function() {n: eo }iam, quis nostrud | {n: eu } laboris nisi ut aliquip ex | {4:[N}{n: ey }{4: }| - {n: eå }uptate velit esse cillum | - {n: eä }la pariatur. Excepteur sint | - {n: eö }on proident, sunt in culpa | + {n: eå }. Duis aute irure dolor in | + {n: eä }uptate velit esse cillum | + {n: eö }la pariatur. Excepteur sint | + occaecat cupidatat non proident, sunt in culpa | qui officia deserunt mollit anim id est | - laborum. | {3:[No Name] [+] }| {2:-- Keyword Local completion (^N^P) }{5:match 1 of 9} | ]]) @@ -1553,11 +1552,11 @@ describe('builtin popupmenu', function() {n: eo } veniam, quis nostrud | {n: eu }amco laboris nisi ut aliquip ex | {4:[N}{n: ey }{4: }| - {n: eå } voluptate velit esse cillum | - {n: eä } nulla pariatur. Excepteur sint | - {n: eö }at non proident, sunt in culpa | + {n: eå }quat. Duis aute irure dolor in | + {n: eä } voluptate velit esse cillum | + {n: eö } nulla pariatur. Excepteur sint | + occaecat cupidatat non proident, sunt in culpa | qui officia deserunt mollit anim id est | - laborum. | {3:[No Name] [+] }| {2:-- INSERT --} | ]]) @@ -1571,11 +1570,11 @@ describe('builtin popupmenu', function() {n: eo } veniam, quis nostrud | {n: eu }amco laboris nisi ut aliquip ex | {4:[N}{n: ey }{4: }| - {n: eå } voluptate velit esse cillum | - {n: eä } nulla pariatur. Excepteur sint | - {n: eö }at non proident, sunt in culpa | + {n: eå }quat. Duis aute irure dolor in | + {n: eä } voluptate velit esse cillum | + {n: eö } nulla pariatur. Excepteur sint | + occaecat cupidatat non proident, sunt in culpa | qui officia deserunt mollit anim id est | - laborum. | {3:[No Name] [+] }| {2:-- INSERT --} | ]]) @@ -1589,11 +1588,11 @@ describe('builtin popupmenu', function() Ut enim ad minim veniam, quis nostrud | exercitation ullamco laboris nisi ut aliquip ex | {4:[No Name] [+] }| + ea commodo consequat. Duis aute irure dolor in | reprehenderit in voluptate velit esse cillum | dolore eu fugiat nulla pariatur. Excepteur sint | occaecat cupidatat non proident, sunt in culpa | qui officia deserunt mollit anim id est | - laborum. | {3:[No Name] [+] }| {2:-- INSERT --} | ]]) @@ -1607,11 +1606,11 @@ describe('builtin popupmenu', function() Ut enim ad minim veniam, quis nostrud | exercitation ullamco laboris nisi ut aliquip ex | {4:[No Name] [+] }| + ea commodo consequat. Duis aute irure dolor in | reprehenderit in voluptate velit esse cillum | dolore eu fugiat nulla pariatur. Excepteur sint | occaecat cupidatat non proident, sunt in culpa | qui officia deserunt mollit anim id est | - laborum. | {3:[No Name] [+] }| {2:-- INSERT --} | ]]) -- cgit From c1331a65dd12dd1128db5fb136a77218ef7376f1 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 24 Apr 2023 09:26:10 +0800 Subject: fix(pum): show right-click menu above cmdline area (#23298) --- test/functional/ui/popupmenu_spec.lua | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'test/functional/ui/popupmenu_spec.lua') diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index cfcf83ba42..53ef60bc89 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -3259,16 +3259,16 @@ describe('builtin popupmenu', function() :let g:menustr = 'bar' | ]]) eq('bar', meths.get_var('menustr')) - feed('<20,1>') + feed('<20,2>') screen:expect([[ ^popup menu test | {1:~ }| + {1:~ }| {1:~ }{n: foo }{1: }| {1:~ }{n: bar }{1: }| - {1:~ }{n: baz }{1: }| - :let g:menustr = 'bar' | + :let g:menustr = 'b{n: baz } | ]]) - feed('<22,4>') + feed('<22,5>') screen:expect([[ ^popup menu test | {1:~ }| @@ -3675,7 +3675,7 @@ describe('builtin popupmenu with ui/ext_multigrid', function() {n: foo }| {n: bar }| {n: baz }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 2, 19, false, 100}}}) + ]], float_pos={[4] = {{id = -1}, 'NW', 2, 2, 19, false, 250}}}) meths.input_mouse('left', 'press', '', 4, 2, 2) screen:expect({grid=[[ ## grid 1 @@ -3716,7 +3716,7 @@ describe('builtin popupmenu with ui/ext_multigrid', function() {n: foo }| {n: bar }| {n: baz }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 100}}}) + ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) meths.input_mouse('right', 'drag', '', 2, 3, 6) screen:expect({grid=[[ ## grid 1 @@ -3738,7 +3738,7 @@ describe('builtin popupmenu with ui/ext_multigrid', function() {n: foo }| {n: bar }| {s: baz }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 100}}}) + ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) meths.input_mouse('right', 'release', '', 2, 1, 6) screen:expect({grid=[[ ## grid 1 @@ -3780,7 +3780,7 @@ describe('builtin popupmenu with ui/ext_multigrid', function() {n: foo }| {n: bar }| {n: baz }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 100}}}) + ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) eq(true, screen.options.mousemoveevent) meths.input_mouse('move', '', '', 2, 3, 6) screen:expect({grid=[[ @@ -3803,7 +3803,7 @@ describe('builtin popupmenu with ui/ext_multigrid', function() {n: foo }| {n: bar }| {s: baz }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 100}}}) + ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) eq(true, screen.options.mousemoveevent) meths.input_mouse('left', 'press', '', 2, 2, 6) screen:expect({grid=[[ -- cgit From a3dfe1bc89a518442503189ca074ee8ab4b8b0d4 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 27 Apr 2023 20:19:21 +0800 Subject: fix(pum): position properly with ext_multigrid (#23336) --- test/functional/ui/popupmenu_spec.lua | 5853 +++++++++++++++++++-------------- 1 file changed, 3304 insertions(+), 2549 deletions(-) (limited to 'test/functional/ui/popupmenu_spec.lua') diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 53ef60bc89..c5e0c10a81 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -1023,1869 +1023,11 @@ describe('ui/ext_popupmenu', function() end) end) +describe("builtin popupmenu 'pumblend'", function() + before_each(clear) -describe('builtin popupmenu', function() - local screen - before_each(function() - clear() - screen = Screen.new(32, 20) - screen:attach() - screen:set_default_attr_ids({ - -- popup selected item / scrollbar track - ['s'] = {background = Screen.colors.WebGray}, - -- popup non-selected item - ['n'] = {background = Screen.colors.LightMagenta}, - -- popup scrollbar knob - ['c'] = {background = Screen.colors.Grey0}, - [1] = {bold = true, foreground = Screen.colors.Blue}, - [2] = {bold = true}, - [3] = {reverse = true}, - [4] = {bold = true, reverse = true}, - [5] = {bold = true, foreground = Screen.colors.SeaGreen}, - [6] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - [7] = {background = Screen.colors.Yellow}, -- Search - [8] = {foreground = Screen.colors.Red}, - }) - end) - - it('with preview-window above', function() - feed(':ped4+') - feed('iaa bb cc dd ee ff gg hh ii jj') - feed('') - screen:expect([[ - aa bb cc dd ee ff gg hh ii jj | - aa | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {3:[No Name] [Preview][+] }| - aa bb cc dd ee ff gg hh ii jj | - aa^ | - {s:aa }{c: }{1: }| - {n:bb }{c: }{1: }| - {n:cc }{c: }{1: }| - {n:dd }{c: }{1: }| - {n:ee }{c: }{1: }| - {n:ff }{c: }{1: }| - {n:gg }{s: }{1: }| - {n:hh }{s: }{4: }| - {2:-- }{5:match 1 of 10} | - ]]) - end) - - it('with preview-window below', function() - feed(':ped4+r') - feed('iaa bb cc dd ee ff gg hh ii jj') - feed('') - screen:expect([[ - aa bb cc dd ee ff gg hh ii jj | - aa^ | - {s:aa }{c: }{1: }| - {n:bb }{c: }{1: }| - {n:cc }{c: }{1: }| - {n:dd }{c: }{1: }| - {n:ee }{c: }{1: }| - {n:ff }{c: }{1: }| - {n:gg }{s: }{1: }| - {n:hh }{s: }{4: }| - aa bb cc dd ee ff gg hh ii jj | - aa | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {3:[No Name] [Preview][+] }| - {2:-- }{5:match 1 of 10} | - ]]) - end) - - it('with preview-window above and tall and inverted', function() - feed(':ped8+') - feed('iaabbccddee') - feed('ffgghhiijj') - feed('kkllmmnnoo') - feed('') - screen:expect([[ - aa | - bb | - cc | - dd | - {s:aa }{c: }{3:ew][+] }| - {n:bb }{c: } | - {n:cc }{c: } | - {n:dd }{c: } | - {n:ee }{c: } | - {n:ff }{c: } | - {n:gg }{c: } | - {n:hh }{c: } | - {n:ii }{c: } | - {n:jj }{c: } | - {n:kk }{c: } | - {n:ll }{s: } | - {n:mm }{s: } | - aa^ | - {4:[No Name] [+] }| - {2:-- }{5:match 1 of 15} | - ]]) - end) - - it('with preview-window above and short and inverted', function() - feed(':ped4+') - feed('iaabbccddee') - feed('ffgghhiijj') - feed('') - screen:expect([[ - aa | - bb | - cc | - dd | - ee | - ff | - gg | - hh | - {s:aa }{c: }{3:ew][+] }| - {n:bb }{c: } | - {n:cc }{c: } | - {n:dd }{c: } | - {n:ee }{c: } | - {n:ff }{c: } | - {n:gg }{c: } | - {n:hh }{c: } | - {n:ii }{s: } | - aa^ | - {4:[No Name] [+] }| - {2:-- }{5:match 1 of 10} | - ]]) - end) - - it('with preview-window below and inverted', function() - feed(':ped4+r') - feed('iaabbccddee') - feed('ffgghhiijj') - feed('') - screen:expect([[ - {s:aa }{c: } | - {n:bb }{c: } | - {n:cc }{c: } | - {n:dd }{c: } | - {n:ee }{c: } | - {n:ff }{c: } | - {n:gg }{s: } | - {n:hh }{s: } | - aa^ | - {4:[No Name] [+] }| - aa | - bb | - cc | - dd | - ee | - ff | - gg | - hh | - {3:[No Name] [Preview][+] }| - {2:-- }{5:match 1 of 10} | - ]]) - end) - - -- oldtest: Test_pum_with_preview_win() - it('preview window opened during completion', function() - exec([[ - funct Omni_test(findstart, base) - if a:findstart - return col(".") - 1 - endif - return [#{word: "one", info: "1info"}, #{word: "two", info: "2info"}, #{word: "three", info: "3info"}] - endfunc - set omnifunc=Omni_test - set completeopt+=longest - ]]) - feed('Gi') - screen:expect([[ - ^ | - {n:one }{1: }| - {n:two }{1: }| - {n:three }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {2:-- }{8:Back at original} | - ]]) - feed('') - screen:expect([[ - 1info | - | - {1:~ }| - {3:[Scratch] [Preview] }| - one^ | - {s:one }{1: }| - {n:two }{1: }| - {n:three }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {4:[No Name] [+] }| - {2:-- }{5:match 1 of 3} | - ]]) - end) - - it('with vsplits', function() - insert('aaa aab aac\n') - feed(':vsplit') - screen:expect([[ - aaa aab aac │aaa aab aac| - ^ │ | - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {4:[No Name] [+] }{3:') - screen:expect([[ - aaa aab aac │aaa aab aac| - bbb aaa^ │bbb aaa | - {1:~ }{s: aaa }{1: }│{1:~ }| - {1:~ }{n: aab }{1: }│{1:~ }| - {1:~ }{n: aac }{1: }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {4:[No Name] [+] }{3:oc a') - screen:expect([[ - aaa aab aac│aaa aab aac | - bbb aaa │bbb aaa | - c aaa │c aaa^ | - {1:~ }│{1:~}{s: aaa }{1: }| - {1:~ }│{1:~}{n: aab }{1: }| - {1:~ }│{1:~}{n: aac }{1: }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {1:~ }│{1:~ }| - {3:') - screen:expect([[ - Est ^ | - L{n: sunt }{s: }sit amet, consectetur | - a{n: in }{s: }sed do eiusmod tempor | - i{n: culpa }{s: }re et dolore magna aliqua. | - U{n: qui }{s: }eniam, quis nostrud | - e{n: officia }{s: }co laboris nisi ut aliquip ex | - {4:[No}{n: deserunt }{s: }{4: }| - Est{n: mollit }{s: } | - L{n: anim }{s: }sit amet, consectetur | - a{n: id }{s: }sed do eiusmod tempor | - i{n: est }{s: }re et dolore magna aliqua. | - U{n: laborum }{c: }eniam, quis nostrud | - {3:[No}{s: Est }{c: }{3: }| - {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | - ]]) - - meths.input_mouse('wheel', 'down', '', 0, 9, 40) - screen:expect([[ - Est ^ | - L{n: sunt }{s: }sit amet, consectetur | - a{n: in }{s: }sed do eiusmod tempor | - i{n: culpa }{s: }re et dolore magna aliqua. | - U{n: qui }{s: }eniam, quis nostrud | - e{n: officia }{s: }co laboris nisi ut aliquip ex | - {4:[No}{n: deserunt }{s: }{4: }| - i{n: mollit }{s: }re et dolore magna aliqua. | - U{n: anim }{s: }eniam, quis nostrud | - e{n: id }{s: }co laboris nisi ut aliquip ex | - e{n: est }{s: }at. Duis aute irure dolor in | - r{n: laborum }{c: }oluptate velit esse cillum | - {3:[No}{s: Est }{c: }{3: }| - {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | - ]]) - - feed('e') - screen:expect([[ - Est e^ | - L{n: elit } sit amet, consectetur | - a{n: eiusmod } sed do eiusmod tempor | - i{n: et }ore et dolore magna aliqua. | - U{n: enim }veniam, quis nostrud | - e{n: exercitation }mco laboris nisi ut aliquip ex | - {4:[No}{n: ex }{4: }| - i{n: ea }ore et dolore magna aliqua. | - U{n: esse }veniam, quis nostrud | - e{n: eu }mco laboris nisi ut aliquip ex | - e{s: est }uat. Duis aute irure dolor in | - reprehenderit in voluptate velit esse cillum | - {3:[No Name] [+] }| - {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | - ]]) - - meths.input_mouse('wheel', 'up', '', 0, 9, 40) - screen:expect([[ - Est e^ | - L{n: elit } sit amet, consectetur | - a{n: eiusmod } sed do eiusmod tempor | - i{n: et }ore et dolore magna aliqua. | - U{n: enim }veniam, quis nostrud | - e{n: exercitation }mco laboris nisi ut aliquip ex | - {4:[No}{n: ex }{4: }| - Est{n: ea } | - L{n: esse } sit amet, consectetur | - a{n: eu } sed do eiusmod tempor | - i{s: est }ore et dolore magna aliqua. | - Ut enim ad minim veniam, quis nostrud | - {3:[No Name] [+] }| - {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | - ]]) - - feed('s') - screen:expect([[ - Est es^ | - L{n: esse } sit amet, consectetur | - a{s: est } sed do eiusmod tempor | - incididunt ut labore et dolore magna aliqua. | - Ut enim ad minim veniam, quis nostrud | - exercitation ullamco laboris nisi ut aliquip ex | - {4:[No Name] [+] }| - Est es | - Lorem ipsum dolor sit amet, consectetur | - adipisicing elit, sed do eiusmod tempor | - incididunt ut labore et dolore magna aliqua. | - Ut enim ad minim veniam, quis nostrud | - {3:[No Name] [+] }| - {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | - ]]) - - meths.input_mouse('wheel', 'down', '', 0, 9, 40) - screen:expect([[ - Est es^ | - L{n: esse } sit amet, consectetur | - a{s: est } sed do eiusmod tempor | - incididunt ut labore et dolore magna aliqua. | - Ut enim ad minim veniam, quis nostrud | - exercitation ullamco laboris nisi ut aliquip ex | - {4:[No Name] [+] }| - incididunt ut labore et dolore magna aliqua. | - Ut enim ad minim veniam, quis nostrud | - exercitation ullamco laboris nisi ut aliquip ex | - ea commodo consequat. Duis aute irure dolor in | - reprehenderit in voluptate velit esse cillum | - {3:[No Name] [+] }| - {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | - ]]) - - feed('') - screen:expect([[ - Est e^ | - L{n: elit } sit amet, consectetur | - a{n: eiusmod } sed do eiusmod tempor | - i{n: et }ore et dolore magna aliqua. | - U{n: enim }veniam, quis nostrud | - e{n: exercitation }mco laboris nisi ut aliquip ex | - {4:[No}{n: ex }{4: }| - i{n: ea }ore et dolore magna aliqua. | - U{n: esse }veniam, quis nostrud | - e{n: eu }mco laboris nisi ut aliquip ex | - e{s: est }uat. Duis aute irure dolor in | - reprehenderit in voluptate velit esse cillum | - {3:[No Name] [+] }| - {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | - ]]) - - feed('') - screen:expect([[ - Est eu^ | - L{n: elit } sit amet, consectetur | - a{n: eiusmod } sed do eiusmod tempor | - i{n: et }ore et dolore magna aliqua. | - U{n: enim }veniam, quis nostrud | - e{n: exercitation }mco laboris nisi ut aliquip ex | - {4:[No}{n: ex }{4: }| - i{n: ea }ore et dolore magna aliqua. | - U{n: esse }veniam, quis nostrud | - e{s: eu }mco laboris nisi ut aliquip ex | - e{n: est }uat. Duis aute irure dolor in | - reprehenderit in voluptate velit esse cillum | - {3:[No Name] [+] }| - {2:-- Keyword Local completion (^N^P) }{5:match 22 of 65} | - ]]) - - meths.input_mouse('wheel', 'down', '', 0, 9, 40) - screen:expect([[ - Est eu^ | - L{n: elit } sit amet, consectetur | - a{n: eiusmod } sed do eiusmod tempor | - i{n: et }ore et dolore magna aliqua. | - U{n: enim }veniam, quis nostrud | - e{n: exercitation }mco laboris nisi ut aliquip ex | - {4:[No}{n: ex }{4: }| - e{n: ea }uat. Duis aute irure dolor in | - r{n: esse }voluptate velit esse cillum | - d{s: eu }nulla pariatur. Excepteur sint | - o{n: est }t non proident, sunt in culpa | - qui officia deserunt mollit anim id est | - {3:[No Name] [+] }| - {2:-- Keyword Local completion (^N^P) }{5:match 22 of 65} | - ]]) - - funcs.complete(4, {'ea', 'eeeeeeeeeeeeeeeeee', 'ei', 'eo', 'eu', 'ey', 'eå', 'eä', 'eö'}) - screen:expect([[ - Est eu^ | - {s: ea }t amet, consectetur | - {n: eeeeeeeeeeeeeeeeee }d do eiusmod tempor | - {n: ei } et dolore magna aliqua. | - {n: eo }iam, quis nostrud | - {n: eu } laboris nisi ut aliquip ex | - {4:[N}{n: ey }{4: }| - {n: eå }. Duis aute irure dolor in | - {n: eä }uptate velit esse cillum | - {n: eö }la pariatur. Excepteur sint | - occaecat cupidatat non proident, sunt in culpa | - qui officia deserunt mollit anim id est | - {3:[No Name] [+] }| - {2:-- Keyword Local completion (^N^P) }{5:match 1 of 9} | - ]]) - - funcs.complete(4, {'ea', 'eee', 'ei', 'eo', 'eu', 'ey', 'eå', 'eä', 'eö'}) - screen:expect([[ - Est eu^ | - {s: ea }r sit amet, consectetur | - {n: eee }, sed do eiusmod tempor | - {n: ei }bore et dolore magna aliqua. | - {n: eo } veniam, quis nostrud | - {n: eu }amco laboris nisi ut aliquip ex | - {4:[N}{n: ey }{4: }| - {n: eå }quat. Duis aute irure dolor in | - {n: eä } voluptate velit esse cillum | - {n: eö } nulla pariatur. Excepteur sint | - occaecat cupidatat non proident, sunt in culpa | - qui officia deserunt mollit anim id est | - {3:[No Name] [+] }| - {2:-- INSERT --} | - ]]) - - feed('') - screen:expect([[ - Esteee^ | - {n: ea }r sit amet, consectetur | - {s: eee }, sed do eiusmod tempor | - {n: ei }bore et dolore magna aliqua. | - {n: eo } veniam, quis nostrud | - {n: eu }amco laboris nisi ut aliquip ex | - {4:[N}{n: ey }{4: }| - {n: eå }quat. Duis aute irure dolor in | - {n: eä } voluptate velit esse cillum | - {n: eö } nulla pariatur. Excepteur sint | - occaecat cupidatat non proident, sunt in culpa | - qui officia deserunt mollit anim id est | - {3:[No Name] [+] }| - {2:-- INSERT --} | - ]]) - - funcs.complete(6, {'foo', 'bar'}) - screen:expect([[ - Esteee^ | - Lo{s: foo }sit amet, consectetur | - ad{n: bar }sed do eiusmod tempor | - incididunt ut labore et dolore magna aliqua. | - Ut enim ad minim veniam, quis nostrud | - exercitation ullamco laboris nisi ut aliquip ex | - {4:[No Name] [+] }| - ea commodo consequat. Duis aute irure dolor in | - reprehenderit in voluptate velit esse cillum | - dolore eu fugiat nulla pariatur. Excepteur sint | - occaecat cupidatat non proident, sunt in culpa | - qui officia deserunt mollit anim id est | - {3:[No Name] [+] }| - {2:-- INSERT --} | - ]]) - - feed('') - screen:expect([[ - Esteefoo^ | - Lorem ipsum dolor sit amet, consectetur | - adipisicing elit, sed do eiusmod tempor | - incididunt ut labore et dolore magna aliqua. | - Ut enim ad minim veniam, quis nostrud | - exercitation ullamco laboris nisi ut aliquip ex | - {4:[No Name] [+] }| - ea commodo consequat. Duis aute irure dolor in | - reprehenderit in voluptate velit esse cillum | - dolore eu fugiat nulla pariatur. Excepteur sint | - occaecat cupidatat non proident, sunt in culpa | - qui officia deserunt mollit anim id est | - {3:[No Name] [+] }| - {2:-- INSERT --} | - ]]) - end) - - it('can be moved due to wrap or resize', function() - feed('isome long prefix before the ') - command("set completeopt+=noinsert,noselect") - command("set linebreak") - funcs.complete(29, {'word', 'choice', 'text', 'thing'}) - screen:expect([[ - some long prefix before the ^ | - {1:~ }{n: word }| - {1:~ }{n: choice}| - {1:~ }{n: text }| - {1:~ }{n: thing }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]]) - - feed('') - screen:expect([[ - some long prefix before the | - thing^ | - {n:word }{1: }| - {n:choice }{1: }| - {n:text }{1: }| - {s:thing }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]]) - - feed('') - screen:expect([[ - some long prefix before the text| - {1:^~ }{n: word }| - {1:~ }{n: choice}| - {1:~ }{s: text }| - {1:~ }{n: thing }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]]) - - screen:try_resize(30,8) - screen:expect([[ - some long prefix before the | - text^ | - {n:word }{1: }| - {n:choice }{1: }| - {s:text }{1: }| - {n:thing }{1: }| - {1:~ }| - {2:-- INSERT --} | - ]]) - - screen:try_resize(50,8) - screen:expect([[ - some long prefix before the text^ | - {1:~ }{n: word }{1: }| - {1:~ }{n: choice }{1: }| - {1:~ }{s: text }{1: }| - {1:~ }{n: thing }{1: }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]]) - - screen:try_resize(25,10) - screen:expect([[ - some long prefix before | - the text^ | - {1:~ }{n: word }{1: }| - {1:~ }{n: choice }{1: }| - {1:~ }{s: text }{1: }| - {1:~ }{n: thing }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]]) - - screen:try_resize(12,5) - screen:expect([[ - some long | - prefix | - bef{n: word } | - tex{n: }^ | - {2:-- INSERT -} | - ]]) - - -- can't draw the pum, but check we don't crash - screen:try_resize(12,2) - screen:expect([[ - text^ | - {2:-- INSERT -} | - ]]) - - -- but state is preserved, pum reappears - screen:try_resize(20,8) - screen:expect([[ - some long prefix | - before the text^ | - {1:~ }{n: word }{1: }| - {1:~ }{n: choice }{1: }| - {1:~ }{s: text }{1: }| - {1:~ }{n: thing }{1: }| - {1:~ }| - {2:-- INSERT --} | - ]]) - end) - - it('with VimResized autocmd', function() - feed('isome long prefix before the ') - command("set completeopt+=noinsert,noselect") - command("autocmd VimResized * redraw!") - command("set linebreak") - funcs.complete(29, {'word', 'choice', 'text', 'thing'}) - screen:expect([[ - some long prefix before the ^ | - {1:~ }{n: word }| - {1:~ }{n: choice}| - {1:~ }{n: text }| - {1:~ }{n: thing }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]]) - - screen:try_resize(16,10) - screen:expect([[ - some long | - prefix before | - the ^ | - {1:~ }{n: word }| - {1:~ }{n: choice }| - {1:~ }{n: text }| - {1:~ }{n: thing }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]]) - end) - - it('with rightleft window', function() - command("set rl wildoptions+=pum") - feed('isome rightleft ') - screen:expect([[ - ^ tfelthgir emos| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {2:-- INSERT --} | - ]]) - - command("set completeopt+=noinsert,noselect") - funcs.complete(16, {'word', 'choice', 'text', 'thing'}) - screen:expect([[ - ^ tfelthgir emos| - {1: }{n: drow}{1: ~}| - {1: }{n: eciohc}{1: ~}| - {1: }{n: txet}{1: ~}| - {1: }{n: gniht}{1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {2:-- INSERT --} | - ]]) - - feed('') - screen:expect([[ - ^ drow tfelthgir emos| - {1: }{s: drow}{1: ~}| - {1: }{n: eciohc}{1: ~}| - {1: }{n: txet}{1: ~}| - {1: }{n: gniht}{1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {2:-- INSERT --} | - ]]) - - feed('') - screen:expect([[ - ^ drow tfelthgir emos| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {2:-- INSERT --} | - ]]) - - -- not rightleft on the cmdline - feed(':sign ') - screen:expect{grid=[[ - drow tfelthgir emos| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - :sign ^ | - ]]} - - feed('') - screen:expect{grid=[[ - drow tfelthgir emos| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: ~}| - {1: }{s: define }{1: ~}| - {1: }{n: jump }{1: ~}| - {1: }{n: list }{1: ~}| - {1: }{n: place }{1: ~}| - {1: }{n: undefine }{1: ~}| - {1: }{n: unplace }{1: ~}| - :sign define^ | - ]]} - end) - - it('with multiline messages', function() - screen:try_resize(40,8) - feed('ixx') - command('imap echoerr "very"\\|echoerr "much"\\|echoerr "error"') - funcs.complete(1, {'word', 'choice', 'text', 'thing'}) - screen:expect([[ - xx | - word^ | - {s:word }{1: }| - {n:choice }{1: }| - {n:text }{1: }| - {n:thing }{1: }| - {1:~ }| - {2:-- INSERT --} | - ]]) - - feed('') - screen:expect([[ - xx | - word | - {s:word }{1: }| - {4: }| - {6:very} | - {6:much} | - {6:error} | - {5:Press ENTER or type command to continue}^ | - ]]) - - feed('') - screen:expect([[ - xx | - word^ | - {s:word }{1: }| - {n:choice }{1: }| - {n:text }{1: }| - {n:thing }{1: }| - {1:~ }| - {2:-- INSERT --} | - ]]) - - feed('') - screen:expect([[ - xx | - choice^ | - {n:word }{1: }| - {s:choice }{1: }| - {n:text }{1: }| - {n:thing }{1: }| - {1:~ }| - {2:-- INSERT --} | - ]]) - - command("split") - screen:expect([[ - xx | - choice^ | - {n:word }{1: }| - {s:choice }{4: }| - {n:text } | - {n:thing } | - {3:[No Name] [+] }| - {2:-- INSERT --} | - ]]) - - meths.input_mouse('wheel', 'down', '', 0, 6, 15) - screen:expect{grid=[[ - xx | - choice^ | - {n:word }{1: }| - {s:choice }{4: }| - {n:text } | - {n:thing }{1: }| - {3:[No Name] [+] }| - {2:-- INSERT --} | - ]], unchanged=true} - end) - - it('with kind, menu and abbr attributes', function() - screen:try_resize(40,8) - feed('ixx ') - funcs.complete(4, {{word='wordey', kind= 'x', menu='extrainfo'}, 'thing', {word='secret', abbr='sneaky', menu='bar'}}) - screen:expect([[ - xx wordey^ | - {1:~ }{s: wordey x extrainfo }{1: }| - {1:~ }{n: thing }{1: }| - {1:~ }{n: sneaky bar }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]]) - - feed('') - screen:expect([[ - xx ^ | - {1:~ }{n: wordey x extrainfo }{1: }| - {1:~ }{n: thing }{1: }| - {1:~ }{n: sneaky bar }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]]) - - feed('') - screen:expect([[ - xx secret^ | - {1:~ }{n: wordey x extrainfo }{1: }| - {1:~ }{n: thing }{1: }| - {1:~ }{s: sneaky bar }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]]) - - feed('') - screen:expect([[ - xx secre^t | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - | - ]]) - end) - - it('wildoptions=pum', function() - screen:try_resize(32,10) - command('set wildmenu') - command('set wildoptions=pum') - command('set shellslash') - command("cd test/functional/fixtures/wildpum") - - feed(':sign ') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - :sign ^ | - ]]) - - feed('') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }{s: define }{1: }| - {1:~ }{n: jump }{1: }| - {1:~ }{n: list }{1: }| - {1:~ }{n: place }{1: }| - {1:~ }{n: undefine }{1: }| - {1:~ }{n: unplace }{1: }| - :sign define^ | - ]]) - - feed('') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }{n: define }{1: }| - {1:~ }{n: jump }{1: }| - {1:~ }{s: list }{1: }| - {1:~ }{n: place }{1: }| - {1:~ }{n: undefine }{1: }| - {1:~ }{n: unplace }{1: }| - :sign list^ | - ]]) - - feed('') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }{n: define }{1: }| - {1:~ }{n: jump }{1: }| - {1:~ }{n: list }{1: }| - {1:~ }{s: place }{1: }| - {1:~ }{n: undefine }{1: }| - {1:~ }{n: unplace }{1: }| - :sign place^ | - ]]) - - feed('') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }{n: define }{1: }| - {1:~ }{n: jump }{1: }| - {1:~ }{s: list }{1: }| - {1:~ }{n: place }{1: }| - {1:~ }{n: undefine }{1: }| - {1:~ }{n: unplace }{1: }| - :sign list^ | - ]]) - - feed('') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }{n: define }{1: }| - {1:~ }{s: jump }{1: }| - {1:~ }{n: list }{1: }| - {1:~ }{n: place }{1: }| - {1:~ }{n: undefine }{1: }| - {1:~ }{n: unplace }{1: }| - :sign jump^ | - ]]) - - -- pressing should end completion and go back to the original match - feed('') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - :sign ^ | - ]]) - - -- pressing should select the current match and end completion - feed('') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - :sign unplace^ | - ]]) - - -- showing popup menu in different columns in the cmdline - feed('sign define ') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }{s: culhl= }{1: }| - {1:~ }{n: icon= }{1: }| - {1:~ }{n: linehl= }{1: }| - {1:~ }{n: numhl= }{1: }| - {1:~ }{n: text= }{1: }| - {1:~ }{n: texthl= }{1: }| - :sign define culhl=^ | - ]]) - - feed('') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }{s: culhl= }{1: }| - {1:~ }{n: icon= }{1: }| - {1:~ }{n: linehl= }{1: }| - {1:~ }{n: numhl= }{1: }| - {1:~ }{n: text= }{1: }| - {1:~ }{n: texthl= }{1: }| - :sign define culhl= culhl=^ | - ]]) - - feed('e Xdi') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }{s: XdirA/ }{1: }| - {1:~ }{n: XfileA }{1: }| - :e Xdir/XdirA/^ | - ]]) - - -- Pressing on a directory name should go into that directory - feed('') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }{s: XdirB/ }{1: }| - {1:~ }{n: XfileB }{1: }| - :e Xdir/XdirA/XdirB/^ | - ]]) - - -- Pressing on a directory name should go to the parent directory - feed('') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }{s: XdirA/ }{1: }| - {1:~ }{n: XfileA }{1: }| - :e Xdir/XdirA/^ | - ]]) - - -- Pressing when the popup menu is displayed should list all the - -- matches and remove the popup menu - feed(':sign ') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {4: }| - :sign define jump list place und| - efine unplace^ | - ]]) - - -- Pressing after that should move the cursor - feed('') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {4: }| - :sign define jump list place und| - efine unplac^e | - ]]) - feed('') - - -- Pressing when the popup menu is displayed should remove the popup - -- menu - feed('sign ') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {4: }| - :sign define | - define | - :sign define^ | - ]]) - - -- Pressing should open the popup menu with the last entry selected - feed(':sign ') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }{n: define }{1: }| - {1:~ }{n: jump }{1: }| - {1:~ }{n: list }{1: }| - {1:~ }{n: place }{1: }| - {1:~ }{s: undefine }{1: }| - {1:~ }{n: unplace }{1: }| - :sign undefine^ | - ]]) - - -- Pressing should close the popup menu and cancel the cmd line - feed(':sign ') - screen:expect([[ - ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - | - ]]) - - -- Typing a character when the popup is open, should close the popup - feed(':sign x') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - :sign definex^ | - ]]) - - -- When the popup is open, entering the cmdline window should close the popup - feed('sign ') - screen:expect([[ - | - {3:[No Name] }| - {1::}sign define | - {1::}sign define^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {4:[Command Line] }| - :sign define | - ]]) - feed(':q') - - -- After the last popup menu item, should show the original string - feed(':sign u') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }{n: undefine }{1: }| - {1:~ }{n: unplace }{1: }| - :sign u^ | - ]]) - - -- Use the popup menu for the command name - feed('bu') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {s: bufdo }{1: }| - {n: buffer }{1: }| - {n: buffers }{1: }| - {n: bunload }{1: }| - :bufdo^ | - ]]) - - -- Pressing should remove the popup menu and erase the last character - feed('sign ') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - :sign defin^ | - ]]) - - -- Pressing should remove the popup menu and erase the previous word - feed('sign ') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - :sign ^ | - ]]) - - -- Pressing should remove the popup menu and erase the entire line - feed('sign ') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - :^ | - ]]) - - -- Using to cancel the popup menu and then pressing should recall - -- the cmdline from history - feed('sign xyz:sign ') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - :sign xyz^ | - ]]) - - feed('') - - -- Check "list" still works - command('set wildmode=longest,list') - feed(':cn') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {4: }| - :cn | - cnewer cnoreabbrev | - cnext cnoremap | - cnfile cnoremenu | - :cn^ | - ]]) - feed('s') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {4: }| - :cn | - cnewer cnoreabbrev | - cnext cnoremap | - cnfile cnoremenu | - :cns^ | - ]]) - - feed('') - command('set wildmode=full') - - -- Tests a directory name contained full-width characters. - feed(':e あいう/') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }{s: 123 }{1: }| - {1:~ }{n: abc }{1: }| - {1:~ }{n: xyz }{1: }| - :e あいう/123^ | - ]]) - feed('') - - -- Pressing should scroll the menu downward - feed(':sign ') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }{n: define }{1: }| - {1:~ }{n: jump }{1: }| - {1:~ }{n: list }{1: }| - {1:~ }{n: place }{1: }| - {1:~ }{s: undefine }{1: }| - {1:~ }{n: unplace }{1: }| - :sign undefine^ | - ]]) - feed('') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }{n: define }{1: }| - {1:~ }{n: jump }{1: }| - {1:~ }{n: list }{1: }| - {1:~ }{n: place }{1: }| - {1:~ }{n: undefine }{1: }| - {1:~ }{s: unplace }{1: }| - :sign unplace^ | - ]]) - feed('') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }{n: define }{1: }| - {1:~ }{n: jump }{1: }| - {1:~ }{n: list }{1: }| - {1:~ }{n: place }{1: }| - {1:~ }{n: undefine }{1: }| - {1:~ }{n: unplace }{1: }| - :sign ^ | - ]]) - feed('') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }{s: define }{1: }| - {1:~ }{n: jump }{1: }| - {1:~ }{n: list }{1: }| - {1:~ }{n: place }{1: }| - {1:~ }{n: undefine }{1: }| - {1:~ }{n: unplace }{1: }| - :sign define^ | - ]]) - feed('sign ') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }{n: define }{1: }| - {1:~ }{n: jump }{1: }| - {1:~ }{n: list }{1: }| - {1:~ }{n: place }{1: }| - {1:~ }{n: undefine }{1: }| - {1:~ }{s: unplace }{1: }| - :sign unplace^ | - ]]) - - -- Pressing should scroll the menu upward - feed('sign ') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }{n: define }{1: }| - {1:~ }{n: jump }{1: }| - {1:~ }{n: list }{1: }| - {1:~ }{n: place }{1: }| - {1:~ }{n: undefine }{1: }| - {1:~ }{n: unplace }{1: }| - :sign ^ | - ]]) - feed('') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }{n: define }{1: }| - {1:~ }{n: jump }{1: }| - {1:~ }{n: list }{1: }| - {1:~ }{n: place }{1: }| - {1:~ }{n: undefine }{1: }| - {1:~ }{s: unplace }{1: }| - :sign unplace^ | - ]]) - feed('') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }{n: define }{1: }| - {1:~ }{s: jump }{1: }| - {1:~ }{n: list }{1: }| - {1:~ }{n: place }{1: }| - {1:~ }{n: undefine }{1: }| - {1:~ }{n: unplace }{1: }| - :sign jump^ | - ]]) - feed('') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }{s: define }{1: }| - {1:~ }{n: jump }{1: }| - {1:~ }{n: list }{1: }| - {1:~ }{n: place }{1: }| - {1:~ }{n: undefine }{1: }| - {1:~ }{n: unplace }{1: }| - :sign define^ | - ]]) - - feed('') - - -- check positioning with multibyte char in pattern - command("e långfile1") - command("sp långfile2") - feed(':b lå') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {4:långfile2 }| - | - {1:~ }| - {1:~ }{s: långfile1 }{1: }| - {3:lå}{n: långfile2 }{3: }| - :b långfile1^ | - ]]) - - -- check doesn't crash on screen resize - screen:try_resize(20,6) - screen:expect([[ - | - {1:~ }| - {4:långfile2 }| - {s: långfile1 } | - {3:lå}{n: långfile2 }{3: }| - :b långfile1^ | - ]]) - - screen:try_resize(50,15) - screen:expect([[ - | - {1:~ }| - {4:långfile2 }| - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }{s: långfile1 }{1: }| - {3:lå}{n: långfile2 }{3: }| - :b långfile1^ | - ]]) - - -- position is calculated correctly with "longest" - feed('') - command('set wildmode=longest:full,full') - feed(':b lå') - screen:expect([[ - | - {1:~ }| - {4:långfile2 }| - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }{n: långfile1 }{1: }| - {3:lå}{n: långfile2 }{3: }| - :b långfile^ | - ]]) - - feed('') - command("close") - command('set wildmode=full') - - -- special case: when patterns ends with "/", show menu items aligned - -- after the "/" - feed(':e compdir/') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }{s: file1 }{1: }| - {1:~ }{n: file2 }{1: }| - :e compdir/file1^ | - ]]) - end) - - it('wildoptions=pum with scrolled messages', function() - screen:try_resize(40,10) - command('set wildmenu') - command('set wildoptions=pum') - - feed(':echoerr "fail"|echoerr "error"') - screen:expect{grid=[[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {4: }| - {6:fail} | - {6:error} | - {5:Press ENTER or type command to continue}^ | - ]]} - - feed(':sign ') - screen:expect{grid=[[ - | - {1:~ }| - {1:~ }| - {1:~ }{s: define }{1: }| - {1:~ }{n: jump }{1: }| - {1:~ }{n: list }{1: }| - {4: }{n: place }{4: }| - {6:fail} {n: undefine } | - {6:error}{n: unplace } | - :sign define^ | - ]]} - - feed('d') - screen:expect{grid=[[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {4: }| - {6:fail} | - {6:error} | - :sign defined^ | - ]]} - end) - - it('wildoptions=pum and wildmode=longest,full #11622', function() - screen:try_resize(30,8) - command('set wildmenu') - command('set wildoptions=pum') - command('set wildmode=longest,full') - - -- With 'wildmode' set to 'longest,full', completing a match should display - -- the longest match, the wildmenu should not be displayed. - feed(':sign u') - screen:expect{grid=[[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - :sign un^ | - ]]} - eq(0, funcs.wildmenumode()) - - -- pressing should display the wildmenu - feed('') - screen:expect{grid=[[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }{s: undefine }{1: }| - {1:~ }{n: unplace }{1: }| - :sign undefine^ | - ]]} - eq(1, funcs.wildmenumode()) - - -- pressing second time should select the next entry in the menu - feed('') - screen:expect{grid=[[ - | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }{n: undefine }{1: }| - {1:~ }{s: unplace }{1: }| - :sign unplace^ | - ]]} - end) - - it('wildoptions=pum with a wrapped line in buffer vim-patch:8.2.4655', function() - screen:try_resize(32, 10) - meths.buf_set_lines(0, 0, -1, true, { ('a'):rep(100) }) - command('set wildoptions+=pum') - feed('$') - feed(':sign ') - screen:expect([[ - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| - aaaa {s: define } | - {1:~ }{n: jump }{1: }| - {1:~ }{n: list }{1: }| - {1:~ }{n: place }{1: }| - {1:~ }{n: undefine }{1: }| - {1:~ }{n: unplace }{1: }| - :sign define^ | - ]]) - end) - - -- oldtest: Test_wildmenu_pum_clear_entries() - it('wildoptions=pum when using Ctrl-E as wildchar vim-patch:9.0.1030', function() - screen:try_resize(30, 10) - exec([[ - set wildoptions=pum - set wildchar= - ]]) - feed(':sign ') - screen:expect([[ - | - {1:~ }| - {1:~ }| - {1:~ }{s: define }{1: }| - {1:~ }{n: jump }{1: }| - {1:~ }{n: list }{1: }| - {1:~ }{n: place }{1: }| - {1:~ }{n: undefine }{1: }| - {1:~ }{n: unplace }{1: }| - :sign define^ | - ]]) - assert_alive() - end) - - it("'pumblend' RGB-color", function() - screen:try_resize(60,14) + it('RGB-color', function() + local screen = Screen.new(60, 14) screen:set_default_attr_ids({ [1] = {background = Screen.colors.Yellow}, [2] = {bold = true, reverse = true}, @@ -2933,6 +1075,7 @@ describe('builtin popupmenu', function() [44] = {foreground = tonumber('0x3f3f3f'), background = tonumber('0x7f5d7f')}, [45] = {background = Screen.colors.WebGray, blend=0}, }) + screen:attach() command('syntax on') command('set mouse=a') command('set pumblend=10') @@ -3081,10 +1224,8 @@ describe('builtin popupmenu', function() ]]) end) - it("'pumblend' 256-color (non-RGB)", function() - screen:detach() - screen = Screen.new(60, 8) - screen:attach({rgb=false, ext_popupmenu=false}) + it('256-color (non-RGB)', function() + local screen = Screen.new(60, 8) screen:set_default_attr_ids({ [1] = {foreground = Screen.colors.Grey0, background = tonumber('0x000007')}, [2] = {foreground = tonumber('0x000055'), background = tonumber('0x000007')}, @@ -3097,6 +1238,7 @@ describe('builtin popupmenu', function() [9] = {bold = true}, [10] = {foreground = tonumber('0x000002')}, }) + screen:attach({rgb=false}) command('set notermguicolors pumblend=10') insert([[ Lorem ipsum dolor sit amet, consectetur @@ -3117,713 +1259,3326 @@ describe('builtin popupmenu', function() {9:-- Keyword Local completion (^N^P) }{10:match 1 of 3} | ]]) end) +end) - it("'pumheight'", function() - screen:try_resize(32,8) - feed('isome long prefix before the ') - command("set completeopt+=noinsert,noselect") - command("set linebreak") - command("set pumheight=2") - funcs.complete(29, {'word', 'choice', 'text', 'thing'}) - screen:expect([[ - some long prefix before the ^ | - {1:~ }{n: word }{c: }| - {1:~ }{n: choice}{s: }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]]) - end) +describe('builtin popupmenu', function() + before_each(clear) - it("'pumwidth'", function() - screen:try_resize(32,8) - feed('isome long prefix before the ') - command("set completeopt+=noinsert,noselect") - command("set linebreak") - command("set pumwidth=8") - funcs.complete(29, {'word', 'choice', 'text', 'thing'}) - screen:expect([[ - some long prefix before the ^ | - {1:~ }{n: word }| - {1:~ }{n: choice}| - {1:~ }{n: text }| - {1:~ }{n: thing }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]]) - end) + local function with_ext_multigrid(multigrid) + local screen + before_each(function() + screen = Screen.new(32, 20) + screen:set_default_attr_ids({ + -- popup selected item / scrollbar track + ['s'] = {background = Screen.colors.WebGray}, + -- popup non-selected item + ['n'] = {background = Screen.colors.LightMagenta}, + -- popup scrollbar knob + ['c'] = {background = Screen.colors.Grey0}, + [1] = {bold = true, foreground = Screen.colors.Blue}, + [2] = {bold = true}, + [3] = {reverse = true}, + [4] = {bold = true, reverse = true}, + [5] = {bold = true, foreground = Screen.colors.SeaGreen}, + [6] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, + [7] = {background = Screen.colors.Yellow}, -- Search + [8] = {foreground = Screen.colors.Red}, + }) + screen:attach({ext_multigrid=multigrid}) + end) - it('does not crash when displayed in the last column with rightleft (#12032)', function() - local col = 30 - local items = {'word', 'choice', 'text', 'thing'} - local max_len = 0 - for _, v in ipairs(items) do - max_len = max_len < #v and #v or max_len - end - screen:try_resize(col, 8) - command('set rightleft') - command('call setline(1, repeat(" ", &columns - '..max_len..'))') - feed('$i') - funcs.complete(col - max_len, items) - feed('') - assert_alive() - end) + it('with preview-window above', function() + feed(':ped4+') + feed('iaa bb cc dd ee ff gg hh ii jj') + feed('') + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + {3:[No Name] [Preview][+] }| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + {4:[No Name] [+] }| + [3:--------------------------------]| + ## grid 2 + aa bb cc dd ee ff gg hh ii jj | + aa^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + {2:-- }{5:match 1 of 10} | + ## grid 4 + aa bb cc dd ee ff gg hh ii jj | + aa | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 5 + {s:aa }{c: }| + {n:bb }{c: }| + {n:cc }{c: }| + {n:dd }{c: }| + {n:ee }{c: }| + {n:ff }{c: }| + {n:gg }{s: }| + {n:hh }{s: }| + ]], float_pos={ + [5] = {{id = -1}, "NW", 2, 2, 0, false, 100}; + }} + else + screen:expect([[ + aa bb cc dd ee ff gg hh ii jj | + aa | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {3:[No Name] [Preview][+] }| + aa bb cc dd ee ff gg hh ii jj | + aa^ | + {s:aa }{c: }{1: }| + {n:bb }{c: }{1: }| + {n:cc }{c: }{1: }| + {n:dd }{c: }{1: }| + {n:ee }{c: }{1: }| + {n:ff }{c: }{1: }| + {n:gg }{s: }{1: }| + {n:hh }{s: }{4: }| + {2:-- }{5:match 1 of 10} | + ]]) + end + end) - it('truncates double-width character correctly when there is no scrollbar', function() - screen:try_resize(32,8) - command('set completeopt+=menuone,noselect') - feed('i' .. string.rep(' ', 13)) - funcs.complete(14, {'哦哦哦哦哦哦哦哦哦哦'}) - screen:expect([[ - ^ | - {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]]) - end) + it('with preview-window below', function() + feed(':ped4+r') + feed('iaa bb cc dd ee ff gg hh ii jj') + feed('') + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + {4:[No Name] [+] }| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + {3:[No Name] [Preview][+] }| + [3:--------------------------------]| + ## grid 2 + aa bb cc dd ee ff gg hh ii jj | + aa^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + {2:-- }{5:match 1 of 10} | + ## grid 4 + aa bb cc dd ee ff gg hh ii jj | + aa | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 5 + {s:aa }{c: }| + {n:bb }{c: }| + {n:cc }{c: }| + {n:dd }{c: }| + {n:ee }{c: }| + {n:ff }{c: }| + {n:gg }{s: }| + {n:hh }{s: }| + ]], float_pos={ + [5] = {{id = -1}, "NW", 2, 2, 0, false, 100}; + }} + else + screen:expect([[ + aa bb cc dd ee ff gg hh ii jj | + aa^ | + {s:aa }{c: }{1: }| + {n:bb }{c: }{1: }| + {n:cc }{c: }{1: }| + {n:dd }{c: }{1: }| + {n:ee }{c: }{1: }| + {n:ff }{c: }{1: }| + {n:gg }{s: }{1: }| + {n:hh }{s: }{4: }| + aa bb cc dd ee ff gg hh ii jj | + aa | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {3:[No Name] [Preview][+] }| + {2:-- }{5:match 1 of 10} | + ]]) + end + end) - it('truncates double-width character correctly when there is scrollbar', function() - screen:try_resize(32,8) - command('set completeopt+=noselect') - command('set pumheight=4') - feed('i' .. string.rep(' ', 12)) - local items = {} - for _ = 1, 8 do - table.insert(items, {word = '哦哦哦哦哦哦哦哦哦哦', equal = 1, dup = 1}) - end - funcs.complete(13, items) - screen:expect([[ - ^ | - {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{c: }| - {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{c: }| - {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{s: }| - {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{s: }| - {1:~ }| - {1:~ }| - {2:-- INSERT --} | - ]]) - end) + it('with preview-window above and tall and inverted', function() + feed(':ped8+') + feed('iaabbccddee') + feed('ffgghhiijj') + feed('kkllmmnnoo') + feed('') + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + {3:[No Name] [Preview][+] }| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + {4:[No Name] [+] }| + [3:--------------------------------]| + ## grid 2 + dd | + ee | + ff | + gg | + hh | + ii | + jj | + kk | + ll | + mm | + nn | + oo | + aa^ | + ## grid 3 + {2:-- }{5:match 1 of 15} | + ## grid 4 + aa | + bb | + cc | + dd | + ## grid 5 + {s:aa }{c: }| + {n:bb }{c: }| + {n:cc }{c: }| + {n:dd }{c: }| + {n:ee }{c: }| + {n:ff }{c: }| + {n:gg }{c: }| + {n:hh }{c: }| + {n:ii }{c: }| + {n:jj }{c: }| + {n:kk }{c: }| + {n:ll }{s: }| + {n:mm }{s: }| + ]], float_pos={ + [5] = {{id = -1}, "SW", 2, 12, 0, false, 100}; + }} + else + screen:expect([[ + aa | + bb | + cc | + dd | + {s:aa }{c: }{3:ew][+] }| + {n:bb }{c: } | + {n:cc }{c: } | + {n:dd }{c: } | + {n:ee }{c: } | + {n:ff }{c: } | + {n:gg }{c: } | + {n:hh }{c: } | + {n:ii }{c: } | + {n:jj }{c: } | + {n:kk }{c: } | + {n:ll }{s: } | + {n:mm }{s: } | + aa^ | + {4:[No Name] [+] }| + {2:-- }{5:match 1 of 15} | + ]]) + end + end) - it('supports mousemodel=popup', function() - screen:try_resize(32, 6) - exec([[ - call setline(1, 'popup menu test') - set mouse=a mousemodel=popup + it('with preview-window above and short and inverted', function() + feed(':ped4+') + feed('iaabbccddee') + feed('ffgghhiijj') + feed('') + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + {3:[No Name] [Preview][+] }| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + {4:[No Name] [+] }| + [3:--------------------------------]| + ## grid 2 + cc | + dd | + ee | + ff | + gg | + hh | + ii | + jj | + aa^ | + ## grid 3 + {2:-- }{5:match 1 of 10} | + ## grid 4 + aa | + bb | + cc | + dd | + ee | + ff | + gg | + hh | + ## grid 5 + {s:aa }{c: }| + {n:bb }{c: }| + {n:cc }{c: }| + {n:dd }{c: }| + {n:ee }{c: }| + {n:ff }{c: }| + {n:gg }{c: }| + {n:hh }{c: }| + {n:ii }{s: }| + ]], float_pos={ + [5] = {{id = -1}, "SW", 2, 8, 0, false, 100}; + }} + else + screen:expect([[ + aa | + bb | + cc | + dd | + ee | + ff | + gg | + hh | + {s:aa }{c: }{3:ew][+] }| + {n:bb }{c: } | + {n:cc }{c: } | + {n:dd }{c: } | + {n:ee }{c: } | + {n:ff }{c: } | + {n:gg }{c: } | + {n:hh }{c: } | + {n:ii }{s: } | + aa^ | + {4:[No Name] [+] }| + {2:-- }{5:match 1 of 10} | + ]]) + end + end) - aunmenu PopUp - menu PopUp.foo :let g:menustr = 'foo' - menu PopUp.bar :let g:menustr = 'bar' - menu PopUp.baz :let g:menustr = 'baz' - ]]) - feed('<4,0>') - screen:expect([[ - ^popup menu test | - {1:~ }{n: foo }{1: }| - {1:~ }{n: bar }{1: }| - {1:~ }{n: baz }{1: }| - {1:~ }| - | - ]]) - feed('') - screen:expect([[ - ^popup menu test | - {1:~ }{s: foo }{1: }| - {1:~ }{n: bar }{1: }| - {1:~ }{n: baz }{1: }| - {1:~ }| - | - ]]) - feed('') - screen:expect([[ - ^popup menu test | - {1:~ }{n: foo }{1: }| - {1:~ }{s: bar }{1: }| - {1:~ }{n: baz }{1: }| - {1:~ }| - | - ]]) - feed('') - screen:expect([[ - ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - :let g:menustr = 'bar' | - ]]) - eq('bar', meths.get_var('menustr')) - feed('<20,2>') - screen:expect([[ - ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }{n: foo }{1: }| - {1:~ }{n: bar }{1: }| - :let g:menustr = 'b{n: baz } | - ]]) - feed('<22,5>') - screen:expect([[ - ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - :let g:menustr = 'baz' | - ]]) - eq('baz', meths.get_var('menustr')) - feed('<4,0>') - screen:expect([[ - ^popup menu test | - {1:~ }{n: foo }{1: }| - {1:~ }{n: bar }{1: }| - {1:~ }{n: baz }{1: }| - {1:~ }| - :let g:menustr = 'baz' | - ]]) - feed('<6,3>') - screen:expect([[ - ^popup menu test | - {1:~ }{n: foo }{1: }| - {1:~ }{n: bar }{1: }| - {1:~ }{s: baz }{1: }| - {1:~ }| - :let g:menustr = 'baz' | - ]]) - feed('<6,1>') - screen:expect([[ - ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - :let g:menustr = 'foo' | - ]]) - eq('foo', meths.get_var('menustr')) - eq(false, screen.options.mousemoveevent) - feed('<4,0>') - screen:expect([[ - ^popup menu test | - {1:~ }{n: foo }{1: }| - {1:~ }{n: bar }{1: }| - {1:~ }{n: baz }{1: }| - {1:~ }| - :let g:menustr = 'foo' | - ]]) - eq(true, screen.options.mousemoveevent) - feed('<6,3>') - screen:expect([[ - ^popup menu test | - {1:~ }{n: foo }{1: }| - {1:~ }{n: bar }{1: }| - {1:~ }{s: baz }{1: }| - {1:~ }| - :let g:menustr = 'foo' | - ]]) - eq(true, screen.options.mousemoveevent) - feed('<6,2>') - screen:expect([[ - ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - :let g:menustr = 'bar' | - ]]) - eq(false, screen.options.mousemoveevent) - eq('bar', meths.get_var('menustr')) - end) + it('with preview-window below and inverted', function() + feed(':ped4+r') + feed('iaabbccddee') + feed('ffgghhiijj') + feed('') + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + {4:[No Name] [+] }| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + [4:--------------------------------]| + {3:[No Name] [Preview][+] }| + [3:--------------------------------]| + ## grid 2 + cc | + dd | + ee | + ff | + gg | + hh | + ii | + jj | + aa^ | + ## grid 3 + {2:-- }{5:match 1 of 10} | + ## grid 4 + aa | + bb | + cc | + dd | + ee | + ff | + gg | + hh | + ## grid 5 + {s:aa }{c: }| + {n:bb }{c: }| + {n:cc }{c: }| + {n:dd }{c: }| + {n:ee }{c: }| + {n:ff }{c: }| + {n:gg }{s: }| + {n:hh }{s: }| + ]], float_pos={ + [5] = {{id = -1}, "SW", 2, 8, 0, false, 100}; + }} + else + screen:expect([[ + {s:aa }{c: } | + {n:bb }{c: } | + {n:cc }{c: } | + {n:dd }{c: } | + {n:ee }{c: } | + {n:ff }{c: } | + {n:gg }{s: } | + {n:hh }{s: } | + aa^ | + {4:[No Name] [+] }| + aa | + bb | + cc | + dd | + ee | + ff | + gg | + hh | + {3:[No Name] [Preview][+] }| + {2:-- }{5:match 1 of 10} | + ]]) + end + end) - -- oldtest: Test_popup_command_dump() - it(':popup command', function() - exec([[ - func ChangeMenu() - aunmenu PopUp.&Paste - nnoremenu 1.40 PopUp.&Paste :echomsg "pasted" - echomsg 'changed' - return "\" - endfunc - - let lines =<< trim END - one two three four five - and one two Xthree four five - one more two three four five - END - call setline(1, lines) - - aunmenu * - source $VIMRUNTIME/menu.vim - ]]) - feed('/X:popup PopUp') - screen:expect([[ - one two three four five | - and one two {7:^X}three four five | - one more tw{n: Undo } | - {1:~ }{n: }{1: }| - {1:~ }{n: Paste }{1: }| - {1:~ }{n: }{1: }| - {1:~ }{n: Select Word }{1: }| - {1:~ }{n: Select Sentence }{1: }| - {1:~ }{n: Select Paragraph }{1: }| - {1:~ }{n: Select Line }{1: }| - {1:~ }{n: Select Block }{1: }| - {1:~ }{n: Select All }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - :popup PopUp | - ]]) + if not multigrid then + -- oldtest: Test_pum_with_preview_win() + it('preview window opened during completion', function() + exec([[ + funct Omni_test(findstart, base) + if a:findstart + return col(".") - 1 + endif + return [#{word: "one", info: "1info"}, #{word: "two", info: "2info"}, #{word: "three", info: "3info"}] + endfunc + set omnifunc=Omni_test + set completeopt+=longest + ]]) + feed('Gi') + screen:expect([[ + ^ | + {n:one }{1: }| + {n:two }{1: }| + {n:three }{1: }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- }{8:Back at original} | + ]]) + feed('') + screen:expect([[ + 1info | + | + {1:~ }| + {3:[Scratch] [Preview] }| + one^ | + {s:one }{1: }| + {n:two }{1: }| + {n:three }{1: }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {4:[No Name] [+] }| + {2:-- }{5:match 1 of 3} | + ]]) + end) + end - -- go to the Paste entry in the menu - feed('jj') - screen:expect([[ - one two three four five | - and one two {7:^X}three four five | - one more tw{n: Undo } | - {1:~ }{n: }{1: }| - {1:~ }{s: Paste }{1: }| - {1:~ }{n: }{1: }| - {1:~ }{n: Select Word }{1: }| - {1:~ }{n: Select Sentence }{1: }| - {1:~ }{n: Select Paragraph }{1: }| - {1:~ }{n: Select Line }{1: }| - {1:~ }{n: Select Block }{1: }| - {1:~ }{n: Select All }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - :popup PopUp | - ]]) + it('with vsplits', function() + screen:try_resize(32, 8) + insert('aaa aab aac\n') + feed(':vsplit') + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [4:--------------------]│[2:-----------]| + [4:--------------------]│[2:-----------]| + [4:--------------------]│[2:-----------]| + [4:--------------------]│[2:-----------]| + [4:--------------------]│[2:-----------]| + [4:--------------------]│[2:-----------]| + {4:[No Name] [+] }{3:') + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [4:--------------------]│[2:-----------]| + [4:--------------------]│[2:-----------]| + [4:--------------------]│[2:-----------]| + [4:--------------------]│[2:-----------]| + [4:--------------------]│[2:-----------]| + [4:--------------------]│[2:-----------]| + {4:[No Name] [+] }{3:oc a') + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [4:-----------]│[2:--------------------]| + [4:-----------]│[2:--------------------]| + [4:-----------]│[2:--------------------]| + [4:-----------]│[2:--------------------]| + [4:-----------]│[2:--------------------]| + [4:-----------]│[2:--------------------]| + {3:') + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [4:-----------]│[2:--------------------]| + [4:-----------]│[2:--------------------]| + [4:-----------]│[2:--------------------]| + [4:-----------]│[2:--------------------]| + [4:-----------]│[2:--------------------]| + [4:-----------]│[2:--------------------]| + {3:') + screen:expect([[ + Est ^ | + L{n: sunt }{s: }sit amet, consectetur | + a{n: in }{s: }sed do eiusmod tempor | + i{n: culpa }{s: }re et dolore magna aliqua. | + U{n: qui }{s: }eniam, quis nostrud | + e{n: officia }{s: }co laboris nisi ut aliquip ex | + {4:[No}{n: deserunt }{s: }{4: }| + Est{n: mollit }{s: } | + L{n: anim }{s: }sit amet, consectetur | + a{n: id }{s: }sed do eiusmod tempor | + i{n: est }{s: }re et dolore magna aliqua. | + U{n: laborum }{c: }eniam, quis nostrud | + {3:[No}{s: Est }{c: }{3: }| + {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | + ]]) + + meths.input_mouse('wheel', 'down', '', 0, 9, 40) + screen:expect([[ + Est ^ | + L{n: sunt }{s: }sit amet, consectetur | + a{n: in }{s: }sed do eiusmod tempor | + i{n: culpa }{s: }re et dolore magna aliqua. | + U{n: qui }{s: }eniam, quis nostrud | + e{n: officia }{s: }co laboris nisi ut aliquip ex | + {4:[No}{n: deserunt }{s: }{4: }| + i{n: mollit }{s: }re et dolore magna aliqua. | + U{n: anim }{s: }eniam, quis nostrud | + e{n: id }{s: }co laboris nisi ut aliquip ex | + e{n: est }{s: }at. Duis aute irure dolor in | + r{n: laborum }{c: }oluptate velit esse cillum | + {3:[No}{s: Est }{c: }{3: }| + {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | + ]]) + + feed('e') + screen:expect([[ + Est e^ | + L{n: elit } sit amet, consectetur | + a{n: eiusmod } sed do eiusmod tempor | + i{n: et }ore et dolore magna aliqua. | + U{n: enim }veniam, quis nostrud | + e{n: exercitation }mco laboris nisi ut aliquip ex | + {4:[No}{n: ex }{4: }| + i{n: ea }ore et dolore magna aliqua. | + U{n: esse }veniam, quis nostrud | + e{n: eu }mco laboris nisi ut aliquip ex | + e{s: est }uat. Duis aute irure dolor in | + reprehenderit in voluptate velit esse cillum | + {3:[No Name] [+] }| + {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | + ]]) + + meths.input_mouse('wheel', 'up', '', 0, 9, 40) + screen:expect([[ + Est e^ | + L{n: elit } sit amet, consectetur | + a{n: eiusmod } sed do eiusmod tempor | + i{n: et }ore et dolore magna aliqua. | + U{n: enim }veniam, quis nostrud | + e{n: exercitation }mco laboris nisi ut aliquip ex | + {4:[No}{n: ex }{4: }| + Est{n: ea } | + L{n: esse } sit amet, consectetur | + a{n: eu } sed do eiusmod tempor | + i{s: est }ore et dolore magna aliqua. | + Ut enim ad minim veniam, quis nostrud | + {3:[No Name] [+] }| + {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | + ]]) + + feed('s') + screen:expect([[ + Est es^ | + L{n: esse } sit amet, consectetur | + a{s: est } sed do eiusmod tempor | + incididunt ut labore et dolore magna aliqua. | + Ut enim ad minim veniam, quis nostrud | + exercitation ullamco laboris nisi ut aliquip ex | + {4:[No Name] [+] }| + Est es | + Lorem ipsum dolor sit amet, consectetur | + adipisicing elit, sed do eiusmod tempor | + incididunt ut labore et dolore magna aliqua. | + Ut enim ad minim veniam, quis nostrud | + {3:[No Name] [+] }| + {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | + ]]) + + meths.input_mouse('wheel', 'down', '', 0, 9, 40) + screen:expect([[ + Est es^ | + L{n: esse } sit amet, consectetur | + a{s: est } sed do eiusmod tempor | + incididunt ut labore et dolore magna aliqua. | + Ut enim ad minim veniam, quis nostrud | + exercitation ullamco laboris nisi ut aliquip ex | + {4:[No Name] [+] }| + incididunt ut labore et dolore magna aliqua. | + Ut enim ad minim veniam, quis nostrud | + exercitation ullamco laboris nisi ut aliquip ex | + ea commodo consequat. Duis aute irure dolor in | + reprehenderit in voluptate velit esse cillum | + {3:[No Name] [+] }| + {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | + ]]) + + feed('') + screen:expect([[ + Est e^ | + L{n: elit } sit amet, consectetur | + a{n: eiusmod } sed do eiusmod tempor | + i{n: et }ore et dolore magna aliqua. | + U{n: enim }veniam, quis nostrud | + e{n: exercitation }mco laboris nisi ut aliquip ex | + {4:[No}{n: ex }{4: }| + i{n: ea }ore et dolore magna aliqua. | + U{n: esse }veniam, quis nostrud | + e{n: eu }mco laboris nisi ut aliquip ex | + e{s: est }uat. Duis aute irure dolor in | + reprehenderit in voluptate velit esse cillum | + {3:[No Name] [+] }| + {2:-- Keyword Local completion (^N^P) }{5:match 1 of 65} | + ]]) + + feed('') + screen:expect([[ + Est eu^ | + L{n: elit } sit amet, consectetur | + a{n: eiusmod } sed do eiusmod tempor | + i{n: et }ore et dolore magna aliqua. | + U{n: enim }veniam, quis nostrud | + e{n: exercitation }mco laboris nisi ut aliquip ex | + {4:[No}{n: ex }{4: }| + i{n: ea }ore et dolore magna aliqua. | + U{n: esse }veniam, quis nostrud | + e{s: eu }mco laboris nisi ut aliquip ex | + e{n: est }uat. Duis aute irure dolor in | + reprehenderit in voluptate velit esse cillum | + {3:[No Name] [+] }| + {2:-- Keyword Local completion (^N^P) }{5:match 22 of 65} | + ]]) + + meths.input_mouse('wheel', 'down', '', 0, 9, 40) + screen:expect([[ + Est eu^ | + L{n: elit } sit amet, consectetur | + a{n: eiusmod } sed do eiusmod tempor | + i{n: et }ore et dolore magna aliqua. | + U{n: enim }veniam, quis nostrud | + e{n: exercitation }mco laboris nisi ut aliquip ex | + {4:[No}{n: ex }{4: }| + e{n: ea }uat. Duis aute irure dolor in | + r{n: esse }voluptate velit esse cillum | + d{s: eu }nulla pariatur. Excepteur sint | + o{n: est }t non proident, sunt in culpa | + qui officia deserunt mollit anim id est | + {3:[No Name] [+] }| + {2:-- Keyword Local completion (^N^P) }{5:match 22 of 65} | + ]]) + + funcs.complete(4, {'ea', 'eeeeeeeeeeeeeeeeee', 'ei', 'eo', 'eu', 'ey', 'eå', 'eä', 'eö'}) + screen:expect([[ + Est eu^ | + {s: ea }t amet, consectetur | + {n: eeeeeeeeeeeeeeeeee }d do eiusmod tempor | + {n: ei } et dolore magna aliqua. | + {n: eo }iam, quis nostrud | + {n: eu } laboris nisi ut aliquip ex | + {4:[N}{n: ey }{4: }| + {n: eå }. Duis aute irure dolor in | + {n: eä }uptate velit esse cillum | + {n: eö }la pariatur. Excepteur sint | + occaecat cupidatat non proident, sunt in culpa | + qui officia deserunt mollit anim id est | + {3:[No Name] [+] }| + {2:-- Keyword Local completion (^N^P) }{5:match 1 of 9} | + ]]) + + funcs.complete(4, {'ea', 'eee', 'ei', 'eo', 'eu', 'ey', 'eå', 'eä', 'eö'}) + screen:expect([[ + Est eu^ | + {s: ea }r sit amet, consectetur | + {n: eee }, sed do eiusmod tempor | + {n: ei }bore et dolore magna aliqua. | + {n: eo } veniam, quis nostrud | + {n: eu }amco laboris nisi ut aliquip ex | + {4:[N}{n: ey }{4: }| + {n: eå }quat. Duis aute irure dolor in | + {n: eä } voluptate velit esse cillum | + {n: eö } nulla pariatur. Excepteur sint | + occaecat cupidatat non proident, sunt in culpa | + qui officia deserunt mollit anim id est | + {3:[No Name] [+] }| + {2:-- INSERT --} | + ]]) + + feed('') + screen:expect([[ + Esteee^ | + {n: ea }r sit amet, consectetur | + {s: eee }, sed do eiusmod tempor | + {n: ei }bore et dolore magna aliqua. | + {n: eo } veniam, quis nostrud | + {n: eu }amco laboris nisi ut aliquip ex | + {4:[N}{n: ey }{4: }| + {n: eå }quat. Duis aute irure dolor in | + {n: eä } voluptate velit esse cillum | + {n: eö } nulla pariatur. Excepteur sint | + occaecat cupidatat non proident, sunt in culpa | + qui officia deserunt mollit anim id est | + {3:[No Name] [+] }| + {2:-- INSERT --} | + ]]) + + funcs.complete(6, {'foo', 'bar'}) + screen:expect([[ + Esteee^ | + Lo{s: foo }sit amet, consectetur | + ad{n: bar }sed do eiusmod tempor | + incididunt ut labore et dolore magna aliqua. | + Ut enim ad minim veniam, quis nostrud | + exercitation ullamco laboris nisi ut aliquip ex | + {4:[No Name] [+] }| + ea commodo consequat. Duis aute irure dolor in | + reprehenderit in voluptate velit esse cillum | + dolore eu fugiat nulla pariatur. Excepteur sint | + occaecat cupidatat non proident, sunt in culpa | + qui officia deserunt mollit anim id est | + {3:[No Name] [+] }| + {2:-- INSERT --} | + ]]) + + feed('') + screen:expect([[ + Esteefoo^ | + Lorem ipsum dolor sit amet, consectetur | + adipisicing elit, sed do eiusmod tempor | + incididunt ut labore et dolore magna aliqua. | + Ut enim ad minim veniam, quis nostrud | + exercitation ullamco laboris nisi ut aliquip ex | + {4:[No Name] [+] }| + ea commodo consequat. Duis aute irure dolor in | + reprehenderit in voluptate velit esse cillum | + dolore eu fugiat nulla pariatur. Excepteur sint | + occaecat cupidatat non proident, sunt in culpa | + qui officia deserunt mollit anim id est | + {3:[No Name] [+] }| + {2:-- INSERT --} | + ]]) + end) + + it('can be moved due to wrap or resize', function() + feed('isome long prefix before the ') + command("set completeopt+=noinsert,noselect") + command("set linebreak") + funcs.complete(29, {'word', 'choice', 'text', 'thing'}) + screen:expect([[ + some long prefix before the ^ | + {1:~ }{n: word }| + {1:~ }{n: choice}| + {1:~ }{n: text }| + {1:~ }{n: thing }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + feed('') + screen:expect([[ + some long prefix before the | + thing^ | + {n:word }{1: }| + {n:choice }{1: }| + {n:text }{1: }| + {s:thing }{1: }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + feed('') + screen:expect([[ + some long prefix before the text| + {1:^~ }{n: word }| + {1:~ }{n: choice}| + {1:~ }{s: text }| + {1:~ }{n: thing }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + screen:try_resize(30,8) + screen:expect([[ + some long prefix before the | + text^ | + {n:word }{1: }| + {n:choice }{1: }| + {s:text }{1: }| + {n:thing }{1: }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + screen:try_resize(50,8) + screen:expect([[ + some long prefix before the text^ | + {1:~ }{n: word }{1: }| + {1:~ }{n: choice }{1: }| + {1:~ }{s: text }{1: }| + {1:~ }{n: thing }{1: }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + screen:try_resize(25,10) + screen:expect([[ + some long prefix before | + the text^ | + {1:~ }{n: word }{1: }| + {1:~ }{n: choice }{1: }| + {1:~ }{s: text }{1: }| + {1:~ }{n: thing }{1: }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + screen:try_resize(12,5) + screen:expect([[ + some long | + prefix | + bef{n: word } | + tex{n: }^ | + {2:-- INSERT -} | + ]]) + + -- can't draw the pum, but check we don't crash + screen:try_resize(12,2) + screen:expect([[ + text^ | + {2:-- INSERT -} | + ]]) + + -- but state is preserved, pum reappears + screen:try_resize(20,8) + screen:expect([[ + some long prefix | + before the text^ | + {1:~ }{n: word }{1: }| + {1:~ }{n: choice }{1: }| + {1:~ }{s: text }{1: }| + {1:~ }{n: thing }{1: }| + {1:~ }| + {2:-- INSERT --} | + ]]) + end) + + it('with VimResized autocmd', function() + feed('isome long prefix before the ') + command("set completeopt+=noinsert,noselect") + command("autocmd VimResized * redraw!") + command("set linebreak") + funcs.complete(29, {'word', 'choice', 'text', 'thing'}) + screen:expect([[ + some long prefix before the ^ | + {1:~ }{n: word }| + {1:~ }{n: choice}| + {1:~ }{n: text }| + {1:~ }{n: thing }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + screen:try_resize(16,10) + screen:expect([[ + some long | + prefix before | + the ^ | + {1:~ }{n: word }| + {1:~ }{n: choice }| + {1:~ }{n: text }| + {1:~ }{n: thing }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + end) + + it('with rightleft window', function() + command("set rl wildoptions+=pum") + feed('isome rightleft ') + screen:expect([[ + ^ tfelthgir emos| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {2:-- INSERT --} | + ]]) + + command("set completeopt+=noinsert,noselect") + funcs.complete(16, {'word', 'choice', 'text', 'thing'}) + screen:expect([[ + ^ tfelthgir emos| + {1: }{n: drow}{1: ~}| + {1: }{n: eciohc}{1: ~}| + {1: }{n: txet}{1: ~}| + {1: }{n: gniht}{1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {2:-- INSERT --} | + ]]) + + feed('') + screen:expect([[ + ^ drow tfelthgir emos| + {1: }{s: drow}{1: ~}| + {1: }{n: eciohc}{1: ~}| + {1: }{n: txet}{1: ~}| + {1: }{n: gniht}{1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {2:-- INSERT --} | + ]]) + + feed('') + screen:expect([[ + ^ drow tfelthgir emos| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {2:-- INSERT --} | + ]]) + + -- not rightleft on the cmdline + feed(':sign ') + screen:expect{grid=[[ + drow tfelthgir emos| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + :sign ^ | + ]]} + + feed('') + screen:expect{grid=[[ + drow tfelthgir emos| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: }{s: define }{1: ~}| + {1: }{n: jump }{1: ~}| + {1: }{n: list }{1: ~}| + {1: }{n: place }{1: ~}| + {1: }{n: undefine }{1: ~}| + {1: }{n: unplace }{1: ~}| + :sign define^ | + ]]} + end) + end - feed('') + it('with rightleft vsplits', function() + screen:try_resize(40, 8) + command('set rightleft') + command('rightbelow vsplit') + command("set completeopt+=noinsert,noselect") + feed('isome rightleft ') + funcs.complete(16, {'word', 'choice', 'text', 'thing'}) + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + {3:[No Name] [+] }{4:[No Name] [+] }| + [3:----------------------------------------]| + ## grid 2 + tfelthgir emos| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + ## grid 3 + {2:-- INSERT --} | + ## grid 4 + ^ tfelthgir emos| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + ## grid 5 + {n: drow}| + {n: eciohc}| + {n: txet}| + {n: gniht}| + ]], float_pos={ + [5] = {{id = -1}, "NW", 4, 1, -11, false, 100}; + }} + else + screen:expect([[ + tfelthgir emos│ ^ tfelthgir emos| + {1: }{n: drow}{1: ~}| + {1: }{n: eciohc}{1: ~}| + {1: }{n: txet}{1: ~}| + {1: }{n: gniht}{1: ~}| + {1: ~}│{1: ~}| + {3:[No Name] [+] }{4:[No Name] [+] }| + {2:-- INSERT --} | + ]]) + end + end) - -- Set an mapping to change a menu entry while it's displayed. - -- The text should not change but the command does. - -- Also verify that "changed" shows up, which means the mapping triggered. - command('nnoremap ChangeMenu()') - feed('/X:popup PopUp') - screen:expect([[ - one two three four five | - and one two {7:^X}three four five | - one more tw{n: Undo } | - {1:~ }{n: }{1: }| - {1:~ }{n: Paste }{1: }| - {1:~ }{n: }{1: }| - {1:~ }{n: Select Word }{1: }| - {1:~ }{n: Select Sentence }{1: }| - {1:~ }{n: Select Paragraph }{1: }| - {1:~ }{n: Select Line }{1: }| - {1:~ }{n: Select Block }{1: }| - {1:~ }{n: Select All }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - changed | - ]]) + if not multigrid then + it('with multiline messages', function() + screen:try_resize(40,8) + feed('ixx') + command('imap echoerr "very"\\|echoerr "much"\\|echoerr "error"') + funcs.complete(1, {'word', 'choice', 'text', 'thing'}) + screen:expect([[ + xx | + word^ | + {s:word }{1: }| + {n:choice }{1: }| + {n:text }{1: }| + {n:thing }{1: }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + feed('') + screen:expect([[ + xx | + word | + {s:word }{1: }| + {4: }| + {6:very} | + {6:much} | + {6:error} | + {5:Press ENTER or type command to continue}^ | + ]]) + + feed('') + screen:expect([[ + xx | + word^ | + {s:word }{1: }| + {n:choice }{1: }| + {n:text }{1: }| + {n:thing }{1: }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + feed('') + screen:expect([[ + xx | + choice^ | + {n:word }{1: }| + {s:choice }{1: }| + {n:text }{1: }| + {n:thing }{1: }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + command("split") + screen:expect([[ + xx | + choice^ | + {n:word }{1: }| + {s:choice }{4: }| + {n:text } | + {n:thing } | + {3:[No Name] [+] }| + {2:-- INSERT --} | + ]]) + + meths.input_mouse('wheel', 'down', '', 0, 6, 15) + screen:expect{grid=[[ + xx | + choice^ | + {n:word }{1: }| + {s:choice }{4: }| + {n:text } | + {n:thing }{1: }| + {3:[No Name] [+] }| + {2:-- INSERT --} | + ]], unchanged=true} + end) + + it('with kind, menu and abbr attributes', function() + screen:try_resize(40,8) + feed('ixx ') + funcs.complete(4, {{word='wordey', kind= 'x', menu='extrainfo'}, 'thing', {word='secret', abbr='sneaky', menu='bar'}}) + screen:expect([[ + xx wordey^ | + {1:~ }{s: wordey x extrainfo }{1: }| + {1:~ }{n: thing }{1: }| + {1:~ }{n: sneaky bar }{1: }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + feed('') + screen:expect([[ + xx ^ | + {1:~ }{n: wordey x extrainfo }{1: }| + {1:~ }{n: thing }{1: }| + {1:~ }{n: sneaky bar }{1: }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + feed('') + screen:expect([[ + xx secret^ | + {1:~ }{n: wordey x extrainfo }{1: }| + {1:~ }{n: thing }{1: }| + {1:~ }{s: sneaky bar }{1: }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + + feed('') + screen:expect([[ + xx secre^t | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]) + end) + + it('wildoptions=pum', function() + screen:try_resize(32,10) + command('set wildmenu') + command('set wildoptions=pum') + command('set shellslash') + command("cd test/functional/fixtures/wildpum") + + feed(':sign ') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :sign ^ | + ]]) + + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{s: define }{1: }| + {1:~ }{n: jump }{1: }| + {1:~ }{n: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{n: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign define^ | + ]]) + + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{n: define }{1: }| + {1:~ }{n: jump }{1: }| + {1:~ }{s: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{n: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign list^ | + ]]) + + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{n: define }{1: }| + {1:~ }{n: jump }{1: }| + {1:~ }{n: list }{1: }| + {1:~ }{s: place }{1: }| + {1:~ }{n: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign place^ | + ]]) + + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{n: define }{1: }| + {1:~ }{n: jump }{1: }| + {1:~ }{s: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{n: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign list^ | + ]]) + + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{n: define }{1: }| + {1:~ }{s: jump }{1: }| + {1:~ }{n: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{n: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign jump^ | + ]]) + + -- pressing should end completion and go back to the original match + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :sign ^ | + ]]) + + -- pressing should select the current match and end completion + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :sign unplace^ | + ]]) + + -- showing popup menu in different columns in the cmdline + feed('sign define ') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{s: culhl= }{1: }| + {1:~ }{n: icon= }{1: }| + {1:~ }{n: linehl= }{1: }| + {1:~ }{n: numhl= }{1: }| + {1:~ }{n: text= }{1: }| + {1:~ }{n: texthl= }{1: }| + :sign define culhl=^ | + ]]) + + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{s: culhl= }{1: }| + {1:~ }{n: icon= }{1: }| + {1:~ }{n: linehl= }{1: }| + {1:~ }{n: numhl= }{1: }| + {1:~ }{n: text= }{1: }| + {1:~ }{n: texthl= }{1: }| + :sign define culhl= culhl=^ | + ]]) + + feed('e Xdi') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }{s: XdirA/ }{1: }| + {1:~ }{n: XfileA }{1: }| + :e Xdir/XdirA/^ | + ]]) + + -- Pressing on a directory name should go into that directory + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }{s: XdirB/ }{1: }| + {1:~ }{n: XfileB }{1: }| + :e Xdir/XdirA/XdirB/^ | + ]]) + + -- Pressing on a directory name should go to the parent directory + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }{s: XdirA/ }{1: }| + {1:~ }{n: XfileA }{1: }| + :e Xdir/XdirA/^ | + ]]) + + -- Pressing when the popup menu is displayed should list all the + -- matches and remove the popup menu + feed(':sign ') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {4: }| + :sign define jump list place und| + efine unplace^ | + ]]) + + -- Pressing after that should move the cursor + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {4: }| + :sign define jump list place und| + efine unplac^e | + ]]) + feed('') + + -- Pressing when the popup menu is displayed should remove the popup + -- menu + feed('sign ') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {4: }| + :sign define | + define | + :sign define^ | + ]]) + + -- Pressing should open the popup menu with the last entry selected + feed(':sign ') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{n: define }{1: }| + {1:~ }{n: jump }{1: }| + {1:~ }{n: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{s: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign undefine^ | + ]]) + + -- Pressing should close the popup menu and cancel the cmd line + feed(':sign ') + screen:expect([[ + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]) + + -- Typing a character when the popup is open, should close the popup + feed(':sign x') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :sign definex^ | + ]]) + + -- When the popup is open, entering the cmdline window should close the popup + feed('sign ') + screen:expect([[ + | + {3:[No Name] }| + {1::}sign define | + {1::}sign define^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {4:[Command Line] }| + :sign define | + ]]) + feed(':q') + + -- After the last popup menu item, should show the original string + feed(':sign u') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }{n: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign u^ | + ]]) + + -- Use the popup menu for the command name + feed('bu') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {s: bufdo }{1: }| + {n: buffer }{1: }| + {n: buffers }{1: }| + {n: bunload }{1: }| + :bufdo^ | + ]]) + + -- Pressing should remove the popup menu and erase the last character + feed('sign ') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :sign defin^ | + ]]) + + -- Pressing should remove the popup menu and erase the previous word + feed('sign ') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :sign ^ | + ]]) + + -- Pressing should remove the popup menu and erase the entire line + feed('sign ') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :^ | + ]]) + + -- Using to cancel the popup menu and then pressing should recall + -- the cmdline from history + feed('sign xyz:sign ') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :sign xyz^ | + ]]) + + feed('') + + -- Check "list" still works + command('set wildmode=longest,list') + feed(':cn') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {4: }| + :cn | + cnewer cnoreabbrev | + cnext cnoremap | + cnfile cnoremenu | + :cn^ | + ]]) + feed('s') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {4: }| + :cn | + cnewer cnoreabbrev | + cnext cnoremap | + cnfile cnoremenu | + :cns^ | + ]]) + + feed('') + command('set wildmode=full') + + -- Tests a directory name contained full-width characters. + feed(':e あいう/') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }{s: 123 }{1: }| + {1:~ }{n: abc }{1: }| + {1:~ }{n: xyz }{1: }| + :e あいう/123^ | + ]]) + feed('') + + -- Pressing should scroll the menu downward + feed(':sign ') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{n: define }{1: }| + {1:~ }{n: jump }{1: }| + {1:~ }{n: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{s: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign undefine^ | + ]]) + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{n: define }{1: }| + {1:~ }{n: jump }{1: }| + {1:~ }{n: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{n: undefine }{1: }| + {1:~ }{s: unplace }{1: }| + :sign unplace^ | + ]]) + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{n: define }{1: }| + {1:~ }{n: jump }{1: }| + {1:~ }{n: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{n: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign ^ | + ]]) + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{s: define }{1: }| + {1:~ }{n: jump }{1: }| + {1:~ }{n: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{n: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign define^ | + ]]) + feed('sign ') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{n: define }{1: }| + {1:~ }{n: jump }{1: }| + {1:~ }{n: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{n: undefine }{1: }| + {1:~ }{s: unplace }{1: }| + :sign unplace^ | + ]]) + + -- Pressing should scroll the menu upward + feed('sign ') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{n: define }{1: }| + {1:~ }{n: jump }{1: }| + {1:~ }{n: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{n: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign ^ | + ]]) + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{n: define }{1: }| + {1:~ }{n: jump }{1: }| + {1:~ }{n: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{n: undefine }{1: }| + {1:~ }{s: unplace }{1: }| + :sign unplace^ | + ]]) + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{n: define }{1: }| + {1:~ }{s: jump }{1: }| + {1:~ }{n: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{n: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign jump^ | + ]]) + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{s: define }{1: }| + {1:~ }{n: jump }{1: }| + {1:~ }{n: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{n: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign define^ | + ]]) + + feed('') + + -- check positioning with multibyte char in pattern + command("e långfile1") + command("sp långfile2") + feed(':b lå') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {4:långfile2 }| + | + {1:~ }| + {1:~ }{s: långfile1 }{1: }| + {3:lå}{n: långfile2 }{3: }| + :b långfile1^ | + ]]) + + -- check doesn't crash on screen resize + screen:try_resize(20,6) + screen:expect([[ + | + {1:~ }| + {4:långfile2 }| + {s: långfile1 } | + {3:lå}{n: långfile2 }{3: }| + :b långfile1^ | + ]]) + + screen:try_resize(50,15) + screen:expect([[ + | + {1:~ }| + {4:långfile2 }| + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }{s: långfile1 }{1: }| + {3:lå}{n: långfile2 }{3: }| + :b långfile1^ | + ]]) + + -- position is calculated correctly with "longest" + feed('') + command('set wildmode=longest:full,full') + feed(':b lå') + screen:expect([[ + | + {1:~ }| + {4:långfile2 }| + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }{n: långfile1 }{1: }| + {3:lå}{n: långfile2 }{3: }| + :b långfile^ | + ]]) + + feed('') + command("close") + command('set wildmode=full') + + -- special case: when patterns ends with "/", show menu items aligned + -- after the "/" + feed(':e compdir/') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }{s: file1 }{1: }| + {1:~ }{n: file2 }{1: }| + :e compdir/file1^ | + ]]) + end) + + it('wildoptions=pum with scrolled messages', function() + screen:try_resize(40,10) + command('set wildmenu') + command('set wildoptions=pum') + + feed(':echoerr "fail"|echoerr "error"') + screen:expect{grid=[[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {4: }| + {6:fail} | + {6:error} | + {5:Press ENTER or type command to continue}^ | + ]]} + + feed(':sign ') + screen:expect{grid=[[ + | + {1:~ }| + {1:~ }| + {1:~ }{s: define }{1: }| + {1:~ }{n: jump }{1: }| + {1:~ }{n: list }{1: }| + {4: }{n: place }{4: }| + {6:fail} {n: undefine } | + {6:error}{n: unplace } | + :sign define^ | + ]]} + + feed('d') + screen:expect{grid=[[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {4: }| + {6:fail} | + {6:error} | + :sign defined^ | + ]]} + end) + + it('wildoptions=pum and wildmode=longest,full #11622', function() + screen:try_resize(30,8) + command('set wildmenu') + command('set wildoptions=pum') + command('set wildmode=longest,full') + + -- With 'wildmode' set to 'longest,full', completing a match should display + -- the longest match, the wildmenu should not be displayed. + feed(':sign u') + screen:expect{grid=[[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :sign un^ | + ]]} + eq(0, funcs.wildmenumode()) + + -- pressing should display the wildmenu + feed('') + screen:expect{grid=[[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }{s: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign undefine^ | + ]]} + eq(1, funcs.wildmenumode()) + + -- pressing second time should select the next entry in the menu + feed('') + screen:expect{grid=[[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }{n: undefine }{1: }| + {1:~ }{s: unplace }{1: }| + :sign unplace^ | + ]]} + end) + + it('wildoptions=pum with a wrapped line in buffer vim-patch:8.2.4655', function() + screen:try_resize(32, 10) + meths.buf_set_lines(0, 0, -1, true, { ('a'):rep(100) }) + command('set wildoptions+=pum') + feed('$') + feed(':sign ') + screen:expect([[ + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa| + aaaa {s: define } | + {1:~ }{n: jump }{1: }| + {1:~ }{n: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{n: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign define^ | + ]]) + end) + + -- oldtest: Test_wildmenu_pum_clear_entries() + it('wildoptions=pum when using Ctrl-E as wildchar vim-patch:9.0.1030', function() + screen:try_resize(30, 10) + exec([[ + set wildoptions=pum + set wildchar= + ]]) + feed(':sign ') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{s: define }{1: }| + {1:~ }{n: jump }{1: }| + {1:~ }{n: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{n: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign define^ | + ]]) + assert_alive() + end) + end - -- Select the Paste entry, executes the changed menu item. - feed('jj') - screen:expect([[ - one two three four five | - and one two {7:^X}three four five | - one more two three four five | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - pasted | - ]]) - end) + it("'pumheight'", function() + screen:try_resize(32,8) + feed('isome long prefix before the ') + command("set completeopt+=noinsert,noselect") + command("set linebreak") + command("set pumheight=2") + funcs.complete(29, {'word', 'choice', 'text', 'thing'}) + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + some long prefix before the ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + {2:-- INSERT --} | + ## grid 4 + {n: word }{c: }| + {n: choice}{s: }| + ]], float_pos={ + [4] = {{id = -1}, "NW", 2, 1, 24, false, 100}; + }} + else + screen:expect([[ + some long prefix before the ^ | + {1:~ }{n: word }{c: }| + {1:~ }{n: choice}{s: }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + end + end) - describe('"kind" and "menu"', function() - before_each(function() - screen:try_resize(30, 8) - exec([[ - func CompleteFunc( findstart, base ) - if a:findstart - return 0 - endif - return { - \ 'words': [ - \ { 'word': 'aword1', 'menu': 'extra text 1', 'kind': 'W', }, - \ { 'word': 'aword2', 'menu': 'extra text 2', 'kind': 'W', }, - \ { 'word': 'aword3', 'menu': 'extra text 3', 'kind': 'W', }, - \]} - endfunc - set completeopt=menu - set completefunc=CompleteFunc - ]]) + it("'pumwidth'", function() + screen:try_resize(32,8) + feed('isome long prefix before the ') + command("set completeopt+=noinsert,noselect") + command("set linebreak") + command("set pumwidth=8") + funcs.complete(29, {'word', 'choice', 'text', 'thing'}) + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + some long prefix before the ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + {2:-- INSERT --} | + ## grid 4 + {n: word }| + {n: choice}| + {n: text }| + {n: thing }| + ]], float_pos={ + [4] = {{id = -1}, "NW", 2, 1, 25, false, 100}; + }} + else + screen:expect([[ + some long prefix before the ^ | + {1:~ }{n: word }| + {1:~ }{n: choice}| + {1:~ }{n: text }| + {1:~ }{n: thing }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + end end) - -- oldtest: Test_pum_highlights_default() - it('default highlight groups', function() - feed('iaw') - screen:expect([[ - aword1^ | - {s:aword1 W extra text 1 }{1: }| - {n:aword2 W extra text 2 }{1: }| - {n:aword3 W extra text 3 }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {2:-- }{5:match 1 of 3} | - ]]) + it('does not crash when displayed in the last column with rightleft #12032', function() + local col = 30 + local items = {'word', 'choice', 'text', 'thing'} + local max_len = 0 + for _, v in ipairs(items) do + max_len = max_len < #v and #v or max_len + end + screen:try_resize(col, 8) + command('set rightleft') + command('call setline(1, repeat(" ", &columns - '..max_len..'))') + feed('$i') + funcs.complete(col - max_len, items) + feed('') + assert_alive() end) - -- oldtest: Test_pum_highlights_custom() - it('custom highlight groups', function() - exec([[ - hi PmenuKind guifg=Red guibg=Magenta - hi PmenuKindSel guifg=Red guibg=Grey - hi PmenuExtra guifg=White guibg=Magenta - hi PmenuExtraSel guifg=Black guibg=Grey - ]]) - local attrs = screen:get_default_attr_ids() - attrs.kn = {foreground = Screen.colors.Red, background = Screen.colors.Magenta} - attrs.ks = {foreground = Screen.colors.Red, background = Screen.colors.Grey} - attrs.xn = {foreground = Screen.colors.White, background = Screen.colors.Magenta} - attrs.xs = {foreground = Screen.colors.Black, background = Screen.colors.Grey} - feed('iaw') - screen:expect([[ - aword1^ | - {s:aword1 }{ks:W }{xs:extra text 1 }{1: }| - {n:aword2 }{kn:W }{xn:extra text 2 }{1: }| - {n:aword3 }{kn:W }{xn:extra text 3 }{1: }| - {1:~ }| - {1:~ }| - {1:~ }| - {2:-- }{5:match 1 of 3} | - ]], attrs) + it('truncates double-width character correctly without scrollbar', function() + screen:try_resize(32, 8) + command('set completeopt+=menuone,noselect') + feed('i' .. string.rep(' ', 13)) + funcs.complete(14, {'哦哦哦哦哦哦哦哦哦哦'}) + if multigrid then + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + {2:-- INSERT --} | + ## grid 4 + {n: 哦哦哦哦哦哦哦哦哦>}| + ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 12, false, 100}}}) + else + screen:expect([[ + ^ | + {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + end end) - end) -end) -describe('builtin popupmenu with ui/ext_multigrid', function() - local screen - before_each(function() - clear() - screen = Screen.new(32, 20) - screen:attach({ext_multigrid=true}) - screen:set_default_attr_ids({ - -- popup selected item / scrollbar track - ['s'] = {background = Screen.colors.WebGray}, - -- popup non-selected item - ['n'] = {background = Screen.colors.LightMagenta}, - -- popup scrollbar knob - ['c'] = {background = Screen.colors.Grey0}, - [1] = {bold = true, foreground = Screen.colors.Blue}, - [2] = {bold = true}, - [3] = {reverse = true}, - [4] = {bold = true, reverse = true}, - [5] = {bold = true, foreground = Screen.colors.SeaGreen}, - [6] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red}, - }) - end) + it('truncates double-width character correctly with scrollbar', function() + screen:try_resize(32,8) + command('set completeopt+=noselect') + command('set pumheight=4') + feed('i' .. string.rep(' ', 12)) + local items = {} + for _ = 1, 8 do + table.insert(items, {word = '哦哦哦哦哦哦哦哦哦哦', equal = 1, dup = 1}) + end + funcs.complete(13, items) + if multigrid then + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + {2:-- INSERT --} | + ## grid 4 + {n: 哦哦哦哦哦哦哦哦哦>}{c: }| + {n: 哦哦哦哦哦哦哦哦哦>}{c: }| + {n: 哦哦哦哦哦哦哦哦哦>}{s: }| + {n: 哦哦哦哦哦哦哦哦哦>}{s: }| + ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 11, false, 100}}}) + else + screen:expect([[ + ^ | + {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{c: }| + {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{c: }| + {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{s: }| + {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{s: }| + {1:~ }| + {1:~ }| + {2:-- INSERT --} | + ]]) + end + end) - it('truncates double-width character correctly when there is no scrollbar', function() - screen:try_resize(32,8) - command('set completeopt+=menuone,noselect') - feed('i' .. string.rep(' ', 13)) - funcs.complete(14, {'哦哦哦哦哦哦哦哦哦哦'}) - screen:expect({grid=[[ - ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [3:--------------------------------]| - ## grid 2 - ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ## grid 3 - {2:-- INSERT --} | - ## grid 4 - {n: 哦哦哦哦哦哦哦哦哦>}| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 12, false, 100}}}) - end) + it('supports mousemodel=popup', function() + screen:try_resize(32, 6) + exec([[ + call setline(1, 'popup menu test') + set mouse=a mousemodel=popup + + aunmenu PopUp + menu PopUp.foo :let g:menustr = 'foo' + menu PopUp.bar :let g:menustr = 'bar' + menu PopUp.baz :let g:menustr = 'baz' + ]]) - it('truncates double-width character correctly when there is scrollbar', function() - screen:try_resize(32,8) - command('set completeopt+=noselect') - command('set pumheight=4') - feed('i' .. string.rep(' ', 12)) - local items = {} - for _ = 1, 8 do - table.insert(items, {word = '哦哦哦哦哦哦哦哦哦哦', equal = 1, dup = 1}) + if multigrid then + meths.input_mouse('right', 'press', '', 2, 0, 4) + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + | + ## grid 4 + {n: foo }| + {n: bar }| + {n: baz }| + ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) + else + feed('<4,0>') + screen:expect([[ + ^popup menu test | + {1:~ }{n: foo }{1: }| + {1:~ }{n: bar }{1: }| + {1:~ }{n: baz }{1: }| + {1:~ }| + | + ]]) + end + feed('') + if multigrid then + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + | + ## grid 4 + {s: foo }| + {n: bar }| + {n: baz }| + ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) + else + screen:expect([[ + ^popup menu test | + {1:~ }{s: foo }{1: }| + {1:~ }{n: bar }{1: }| + {1:~ }{n: baz }{1: }| + {1:~ }| + | + ]]) + end + feed('') + if multigrid then + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + | + ## grid 4 + {n: foo }| + {s: bar }| + {n: baz }| + ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) + else + screen:expect([[ + ^popup menu test | + {1:~ }{n: foo }{1: }| + {1:~ }{s: bar }{1: }| + {1:~ }{n: baz }{1: }| + {1:~ }| + | + ]]) + end + feed('') + if multigrid then + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + :let g:menustr = 'bar' | + ]]}) + else + screen:expect([[ + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :let g:menustr = 'bar' | + ]]) + end + eq('bar', meths.get_var('menustr')) + + if multigrid then + meths.input_mouse('right', 'press', '', 2, 2, 20) + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + :let g:menustr = 'bar' | + ## grid 4 + {n: foo }| + {n: bar }| + {n: baz }| + ]], float_pos={[4] = {{id = -1}, 'NW', 2, 3, 19, false, 250}}}) + else + feed('<20,2>') + screen:expect([[ + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }{n: foo }{1: }| + {1:~ }{n: bar }{1: }| + :let g:menustr = 'b{n: baz } | + ]]) + end + if multigrid then + meths.input_mouse('left', 'press', '', 4, 2, 2) + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + :let g:menustr = 'baz' | + ]]}) + else + feed('<22,5>') + screen:expect([[ + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :let g:menustr = 'baz' | + ]]) + end + eq('baz', meths.get_var('menustr')) + + if multigrid then + meths.input_mouse('right', 'press', '', 2, 0, 4) + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + :let g:menustr = 'baz' | + ## grid 4 + {n: foo }| + {n: bar }| + {n: baz }| + ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) + else + feed('<4,0>') + screen:expect([[ + ^popup menu test | + {1:~ }{n: foo }{1: }| + {1:~ }{n: bar }{1: }| + {1:~ }{n: baz }{1: }| + {1:~ }| + :let g:menustr = 'baz' | + ]]) + end + if multigrid then + meths.input_mouse('right', 'drag', '', 2, 3, 6) + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + :let g:menustr = 'baz' | + ## grid 4 + {n: foo }| + {n: bar }| + {s: baz }| + ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) + else + feed('<6,3>') + screen:expect([[ + ^popup menu test | + {1:~ }{n: foo }{1: }| + {1:~ }{n: bar }{1: }| + {1:~ }{s: baz }{1: }| + {1:~ }| + :let g:menustr = 'baz' | + ]]) + end + if multigrid then + meths.input_mouse('right', 'release', '', 2, 1, 6) + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + :let g:menustr = 'foo' | + ]]}) + else + feed('<6,1>') + screen:expect([[ + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :let g:menustr = 'foo' | + ]]) + end + eq('foo', meths.get_var('menustr')) + + eq(false, screen.options.mousemoveevent) + if multigrid then + meths.input_mouse('right', 'press', '', 2, 0, 4) + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + :let g:menustr = 'foo' | + ## grid 4 + {n: foo }| + {n: bar }| + {n: baz }| + ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) + else + feed('<4,0>') + screen:expect([[ + ^popup menu test | + {1:~ }{n: foo }{1: }| + {1:~ }{n: bar }{1: }| + {1:~ }{n: baz }{1: }| + {1:~ }| + :let g:menustr = 'foo' | + ]]) + end + eq(true, screen.options.mousemoveevent) + if multigrid then + meths.input_mouse('move', '', '', 2, 3, 6) + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + :let g:menustr = 'foo' | + ## grid 4 + {n: foo }| + {n: bar }| + {s: baz }| + ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) + else + feed('<6,3>') + screen:expect([[ + ^popup menu test | + {1:~ }{n: foo }{1: }| + {1:~ }{n: bar }{1: }| + {1:~ }{s: baz }{1: }| + {1:~ }| + :let g:menustr = 'foo' | + ]]) + end + eq(true, screen.options.mousemoveevent) + if multigrid then + meths.input_mouse('left', 'press', '', 2, 2, 6) + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [2:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + ## grid 3 + :let g:menustr = 'bar' | + ]]}) + else + feed('<6,2>') + screen:expect([[ + ^popup menu test | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :let g:menustr = 'bar' | + ]]) + end + eq(false, screen.options.mousemoveevent) + eq('bar', meths.get_var('menustr')) + + command('set laststatus=0 | botright split') + if multigrid then + meths.input_mouse('right', 'press', '', 5, 1, 20) + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + {3:[No Name] [+] }| + [5:--------------------------------]| + [5:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + popup menu test | + {1:~ }| + ## grid 3 + :let g:menustr = 'bar' | + ## grid 4 + {n: foo }| + {n: bar }| + {n: baz }| + ## grid 5 + ^popup menu test | + {1:~ }| + ]], float_pos={[4] = {{id = -1}, "SW", 5, 1, 19, false, 250}}}) + else + feed('<20,4>') + screen:expect([[ + popup menu test | + {1:~ }{n: foo }{1: }| + {3:[No Name] [+] }{n: bar }{3: }| + ^popup menu test {n: baz } | + {1:~ }| + :let g:menustr = 'bar' | + ]]) + end + if multigrid then + meths.input_mouse('left', 'press', '', 4, 2, 2) + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + {3:[No Name] [+] }| + [5:--------------------------------]| + [5:--------------------------------]| + [3:--------------------------------]| + ## grid 2 + popup menu test | + {1:~ }| + ## grid 3 + :let g:menustr = 'baz' | + ## grid 5 + ^popup menu test | + {1:~ }| + ]]}) + else + feed('<22,3>') + screen:expect([[ + popup menu test | + {1:~ }| + {3:[No Name] [+] }| + ^popup menu test | + {1:~ }| + :let g:menustr = 'baz' | + ]]) + end + eq('baz', meths.get_var('menustr')) + + command('set winwidth=1 | rightbelow vsplit') + if multigrid then + meths.input_mouse('right', 'press', '', 6, 1, 14) + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + {3:[No Name] [+] }| + [5:---------------]│[6:----------------]| + [5:---------------]│[6:----------------]| + [3:--------------------------------]| + ## grid 2 + popup menu test | + {1:~ }| + ## grid 3 + :let g:menustr = 'baz' | + ## grid 4 + {n: foo}| + {n: bar}| + {n: baz}| + ## grid 5 + popup menu test| + {1:~ }| + ## grid 6 + ^popup menu test | + {1:~ }| + ]], float_pos={[4] = {{id = -1}, "SW", 6, 1, 12, false, 250}}}) + else + feed('<30,4>') + screen:expect([[ + popup menu test | + {1:~ }{n: foo}| + {3:[No Name] [+] }{n: bar}| + popup menu test│^popup menu t{n: baz}| + {1:~ }│{1:~ }| + :let g:menustr = 'baz' | + ]]) + end + if multigrid then + meths.input_mouse('left', 'press', '', 4, 0, 2) + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + {3:[No Name] [+] }| + [5:---------------]│[6:----------------]| + [5:---------------]│[6:----------------]| + [3:--------------------------------]| + ## grid 2 + popup menu test | + {1:~ }| + ## grid 3 + :let g:menustr = 'foo' | + ## grid 5 + popup menu test| + {1:~ }| + ## grid 6 + ^popup menu test | + {1:~ }| + ]]}) + else + feed('<31,1>') + screen:expect([[ + popup menu test | + {1:~ }| + {3:[No Name] [+] }| + popup menu test│^popup menu test | + {1:~ }│{1:~ }| + :let g:menustr = 'foo' | + ]]) + end + eq('foo', meths.get_var('menustr')) + end) + + if not multigrid then + -- oldtest: Test_popup_command_dump() + it(':popup command', function() + exec([[ + func ChangeMenu() + aunmenu PopUp.&Paste + nnoremenu 1.40 PopUp.&Paste :echomsg "pasted" + echomsg 'changed' + return "\" + endfunc + + let lines =<< trim END + one two three four five + and one two Xthree four five + one more two three four five + END + call setline(1, lines) + + aunmenu * + source $VIMRUNTIME/menu.vim + ]]) + feed('/X:popup PopUp') + screen:expect([[ + one two three four five | + and one two {7:^X}three four five | + one more tw{n: Undo } | + {1:~ }{n: }{1: }| + {1:~ }{n: Paste }{1: }| + {1:~ }{n: }{1: }| + {1:~ }{n: Select Word }{1: }| + {1:~ }{n: Select Sentence }{1: }| + {1:~ }{n: Select Paragraph }{1: }| + {1:~ }{n: Select Line }{1: }| + {1:~ }{n: Select Block }{1: }| + {1:~ }{n: Select All }{1: }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :popup PopUp | + ]]) + + -- go to the Paste entry in the menu + feed('jj') + screen:expect([[ + one two three four five | + and one two {7:^X}three four five | + one more tw{n: Undo } | + {1:~ }{n: }{1: }| + {1:~ }{s: Paste }{1: }| + {1:~ }{n: }{1: }| + {1:~ }{n: Select Word }{1: }| + {1:~ }{n: Select Sentence }{1: }| + {1:~ }{n: Select Paragraph }{1: }| + {1:~ }{n: Select Line }{1: }| + {1:~ }{n: Select Block }{1: }| + {1:~ }{n: Select All }{1: }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :popup PopUp | + ]]) + + -- Select a word + feed('j') + screen:expect([[ + one two three four five | + and one two {7:^X}three four five | + one more tw{n: Undo } | + {1:~ }{n: }{1: }| + {1:~ }{n: Paste }{1: }| + {1:~ }{n: }{1: }| + {1:~ }{s: Select Word }{1: }| + {1:~ }{n: Select Sentence }{1: }| + {1:~ }{n: Select Paragraph }{1: }| + {1:~ }{n: Select Line }{1: }| + {1:~ }{n: Select Block }{1: }| + {1:~ }{n: Select All }{1: }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :popup PopUp | + ]]) + + feed('') + + -- Set an mapping to change a menu entry while it's displayed. + -- The text should not change but the command does. + -- Also verify that "changed" shows up, which means the mapping triggered. + command('nnoremap ChangeMenu()') + feed('/X:popup PopUp') + screen:expect([[ + one two three four five | + and one two {7:^X}three four five | + one more tw{n: Undo } | + {1:~ }{n: }{1: }| + {1:~ }{n: Paste }{1: }| + {1:~ }{n: }{1: }| + {1:~ }{n: Select Word }{1: }| + {1:~ }{n: Select Sentence }{1: }| + {1:~ }{n: Select Paragraph }{1: }| + {1:~ }{n: Select Line }{1: }| + {1:~ }{n: Select Block }{1: }| + {1:~ }{n: Select All }{1: }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + changed | + ]]) + + -- Select the Paste entry, executes the changed menu item. + feed('jj') + screen:expect([[ + one two three four five | + and one two {7:^X}three four five | + one more two three four five | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + pasted | + ]]) + end) + + describe('"kind" and "menu"', function() + before_each(function() + screen:try_resize(30, 8) + exec([[ + func CompleteFunc( findstart, base ) + if a:findstart + return 0 + endif + return { + \ 'words': [ + \ { 'word': 'aword1', 'menu': 'extra text 1', 'kind': 'W', }, + \ { 'word': 'aword2', 'menu': 'extra text 2', 'kind': 'W', }, + \ { 'word': 'aword3', 'menu': 'extra text 3', 'kind': 'W', }, + \]} + endfunc + set completeopt=menu + set completefunc=CompleteFunc + ]]) + end) + + -- oldtest: Test_pum_highlights_default() + it('default highlight groups', function() + feed('iaw') + screen:expect([[ + aword1^ | + {s:aword1 W extra text 1 }{1: }| + {n:aword2 W extra text 2 }{1: }| + {n:aword3 W extra text 3 }{1: }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- }{5:match 1 of 3} | + ]]) + end) + + -- oldtest: Test_pum_highlights_custom() + it('custom highlight groups', function() + exec([[ + hi PmenuKind guifg=Red guibg=Magenta + hi PmenuKindSel guifg=Red guibg=Grey + hi PmenuExtra guifg=White guibg=Magenta + hi PmenuExtraSel guifg=Black guibg=Grey + ]]) + local attrs = screen:get_default_attr_ids() + attrs.kn = {foreground = Screen.colors.Red, background = Screen.colors.Magenta} + attrs.ks = {foreground = Screen.colors.Red, background = Screen.colors.Grey} + attrs.xn = {foreground = Screen.colors.White, background = Screen.colors.Magenta} + attrs.xs = {foreground = Screen.colors.Black, background = Screen.colors.Grey} + feed('iaw') + screen:expect([[ + aword1^ | + {s:aword1 }{ks:W }{xs:extra text 1 }{1: }| + {n:aword2 }{kn:W }{xn:extra text 2 }{1: }| + {n:aword3 }{kn:W }{xn:extra text 3 }{1: }| + {1:~ }| + {1:~ }| + {1:~ }| + {2:-- }{5:match 1 of 3} | + ]], attrs) + end) + end) end - funcs.complete(13, items) - screen:expect({grid=[[ - ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [3:--------------------------------]| - ## grid 2 - ^ | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ## grid 3 - {2:-- INSERT --} | - ## grid 4 - {n: 哦哦哦哦哦哦哦哦哦>}{c: }| - {n: 哦哦哦哦哦哦哦哦哦>}{c: }| - {n: 哦哦哦哦哦哦哦哦哦>}{s: }| - {n: 哦哦哦哦哦哦哦哦哦>}{s: }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 11, false, 100}}}) - end) + end - it('supports mousemodel=popup', function() - screen:try_resize(32, 6) - exec([[ - call setline(1, 'popup menu test') - set mouse=a mousemodel=popup + describe('with ext_multigrid', function() + with_ext_multigrid(true) + end) - aunmenu PopUp - menu PopUp.foo :let g:menustr = 'foo' - menu PopUp.bar :let g:menustr = 'bar' - menu PopUp.baz :let g:menustr = 'baz' - ]]) - meths.input_mouse('right', 'press', '', 2, 1, 20) - screen:expect({grid=[[ - ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [3:--------------------------------]| - ## grid 2 - ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ## grid 3 - | - ## grid 4 - {n: foo }| - {n: bar }| - {n: baz }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 2, 19, false, 250}}}) - meths.input_mouse('left', 'press', '', 4, 2, 2) - screen:expect({grid=[[ - ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [3:--------------------------------]| - ## grid 2 - ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ## grid 3 - :let g:menustr = 'baz' | - ]]}) - eq('baz', meths.get_var('menustr')) - meths.input_mouse('right', 'press', '', 2, 0, 4) - screen:expect({grid=[[ - ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [3:--------------------------------]| - ## grid 2 - ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ## grid 3 - :let g:menustr = 'baz' | - ## grid 4 - {n: foo }| - {n: bar }| - {n: baz }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) - meths.input_mouse('right', 'drag', '', 2, 3, 6) - screen:expect({grid=[[ - ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [3:--------------------------------]| - ## grid 2 - ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ## grid 3 - :let g:menustr = 'baz' | - ## grid 4 - {n: foo }| - {n: bar }| - {s: baz }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) - meths.input_mouse('right', 'release', '', 2, 1, 6) - screen:expect({grid=[[ - ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [3:--------------------------------]| - ## grid 2 - ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ## grid 3 - :let g:menustr = 'foo' | - ]]}) - eq('foo', meths.get_var('menustr')) - eq(false, screen.options.mousemoveevent) - meths.input_mouse('right', 'press', '', 2, 0, 4) - screen:expect({grid=[[ - ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [3:--------------------------------]| - ## grid 2 - ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ## grid 3 - :let g:menustr = 'foo' | - ## grid 4 - {n: foo }| - {n: bar }| - {n: baz }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) - eq(true, screen.options.mousemoveevent) - meths.input_mouse('move', '', '', 2, 3, 6) - screen:expect({grid=[[ - ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [3:--------------------------------]| - ## grid 2 - ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ## grid 3 - :let g:menustr = 'foo' | - ## grid 4 - {n: foo }| - {n: bar }| - {s: baz }| - ]], float_pos={[4] = {{id = -1}, 'NW', 2, 1, 3, false, 250}}}) - eq(true, screen.options.mousemoveevent) - meths.input_mouse('left', 'press', '', 2, 2, 6) - screen:expect({grid=[[ - ## grid 1 - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [2:--------------------------------]| - [3:--------------------------------]| - ## grid 2 - ^popup menu test | - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - ## grid 3 - :let g:menustr = 'bar' | - ]]}) - eq(false, screen.options.mousemoveevent) - eq('bar', meths.get_var('menustr')) + describe('without ext_multigrid', function() + with_ext_multigrid(false) end) end) -- cgit From aca226d728418e791b897a908631d52aa24157fe Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 28 Apr 2023 05:50:08 +0800 Subject: vim-patch:9.0.1493: popup menu position wrong in window with toolbar Problem: Popup menu position wrong in window with toolbar. Solution: Take the window toolbar into account when positioning the popup menu. (closes vim/vim#12308) https://github.com/vim/vim/commit/4e1ca0d9a6c6d66987da67155e97f83f286ffbcc Fixed in the previous commit. Test only. --- test/functional/ui/popupmenu_spec.lua | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'test/functional/ui/popupmenu_spec.lua') diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index c5e0c10a81..0b71e12b6f 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -4508,6 +4508,34 @@ describe('builtin popupmenu', function() {1:~ }| pasted | ]]) + + -- Add a window toolbar to the window and check the :popup menu position. + command('setlocal winbar=TEST') + feed('/X:popup PopUp') + screen:expect([[ + {2:TEST }| + one two three four five | + and one two {7:^X}three four five | + one more tw{n: Undo } | + {1:~ }{n: }{1: }| + {1:~ }{n: Paste }{1: }| + {1:~ }{n: }{1: }| + {1:~ }{n: Select Word }{1: }| + {1:~ }{n: Select Sentence }{1: }| + {1:~ }{n: Select Paragraph }{1: }| + {1:~ }{n: Select Line }{1: }| + {1:~ }{n: Select Block }{1: }| + {1:~ }{n: Select All }{1: }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :popup PopUp | + ]]) + + feed('') end) describe('"kind" and "menu"', function() -- cgit From f3b44cf23d9c240471826e4f35555ee85ded1e5b Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Thu, 27 Apr 2023 04:54:50 +0200 Subject: vim-patch:9.0.0652: 'smoothscroll' not tested with 'number' and "n" in 'cpo' Problem: 'smoothscroll' not tested with 'number' and "n" in 'cpo'. Solution: Add tests, fix uncovered problem. https://github.com/vim/vim/commit/b6aab8f44beb8c5d99393abdc2c9faab085c72aa Co-authored-by: Bram Moolenaar --- test/functional/ui/popupmenu_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/functional/ui/popupmenu_spec.lua') diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 0b71e12b6f..6c26c8ea39 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -2396,7 +2396,7 @@ describe('builtin popupmenu', function() -- can't draw the pum, but check we don't crash screen:try_resize(12,2) screen:expect([[ - text^ | + {1:<<<}t^ | {2:-- INSERT -} | ]]) -- cgit From f186224dfcf86678b6e5ee126d6b9a393f02f634 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 2 May 2023 23:55:14 +0800 Subject: fix(pum): fix missing rightmost column with 'rightleft' (#23445) --- test/functional/ui/popupmenu_spec.lua | 225 +++++++++++++++++++++++++++++++--- 1 file changed, 208 insertions(+), 17 deletions(-) (limited to 'test/functional/ui/popupmenu_spec.lua') diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 6c26c8ea39..4c0ecd9c4e 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -5,6 +5,7 @@ local clear, feed = helpers.clear, helpers.feed local source = helpers.source local insert = helpers.insert local meths = helpers.meths +local async_meths = helpers.async_meths local command = helpers.command local funcs = helpers.funcs local eq = helpers.eq @@ -1978,6 +1979,54 @@ describe('builtin popupmenu', function() {2:-- }{5:match 1 of 4} | ]]) end + + feed('\n') + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [4:-----------]│[2:--------------------]| + [4:-----------]│[2:--------------------]| + [4:-----------]│[2:--------------------]| + [4:-----------]│[2:--------------------]| + [4:-----------]│[2:--------------------]| + [4:-----------]│[2:--------------------]| + {3:') screen:expect([[ ^ drow tfelthgir emos| - {1: }{s: drow}{1: ~}| - {1: }{n: eciohc}{1: ~}| - {1: }{n: txet}{1: ~}| - {1: }{n: gniht}{1: ~}| + {1: }{s: drow }{1: ~}| + {1: }{n: eciohc }{1: ~}| + {1: }{n: txet }{1: ~}| + {1: }{n: gniht }{1: ~}| {1: ~}| {1: ~}| {1: ~}| @@ -2643,25 +2692,167 @@ describe('builtin popupmenu', function() {1: ~}| {1: ~}| ## grid 5 - {n: drow}| - {n: eciohc}| - {n: txet}| - {n: gniht}| + {n: drow }| + {n: eciohc }| + {n: txet }| + {n: gniht }| ]], float_pos={ - [5] = {{id = -1}, "NW", 4, 1, -11, false, 100}; + [5] = {{id = -1}, "NW", 4, 1, -10, false, 100}; }} else screen:expect([[ tfelthgir emos│ ^ tfelthgir emos| - {1: }{n: drow}{1: ~}| - {1: }{n: eciohc}{1: ~}| - {1: }{n: txet}{1: ~}| - {1: }{n: gniht}{1: ~}| + {1: }{n: drow }{1: ~}| + {1: }{n: eciohc }{1: ~}| + {1: }{n: txet }{1: ~}| + {1: }{n: gniht }{1: ~}| {1: ~}│{1: ~}| {3:[No Name] [+] }{4:[No Name] [+] }| {2:-- INSERT --} | ]]) end + feed('') + funcs.complete(1, {'word', 'choice', 'text', 'thing'}) + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + {3:[No Name] [+] }{4:[No Name] [+] }| + [3:----------------------------------------]| + ## grid 2 + tfelthgir emos| + | + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + ## grid 3 + {2:-- INSERT --} | + ## grid 4 + tfelthgir emos| + ^ | + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + ## grid 5 + {n: drow}| + {n: eciohc}| + {n: txet}| + {n: gniht}| + ]], float_pos={ + [5] = {{id = -1}, "NW", 4, 2, 5, false, 100}; + }} + else + screen:expect([[ + tfelthgir emos│ tfelthgir emos| + │ ^ | + {1: ~}│{1: }{n: drow}| + {1: ~}│{1: }{n: eciohc}| + {1: ~}│{1: }{n: txet}| + {1: ~}│{1: }{n: gniht}| + {3:[No Name] [+] }{4:[No Name] [+] }| + {2:-- INSERT --} | + ]]) + end + feed('') + async_meths.call_function('input', {'', '', 'sign'}) + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + {3:[No Name] [+] }{4:[No Name] [+] }| + [3:----------------------------------------]| + ## grid 2 + tfelthgir emos| + | + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + ## grid 3 + ^ | + ## grid 4 + tfelthgir emos| + | + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + ]]} + else + screen:expect([[ + tfelthgir emos│ tfelthgir emos| + │ | + {1: ~}│{1: ~}| + {1: ~}│{1: ~}| + {1: ~}│{1: ~}| + {1: ~}│{1: ~}| + {3:[No Name] [+] }{4:[No Name] [+] }| + ^ | + ]]) + end + command('set wildoptions+=pum') + feed('') + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + [2:-------------------]│[4:--------------------]| + {3:[No Name] [+] }{4:[No Name] [+] }| + [3:----------------------------------------]| + ## grid 2 + tfelthgir emos| + | + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + ## grid 3 + define^ | + ## grid 4 + tfelthgir emos| + | + {1: ~}| + {1: ~}| + {1: ~}| + {1: ~}| + ## grid 5 + {s:define }| + {n:jump }| + {n:list }| + {n:place }| + {n:undefine }| + {n:unplace }| + ]], float_pos={ + [5] = {{id = -1}, "SW", 1, 7, 0, false, 250}; + }} + else + screen:expect([[ + tfelthgir emos│ tfelthgir emos| + {s:define } │ | + {n:jump }{1: ~}│{1: ~}| + {n:list }{1: ~}│{1: ~}| + {n:place }{1: ~}│{1: ~}| + {n:undefine }{1: ~}│{1: ~}| + {n:unplace }{3: }{4:[No Name] [+] }| + define^ | + ]]) + end end) if not multigrid then -- cgit From 8bc973c6f59c6b90917dafc025303e69835167a3 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 3 May 2023 01:13:03 +0800 Subject: fix(pum): fix missing scrollbar with 'rightleft' (#23448) --- test/functional/ui/popupmenu_spec.lua | 79 +++++++++-------------------------- 1 file changed, 20 insertions(+), 59 deletions(-) (limited to 'test/functional/ui/popupmenu_spec.lua') diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 4c0ecd9c4e..61b815dbf6 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -2658,10 +2658,11 @@ describe('builtin popupmenu', function() end it('with rightleft vsplits', function() - screen:try_resize(40, 8) + screen:try_resize(40, 6) command('set rightleft') command('rightbelow vsplit') - command("set completeopt+=noinsert,noselect") + command('set completeopt+=noinsert,noselect') + command('set pumheight=2') feed('isome rightleft ') funcs.complete(16, {'word', 'choice', 'text', 'thing'}) if multigrid then @@ -2671,8 +2672,6 @@ describe('builtin popupmenu', function() [2:-------------------]│[4:--------------------]| [2:-------------------]│[4:--------------------]| [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| {3:[No Name] [+] }{4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -2680,8 +2679,6 @@ describe('builtin popupmenu', function() {1: ~}| {1: ~}| {1: ~}| - {1: ~}| - {1: ~}| ## grid 3 {2:-- INSERT --} | ## grid 4 @@ -2689,23 +2686,17 @@ describe('builtin popupmenu', function() {1: ~}| {1: ~}| {1: ~}| - {1: ~}| - {1: ~}| ## grid 5 - {n: drow }| - {n: eciohc }| - {n: txet }| - {n: gniht }| + {c: }{n: drow }| + {s: }{n: eciohc }| ]], float_pos={ - [5] = {{id = -1}, "NW", 4, 1, -10, false, 100}; + [5] = {{id = -1}, "NW", 4, 1, -11, false, 100}; }} else screen:expect([[ tfelthgir emos│ ^ tfelthgir emos| - {1: }{n: drow }{1: ~}| - {1: }{n: eciohc }{1: ~}| - {1: }{n: txet }{1: ~}| - {1: }{n: gniht }{1: ~}| + {1: }{c: }{n: drow }{1: ~}| + {1: }{s: }{n: eciohc }{1: ~}| {1: ~}│{1: ~}| {3:[No Name] [+] }{4:[No Name] [+] }| {2:-- INSERT --} | @@ -2720,8 +2711,6 @@ describe('builtin popupmenu', function() [2:-------------------]│[4:--------------------]| [2:-------------------]│[4:--------------------]| [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| {3:[No Name] [+] }{4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -2729,8 +2718,6 @@ describe('builtin popupmenu', function() | {1: ~}| {1: ~}| - {1: ~}| - {1: ~}| ## grid 3 {2:-- INSERT --} | ## grid 4 @@ -2738,24 +2725,18 @@ describe('builtin popupmenu', function() ^ | {1: ~}| {1: ~}| - {1: ~}| - {1: ~}| ## grid 5 - {n: drow}| - {n: eciohc}| - {n: txet}| - {n: gniht}| + {c: }{n: drow}| + {s: }{n: eciohc}| ]], float_pos={ - [5] = {{id = -1}, "NW", 4, 2, 5, false, 100}; + [5] = {{id = -1}, "NW", 4, 2, 4, false, 100}; }} else screen:expect([[ tfelthgir emos│ tfelthgir emos| │ ^ | - {1: ~}│{1: }{n: drow}| - {1: ~}│{1: }{n: eciohc}| - {1: ~}│{1: }{n: txet}| - {1: ~}│{1: }{n: gniht}| + {1: ~}│{1: }{c: }{n: drow}| + {1: ~}│{1: }{s: }{n: eciohc}| {3:[No Name] [+] }{4:[No Name] [+] }| {2:-- INSERT --} | ]]) @@ -2769,8 +2750,6 @@ describe('builtin popupmenu', function() [2:-------------------]│[4:--------------------]| [2:-------------------]│[4:--------------------]| [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| {3:[No Name] [+] }{4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -2778,8 +2757,6 @@ describe('builtin popupmenu', function() | {1: ~}| {1: ~}| - {1: ~}| - {1: ~}| ## grid 3 ^ | ## grid 4 @@ -2787,8 +2764,6 @@ describe('builtin popupmenu', function() | {1: ~}| {1: ~}| - {1: ~}| - {1: ~}| ]]} else screen:expect([[ @@ -2796,8 +2771,6 @@ describe('builtin popupmenu', function() │ | {1: ~}│{1: ~}| {1: ~}│{1: ~}| - {1: ~}│{1: ~}| - {1: ~}│{1: ~}| {3:[No Name] [+] }{4:[No Name] [+] }| ^ | ]]) @@ -2811,8 +2784,6 @@ describe('builtin popupmenu', function() [2:-------------------]│[4:--------------------]| [2:-------------------]│[4:--------------------]| [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| - [2:-------------------]│[4:--------------------]| {3:[No Name] [+] }{4:[No Name] [+] }| [3:----------------------------------------]| ## grid 2 @@ -2820,8 +2791,6 @@ describe('builtin popupmenu', function() | {1: ~}| {1: ~}| - {1: ~}| - {1: ~}| ## grid 3 define^ | ## grid 4 @@ -2829,27 +2798,19 @@ describe('builtin popupmenu', function() | {1: ~}| {1: ~}| - {1: ~}| - {1: ~}| ## grid 5 - {s:define }| - {n:jump }| - {n:list }| - {n:place }| - {n:undefine }| - {n:unplace }| + {s:define }{c: }| + {n:jump }{s: }| ]], float_pos={ - [5] = {{id = -1}, "SW", 1, 7, 0, false, 250}; + [5] = {{id = -1}, "SW", 1, 5, 0, false, 250}; }} else screen:expect([[ tfelthgir emos│ tfelthgir emos| - {s:define } │ | - {n:jump }{1: ~}│{1: ~}| - {n:list }{1: ~}│{1: ~}| - {n:place }{1: ~}│{1: ~}| - {n:undefine }{1: ~}│{1: ~}| - {n:unplace }{3: }{4:[No Name] [+] }| + │ | + {1: ~}│{1: ~}| + {s:define }{c: }{1: ~}│{1: ~}| + {n:jump }{s: }{3: }{4:[No Name] [+] }| define^ | ]]) end -- cgit From dc394b9641f92a5014147da58f5e14fd1681ec0f Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 3 May 2023 10:29:19 +0800 Subject: fix(mouse): fix popup menu position check with winbar (#23456) --- test/functional/ui/popupmenu_spec.lua | 73 +++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'test/functional/ui/popupmenu_spec.lua') diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 61b815dbf6..76038472bd 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -4509,6 +4509,79 @@ describe('builtin popupmenu', function() ]]) end eq('foo', meths.get_var('menustr')) + + command('setlocal winbar=WINBAR') + if multigrid then + meths.input_mouse('right', 'press', '', 6, 1, 14) + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + {3:[No Name] [+] }| + [5:---------------]│[6:----------------]| + [5:---------------]│[6:----------------]| + [3:--------------------------------]| + ## grid 2 + popup menu test | + {1:~ }| + ## grid 3 + :let g:menustr = 'foo' | + ## grid 4 + {n: foo}| + {n: bar}| + {n: baz}| + ## grid 5 + popup menu test| + {1:~ }| + ## grid 6 + {2:WINBAR }| + ^popup menu test | + ]], float_pos={[4] = {{id = -1}, "SW", 6, 1, 12, false, 250}}}) + else + feed('<30,4>') + screen:expect([[ + popup menu test | + {1:~ }{n: foo}| + {3:[No Name] [+] }{n: bar}| + popup menu test│{2:WINBAR }{n: baz}| + {1:~ }│^popup menu test | + :let g:menustr = 'foo' | + ]]) + end + if multigrid then + meths.input_mouse('left', 'press', '', 4, 1, 2) + screen:expect({grid=[[ + ## grid 1 + [2:--------------------------------]| + [2:--------------------------------]| + {3:[No Name] [+] }| + [5:---------------]│[6:----------------]| + [5:---------------]│[6:----------------]| + [3:--------------------------------]| + ## grid 2 + popup menu test | + {1:~ }| + ## grid 3 + :let g:menustr = 'bar' | + ## grid 5 + popup menu test| + {1:~ }| + ## grid 6 + {2:WINBAR }| + ^popup menu test | + ]]}) + else + feed('<31,2>') + screen:expect([[ + popup menu test | + {1:~ }| + {3:[No Name] [+] }| + popup menu test│{2:WINBAR }| + {1:~ }│^popup menu test | + :let g:menustr = 'bar' | + ]]) + end + eq('bar', meths.get_var('menustr')) end) if not multigrid then -- cgit From b84a67f50ed6141f72d433094a1a611ae4f67924 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 22 Aug 2023 22:48:55 +0800 Subject: vim-patch:9.0.0579: using freed memory when 'tagfunc' wipes out buffer (#24838) Problem: Using freed memory when 'tagfunc' wipes out buffer that holds 'complete'. Solution: Make a copy of the option. Make sure cursor position is valid. https://github.com/vim/vim/commit/0ff01835a40f549c5c4a550502f62a2ac9ac447c Cherry-pick a cmdwin change from patch 9.0.0500. Co-authored-by: Bram Moolenaar --- test/functional/ui/popupmenu_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/functional/ui/popupmenu_spec.lua') diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 76038472bd..ea65cf35bd 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -3239,7 +3239,7 @@ describe('builtin popupmenu', function() | {3:[No Name] }| {1::}sign define | - {1::}sign define^ | + {1::}sign defin^e | {1:~ }| {1:~ }| {1:~ }| -- cgit From a9a48d6b5f00241e16e7131c997f0117bc5e9047 Mon Sep 17 00:00:00 2001 From: bfredl Date: Sat, 30 Sep 2023 10:31:55 +0200 Subject: refactor(message): simplify msg_puts_display and use batched grid updates msg_puts_display was more complex than necessary in nvim, as in nvim, it no longer talks directly with a terminal. In particular we don't need to scroll the grid before emiting the last char. The TUI already takes care of things like that, for terminals where it matters. --- test/functional/ui/popupmenu_spec.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test/functional/ui/popupmenu_spec.lua') diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index ea65cf35bd..38649a2be3 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -2439,14 +2439,14 @@ describe('builtin popupmenu', function() prefix | bef{n: word } | tex{n: }^ | - {2:-- INSERT -} | + {2:-- INSERT --}| ]]) -- can't draw the pum, but check we don't crash screen:try_resize(12,2) screen:expect([[ {1:<<<}t^ | - {2:-- INSERT -} | + {2:-- INSERT --}| ]]) -- but state is preserved, pum reappears -- cgit From 356a6728ac077fa7ec4f6fbc51eda33e025d86e0 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 17 Oct 2023 21:42:34 +0800 Subject: vim-patch:9.0.2037: A few remaining cmdline completion issues with C-E/Y (#25686) Problem: A few remaining cmdline completion issues with C-E/Y Solution: Fix cmdline completion fuzzy/Ctrl-E/Ctrl-Y/options when not used at the end Fix cmdline completion fuzzy/Ctrl-E/Ctrl-Y/options when not used at the end A few places in the cmdline completion code only works properly when the user hits Tab (or 'wildchar') at the end of the cmdline, even though it's supposed to work even in the middle of the line. For fuzzy search, `:e ++ff`, and `:set hl=`, fix completion code to make sure to use `xp_pattern_len` instead of assuming the entire `xp_pattern` is the search pattern (since it contains texts after the cursor). Fix Ctrl-E / Ctrl-Y to not jump to the end when canceling/accepting a wildmenu completion. Also, make them work even when not using `set wildoptions+=pum` as there is no drawback to doing so. (Related issue where this was brought up: vim/vim#13331) closes: vim/vim#13362 https://github.com/vim/vim/commit/209ec90b9b9bd948d76511c9cd2b17f47a97afe6 Cherry-pick ex_getln.c changes from patch 9.0.2035. Co-authored-by: Yee Cheng Chin --- test/functional/ui/popupmenu_spec.lua | 67 ++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 12 deletions(-) (limited to 'test/functional/ui/popupmenu_spec.lua') diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 38649a2be3..bfa4b7f14e 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -3096,7 +3096,7 @@ describe('builtin popupmenu', function() :sign define culhl= culhl=^ | ]]) - feed('e Xdi') + feed('e Xnamedi') screen:expect([[ | {1:~ }| @@ -3105,9 +3105,9 @@ describe('builtin popupmenu', function() {1:~ }| {1:~ }| {1:~ }| - {1:~ }{s: XdirA/ }{1: }| - {1:~ }{n: XfileA }{1: }| - :e Xdir/XdirA/^ | + {1:~ }{s: XdirA/ }{1: }| + {1:~ }{n: XfileA }{1: }| + :e Xnamedir/XdirA/^ | ]]) -- Pressing on a directory name should go into that directory @@ -3120,9 +3120,9 @@ describe('builtin popupmenu', function() {1:~ }| {1:~ }| {1:~ }| - {1:~ }{s: XdirB/ }{1: }| - {1:~ }{n: XfileB }{1: }| - :e Xdir/XdirA/XdirB/^ | + {1:~ }{s: XdirB/ }{1: }| + {1:~ }{n: XfileB }{1: }| + :e Xnamedir/XdirA/XdirB/^ | ]]) -- Pressing on a directory name should go to the parent directory @@ -3135,9 +3135,9 @@ describe('builtin popupmenu', function() {1:~ }| {1:~ }| {1:~ }| - {1:~ }{s: XdirA/ }{1: }| - {1:~ }{n: XfileA }{1: }| - :e Xdir/XdirA/^ | + {1:~ }{s: XdirA/ }{1: }| + {1:~ }{n: XfileA }{1: }| + :e Xnamedir/XdirA/^ | ]]) -- Pressing when the popup menu is displayed should list all the @@ -3511,6 +3511,49 @@ describe('builtin popupmenu', function() :sign define^ | ]]) + -- pressing to end completion should work in middle of the line too + feed(':set wildchazz') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }{s: wildchar }{1: }| + {1:~ }{n: wildcharm }{1: }| + :set wildchar^zz | + ]]) + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :set wildcha^zz | + ]]) + + -- pressing should select the current match and end completion + feed(':set wildchazz') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + :set wildchar^zz | + ]]) + feed('') -- check positioning with multibyte char in pattern @@ -3726,13 +3769,13 @@ describe('builtin popupmenu', function() end) -- oldtest: Test_wildmenu_pum_clear_entries() - it('wildoptions=pum when using Ctrl-E as wildchar vim-patch:9.0.1030', function() + it('wildoptions=pum when using odd wildchar', function() screen:try_resize(30, 10) exec([[ set wildoptions=pum set wildchar= ]]) - feed(':sign ') + feed(':sign ') screen:expect([[ | {1:~ }| -- cgit From 272ef271153b0f66410b0e59ce31e05d211b44fd Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Tue, 17 Oct 2023 22:43:42 +0800 Subject: vim-patch:9.0.2035: [security] use-after-free with wildmenu (#25687) Problem: [security] use-after-free with wildmenu Solution: properly clean up the wildmenu when exiting Fix wildchar/wildmenu/pum memory corruption with special wildchar's Currently, using `wildchar=` or `wildchar=` can lead to a memory corruption if using wildmenu+pum, or wrong states if only using wildmenu. This is due to the code only using one single place inside the cmdline process loop to perform wild menu clean up (by checking `end_wildmenu`) but there are other odd situations where the loop could have exited and we need a post-loop clean up just to be sure. If the clean up was not done you would have a stale popup menu referring to invalid memory, or if not using popup menu, incorrect status line (if `laststatus=0`). For example, if you hit `` two times when it's wildchar, there's a hard-coded behavior to exit command-line as a failsafe for user, and if you hit `` it will also exit command-line, but the clean up code would not have hit because of specialized `` handling. Fix Ctrl-E / Ctrl-Y to not cancel/accept wildmenu if they are also used for 'wildchar'/'wildcharm'. Currently they don't behave properly, and also have potentially memory unsafe behavior as the logic is currently not accounting for this situation and try to do both. (Previous patch that addressed this: vim/vim#11677) Also, correctly document Escape key behavior (double-hit it to escape) in wildchar docs as it's previously undocumented. In addition, block known invalid chars to be set in `wildchar` option, such as Ctrl-C and ``. This is just to make it clear to the user they shouldn't be set, and is not required for this bug fix. closes: vim/vim#13361 https://github.com/vim/vim/commit/8f4fb007e4d472b09ff6bed9ffa485e0c3093699 Co-authored-by: Yee Cheng Chin --- test/functional/ui/popupmenu_spec.lua | 99 +++++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 3 deletions(-) (limited to 'test/functional/ui/popupmenu_spec.lua') diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index bfa4b7f14e..6d5546e0aa 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -3768,13 +3768,16 @@ describe('builtin popupmenu', function() ]]) end) - -- oldtest: Test_wildmenu_pum_clear_entries() - it('wildoptions=pum when using odd wildchar', function() + -- oldtest: Test_wildmenu_pum_odd_wildchar() + it('wildoptions=pum with odd wildchar', function() screen:try_resize(30, 10) + -- Test odd wildchar interactions with pum. Make sure they behave properly + -- and don't lead to memory corruption due to improperly cleaned up memory. exec([[ set wildoptions=pum set wildchar= ]]) + feed(':sign ') screen:expect([[ | @@ -3788,7 +3791,97 @@ describe('builtin popupmenu', function() {1:~ }{n: unplace }{1: }| :sign define^ | ]]) - assert_alive() + + -- being a wildchar takes priority over its original functionality + feed('') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{n: define }{1: }| + {1:~ }{s: jump }{1: }| + {1:~ }{n: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{n: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign jump^ | + ]]) + + feed('') + screen:expect([[ + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]) + + -- Escape key can be wildchar too. Double- is hard-coded to escape + -- command-line, and we need to make sure to clean up properly. + command('set wildchar=') + feed(':sign ') + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{s: define }{1: }| + {1:~ }{n: jump }{1: }| + {1:~ }{n: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{n: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign define^ | + ]]) + + feed('') + screen:expect([[ + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]) + + -- can also be wildchar. however will still escape cmdline + -- and we again need to make sure we clean up properly. + command([[set wildchar=]]) + feed([[:sign ]]) + screen:expect([[ + | + {1:~ }| + {1:~ }| + {1:~ }{s: define }{1: }| + {1:~ }{n: jump }{1: }| + {1:~ }{n: list }{1: }| + {1:~ }{n: place }{1: }| + {1:~ }{n: undefine }{1: }| + {1:~ }{n: unplace }{1: }| + :sign define^ | + ]]) + + feed('') + screen:expect([[ + ^ | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]) end) end -- cgit From 4db4168aafc8ac59f5cb4def5cd7eecfb3f2ada4 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 18 Oct 2023 06:40:08 +0800 Subject: vim-patch:8.2.4497: wrong color for half of wide character next to pum scrollbar (#25693) Problem: Wrong color for half of wide character next to pum scrollbar. Solution: Redraw the screen cell with the right color. (closes vim/vim#9874) https://github.com/vim/vim/commit/35d8c2010ea6ee5c9bcfa6a8285648172b92ed83 Co-authored-by: Bram Moolenaar --- test/functional/ui/popupmenu_spec.lua | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'test/functional/ui/popupmenu_spec.lua') diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 6d5546e0aa..a6cd216d84 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -1788,6 +1788,30 @@ describe('builtin popupmenu', function() {2:-- }{5:match 1 of 3} | ]]) end) + + -- oldtest: Test_scrollbar_on_wide_char() + it('scrollbar overwrites half of double-width char below properly', function() + screen:try_resize(32, 10) + exec([[ + call setline(1, ['a', ' 啊啊啊', + \ ' 哦哦哦', + \ ' 呃呃呃']) + call setline(5, range(10)->map({i, v -> 'aa' .. v .. 'bb'})) + ]]) + feed('A') + screen:expect([[ + aa0bb^ | + {s:aa0bb }{c: }啊 | + {n:aa1bb }{c: } 哦 | + {n:aa2bb }{c: }呃呃 | + {n:aa3bb }{c: } | + {n:aa4bb }{c: } | + {n:aa5bb }{c: } | + {n:aa6bb }{s: } | + {n:aa7bb }{s: } | + {2:-- }{5:match 1 of 10} | + ]]) + end) end it('with vsplits', function() -- cgit