diff options
Diffstat (limited to 'test/functional/ui')
-rw-r--r-- | test/functional/ui/decorations_spec.lua | 508 | ||||
-rw-r--r-- | test/functional/ui/float_spec.lua | 443 | ||||
-rw-r--r-- | test/functional/ui/inccommand_spec.lua | 23 | ||||
-rw-r--r-- | test/functional/ui/mouse_spec.lua | 187 |
4 files changed, 1155 insertions, 6 deletions
diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index 4373d17890..8074f91215 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -790,3 +790,511 @@ end]] helpers.assert_alive() end) end) + +describe('decorations: virtual lines', function() + local screen, ns + before_each(function() + clear() + screen = Screen.new(50, 12) + screen:attach() + screen:set_default_attr_ids { + [1] = {bold=true, foreground=Screen.colors.Blue}; + [2] = {foreground = Screen.colors.Cyan4}; + [3] = {background = Screen.colors.Yellow1}; + [4] = {bold = true}; + [5] = {background = Screen.colors.Yellow, foreground = Screen.colors.Blue}; + [6] = {foreground = Screen.colors.Blue}; + [7] = {foreground = Screen.colors.SlateBlue}; + [8] = {background = Screen.colors.WebGray, foreground = Screen.colors.DarkBlue}; + [9] = {foreground = Screen.colors.Brown}; + } + + ns = meths.create_namespace 'test' + end) + + local example_text = [[ +if (h->n_buckets < new_n_buckets) { // expand + khkey_t *new_keys = (khkey_t *)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); + h->keys = new_keys; + if (kh_is_map && val_size) { + char *new_vals = krealloc( h->vals_buf, new_n_buckets * val_size); + h->vals_buf = new_vals; + } +}]] + + it('works with one line', function() + insert(example_text) + feed 'gg' + meths.buf_set_extmark(0, ns, 1, 33, { + virt_lines={ {{">> ", "NonText"}, {"krealloc", "Identifier"}, {": change the size of an allocation"}}}; + virt_lines_above=true; + }) + + screen:expect{grid=[[ + ^if (h->n_buckets < new_n_buckets) { // expand | + {1:>> }{2:krealloc}: change the size of an allocation | + khkey_t *new_keys = (khkey_t *)krealloc((void *)| + h->keys, new_n_buckets * sizeof(khkey_t)); | + h->keys = new_keys; | + if (kh_is_map && val_size) { | + char *new_vals = krealloc( h->vals_buf, new_n_| + buckets * val_size); | + h->vals_buf = new_vals; | + } | + } | + | + ]]} + + feed '/krealloc<cr>' + screen:expect{grid=[[ + if (h->n_buckets < new_n_buckets) { // expand | + {1:>> }{2:krealloc}: change the size of an allocation | + khkey_t *new_keys = (khkey_t *){3:^krealloc}((void *)| + h->keys, new_n_buckets * sizeof(khkey_t)); | + h->keys = new_keys; | + if (kh_is_map && val_size) { | + char *new_vals = {3:krealloc}( h->vals_buf, new_n_| + buckets * val_size); | + h->vals_buf = new_vals; | + } | + } | + /krealloc | + ]]} + + -- virtual line remains anchored to the extmark + feed 'i<cr>' + screen:expect{grid=[[ + if (h->n_buckets < new_n_buckets) { // expand | + khkey_t *new_keys = (khkey_t *) | + {1:>> }{2:krealloc}: change the size of an allocation | + {3:^krealloc}((void *)h->keys, new_n_buckets * sizeof(k| + hkey_t)); | + h->keys = new_keys; | + if (kh_is_map && val_size) { | + char *new_vals = {3:krealloc}( h->vals_buf, new_n_| + buckets * val_size); | + h->vals_buf = new_vals; | + } | + {4:-- INSERT --} | + ]]} + + feed '<esc>3+' + screen:expect{grid=[[ + if (h->n_buckets < new_n_buckets) { // expand | + khkey_t *new_keys = (khkey_t *) | + {1:>> }{2:krealloc}: change the size of an allocation | + {3:krealloc}((void *)h->keys, new_n_buckets * sizeof(k| + hkey_t)); | + h->keys = new_keys; | + if (kh_is_map && val_size) { | + ^char *new_vals = {3:krealloc}( h->vals_buf, new_n_| + buckets * val_size); | + h->vals_buf = new_vals; | + } | + | + ]]} + + meths.buf_set_extmark(0, ns, 5, 0, { + virt_lines = { {{"^^ REVIEW:", "Todo"}, {" new_vals variable seems unneccesary?", "Comment"}} }; + }) + -- TODO: what about the cursor?? + screen:expect{grid=[[ + if (h->n_buckets < new_n_buckets) { // expand | + khkey_t *new_keys = (khkey_t *) | + {3:krealloc}((void *)h->keys, new_n_buckets * sizeof(k| + hkey_t)); | + h->keys = new_keys; | + if (kh_is_map && val_size) { | + char *new_vals = {3:krealloc}( h->vals_buf, new_n_| + buck^ets * val_size); | + {5:^^ REVIEW:}{6: new_vals variable seems unneccesary?} | + h->vals_buf = new_vals; | + } | + | + ]]} + + meths.buf_clear_namespace(0, ns, 0, -1) + screen:expect{grid=[[ + if (h->n_buckets < new_n_buckets) { // expand | + khkey_t *new_keys = (khkey_t *) | + {3:krealloc}((void *)h->keys, new_n_buckets * sizeof(k| + hkey_t)); | + h->keys = new_keys; | + if (kh_is_map && val_size) { | + char *new_vals = {3:krealloc}( h->vals_buf, new_n_| + buck^ets * val_size); | + h->vals_buf = new_vals; | + } | + } | + | + ]]} + end) + + + it('works with text at the beginning of the buffer', function() + insert(example_text) + feed 'gg' + + screen:expect{grid=[[ + ^if (h->n_buckets < new_n_buckets) { // expand | + khkey_t *new_keys = (khkey_t *)krealloc((void *)| + h->keys, new_n_buckets * sizeof(khkey_t)); | + h->keys = new_keys; | + if (kh_is_map && val_size) { | + char *new_vals = krealloc( h->vals_buf, new_n_| + buckets * val_size); | + h->vals_buf = new_vals; | + } | + } | + {1:~ }| + | + ]]} + + meths.buf_set_extmark(0, ns, 0, 0, { + virt_lines={ + {{"refactor(khash): ", "Special"}, {"take size of values as parameter"}}; + {{"Author: Dev Devsson, "}, {"Tue Aug 31 10:13:37 2021", "Comment"}}; + }; + virt_lines_above=true; + right_gravity=false; + }) + + -- placing virt_text on topline does not automatically cause a scroll + screen:expect{grid=[[ + ^if (h->n_buckets < new_n_buckets) { // expand | + khkey_t *new_keys = (khkey_t *)krealloc((void *)| + h->keys, new_n_buckets * sizeof(khkey_t)); | + h->keys = new_keys; | + if (kh_is_map && val_size) { | + char *new_vals = krealloc( h->vals_buf, new_n_| + buckets * val_size); | + h->vals_buf = new_vals; | + } | + } | + {1:~ }| + | + ]], unchanged=true} + + feed '<c-b>' + screen:expect{grid=[[ + {7:refactor(khash): }take size of values as parameter | + Author: Dev Devsson, {6:Tue Aug 31 10:13:37 2021} | + ^if (h->n_buckets < new_n_buckets) { // expand | + khkey_t *new_keys = (khkey_t *)krealloc((void *)| + h->keys, new_n_buckets * sizeof(khkey_t)); | + h->keys = new_keys; | + if (kh_is_map && val_size) { | + char *new_vals = krealloc( h->vals_buf, new_n_| + buckets * val_size); | + h->vals_buf = new_vals; | + } | + | + ]]} + end) + + it('works with text et the end of the buffer', function() + insert(example_text) + feed 'G' + + screen:expect{grid=[[ + if (h->n_buckets < new_n_buckets) { // expand | + khkey_t *new_keys = (khkey_t *)krealloc((void *)| + h->keys, new_n_buckets * sizeof(khkey_t)); | + h->keys = new_keys; | + if (kh_is_map && val_size) { | + char *new_vals = krealloc( h->vals_buf, new_n_| + buckets * val_size); | + h->vals_buf = new_vals; | + } | + ^} | + {1:~ }| + | + ]]} + + local id = meths.buf_set_extmark(0, ns, 7, 0, { + virt_lines={{{"Grugg"}}}; + right_gravity=false; + }) + + screen:expect{grid=[[ + if (h->n_buckets < new_n_buckets) { // expand | + khkey_t *new_keys = (khkey_t *)krealloc((void *)| + h->keys, new_n_buckets * sizeof(khkey_t)); | + h->keys = new_keys; | + if (kh_is_map && val_size) { | + char *new_vals = krealloc( h->vals_buf, new_n_| + buckets * val_size); | + h->vals_buf = new_vals; | + } | + ^} | + Grugg | + | + ]]} + + meths.buf_del_extmark(0, ns, id) + screen:expect{grid=[[ + if (h->n_buckets < new_n_buckets) { // expand | + khkey_t *new_keys = (khkey_t *)krealloc((void *)| + h->keys, new_n_buckets * sizeof(khkey_t)); | + h->keys = new_keys; | + if (kh_is_map && val_size) { | + char *new_vals = krealloc( h->vals_buf, new_n_| + buckets * val_size); | + h->vals_buf = new_vals; | + } | + ^} | + {1:~ }| + | + ]]} + end) + + it('works with a block scrolling up', function() + screen:try_resize(30, 7) + insert("aa\nbb\ncc\ndd\nee\nff\ngg\nhh") + feed 'gg' + + meths.buf_set_extmark(0, ns, 6, 0, { + virt_lines={ + {{"they see me"}}; + {{"scrolling", "Special"}}; + {{"they"}}; + {{"hatin'", "Special"}}; + }; + }) + + screen:expect{grid=[[ + ^aa | + bb | + cc | + dd | + ee | + ff | + | + ]]} + + feed '<c-e>' + screen:expect{grid=[[ + ^bb | + cc | + dd | + ee | + ff | + gg | + | + ]]} + + feed '<c-e>' + screen:expect{grid=[[ + ^cc | + dd | + ee | + ff | + gg | + they see me | + | + ]]} + + feed '<c-e>' + screen:expect{grid=[[ + ^dd | + ee | + ff | + gg | + they see me | + {7:scrolling} | + | + ]]} + + feed '<c-e>' + screen:expect{grid=[[ + ^ee | + ff | + gg | + they see me | + {7:scrolling} | + they | + | + ]]} + + feed '<c-e>' + screen:expect{grid=[[ + ^ff | + gg | + they see me | + {7:scrolling} | + they | + {7:hatin'} | + | + ]]} + + feed '<c-e>' + screen:expect{grid=[[ + ^gg | + they see me | + {7:scrolling} | + they | + {7:hatin'} | + hh | + | + ]]} + + feed '<c-e>' + screen:expect{grid=[[ + they see me | + {7:scrolling} | + they | + {7:hatin'} | + ^hh | + {1:~ }| + | + ]]} + + feed '<c-e>' + screen:expect{grid=[[ + {7:scrolling} | + they | + {7:hatin'} | + ^hh | + {1:~ }| + {1:~ }| + | + ]]} + + feed '<c-e>' + screen:expect{grid=[[ + they | + {7:hatin'} | + ^hh | + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]} + + feed '<c-e>' + screen:expect{grid=[[ + {7:hatin'} | + ^hh | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]} + + feed '<c-e>' + screen:expect{grid=[[ + ^hh | + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + {1:~ }| + | + ]]} + end) + + it('works with sign and numbercolumns', function() + insert(example_text) + feed 'gg' + command 'set number signcolumn=yes' + screen:expect{grid=[[ + {8: }{9: 1 }^if (h->n_buckets < new_n_buckets) { // expan| + {8: }{9: }d | + {8: }{9: 2 } khkey_t *new_keys = (khkey_t *)krealloc((v| + {8: }{9: }oid *)h->keys, new_n_buckets * sizeof(khkey_| + {8: }{9: }t)); | + {8: }{9: 3 } h->keys = new_keys; | + {8: }{9: 4 } if (kh_is_map && val_size) { | + {8: }{9: 5 } char *new_vals = krealloc( h->vals_buf, | + {8: }{9: }new_n_buckets * val_size); | + {8: }{9: 6 } h->vals_buf = new_vals; | + {8: }{9: 7 } } | + | + ]]} + + meths.buf_set_extmark(0, ns, 2, 0, { + virt_lines={ + {{"Some special", "Special"}}; + {{"remark about codes", "Comment"}}; + }; + }) + + screen:expect{grid=[[ + {8: }{9: 1 }^if (h->n_buckets < new_n_buckets) { // expan| + {8: }{9: }d | + {8: }{9: 2 } khkey_t *new_keys = (khkey_t *)krealloc((v| + {8: }{9: }oid *)h->keys, new_n_buckets * sizeof(khkey_| + {8: }{9: }t)); | + {8: }{9: 3 } h->keys = new_keys; | + {8: }{9: }{7:Some special} | + {8: }{9: }{6:remark about codes} | + {8: }{9: 4 } if (kh_is_map && val_size) { | + {8: }{9: 5 } char *new_vals = krealloc( h->vals_buf, | + {8: }{9: }new_n_buckets * val_size); | + | + ]]} + + meths.buf_set_extmark(0, ns, 2, 0, { + virt_lines={ + {{"Some special", "Special"}}; + {{"remark about codes", "Comment"}}; + }; + virt_lines_leftcol=true; + }) + screen:expect{grid=[[ + {8: }{9: 1 }^if (h->n_buckets < new_n_buckets) { // expan| + {8: }{9: }d | + {8: }{9: 2 } khkey_t *new_keys = (khkey_t *)krealloc((v| + {8: }{9: }oid *)h->keys, new_n_buckets * sizeof(khkey_| + {8: }{9: }t)); | + {8: }{9: 3 } h->keys = new_keys; | + {7:Some special} | + {6:remark about codes} | + {8: }{9: 4 } if (kh_is_map && val_size) { | + {8: }{9: 5 } char *new_vals = krealloc( h->vals_buf, | + {8: }{9: }new_n_buckets * val_size); | + | + ]]} + end) + + + it('works with hard tabs', function() + insert(example_text) + feed 'gg' + meths.buf_set_extmark(0, ns, 1, 0, { + virt_lines={ {{">>", "NonText"}, {"\tvery\ttabby", "Identifier"}, {"text\twith\ttabs"}}}; + }) + screen:expect{grid=[[ + ^if (h->n_buckets < new_n_buckets) { // expand | + khkey_t *new_keys = (khkey_t *)krealloc((void *)| + h->keys, new_n_buckets * sizeof(khkey_t)); | + {1:>>}{2: very tabby}text with tabs | + h->keys = new_keys; | + if (kh_is_map && val_size) { | + char *new_vals = krealloc( h->vals_buf, new_n_| + buckets * val_size); | + h->vals_buf = new_vals; | + } | + } | + | + ]]} + + command 'set tabstop=4' + screen:expect{grid=[[ + ^if (h->n_buckets < new_n_buckets) { // expand | + khkey_t *new_keys = (khkey_t *)krealloc((void *)| + h->keys, new_n_buckets * sizeof(khkey_t)); | + {1:>>}{2: very tabby}text with tabs | + h->keys = new_keys; | + if (kh_is_map && val_size) { | + char *new_vals = krealloc( h->vals_buf, new_n_| + buckets * val_size); | + h->vals_buf = new_vals; | + } | + } | + | + ]]} + end) + +end) diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua index ccf5f963d1..6c2c4b398a 100644 --- a/test/functional/ui/float_spec.lua +++ b/test/functional/ui/float_spec.lua @@ -46,6 +46,7 @@ describe('float window', function() [24] = {foreground = Screen.colors.Black, background = Screen.colors.Grey80}; [25] = {blend = 100, background = Screen.colors.Gray0}; [26] = {blend = 80, background = Screen.colors.Gray0}; + [27] = {background = Screen.colors.LightGray}; } it('behavior', function() @@ -109,6 +110,21 @@ describe('float window', function() assert_alive() end) + it('closed immediately by autocmd after win_enter #15548', function() + eq('Error executing lua: [string "<nvim>"]:0: Window was closed immediately', + pcall_err(exec_lua, [[ + vim.cmd "autocmd BufLeave * ++once quit!" + local buf = vim.api.nvim_create_buf(true, true) + vim.api.nvim_open_win(buf, true, { + relative = "win", + row = 0, col = 0, + width = 1, height = 1, + noautocmd = false, + }) + ]])) + assert_alive() + end) + it('opened with correct height', function() local height = exec_lua([[ vim.api.nvim_set_option("winheight", 20) @@ -1514,7 +1530,7 @@ describe('float window', function() it('API has proper error messages', function() local buf = meths.create_buf(false,false) - eq("Invalid key 'bork'", + eq("Invalid key: 'bork'", pcall_err(meths.open_win,buf, false, {width=20,height=2,bork=true})) eq("'win' key is only valid with relative='win'", pcall_err(meths.open_win,buf, false, {width=20,height=2,relative='editor',row=0,col=0,win=0})) @@ -1527,13 +1543,15 @@ describe('float window', function() eq("'relative' requires 'row'/'col' or 'bufpos'", pcall_err(meths.open_win,buf, false, {width=20,height=2,relative='editor'})) eq("'width' key must be a positive Integer", - pcall_err(meths.open_win,buf, false, {width=-1,height=2,relative='editor'})) + pcall_err(meths.open_win,buf, false, {width=-1,height=2,relative='editor', row=0, col=0})) eq("'height' key must be a positive Integer", - pcall_err(meths.open_win,buf, false, {width=20,height=-1,relative='editor'})) + pcall_err(meths.open_win,buf, false, {width=20,height=-1,relative='editor', row=0, col=0})) eq("'height' key must be a positive Integer", - pcall_err(meths.open_win,buf, false, {width=20,height=0,relative='editor'})) - eq("Must specify 'width' and 'height'", - pcall_err(meths.open_win,buf, false, {relative='editor'})) + pcall_err(meths.open_win,buf, false, {width=20,height=0,relative='editor', row=0, col=0})) + eq("Must specify 'width'", + pcall_err(meths.open_win,buf, false, {relative='editor', row=0, col=0})) + eq("Must specify 'height'", + pcall_err(meths.open_win,buf, false, {relative='editor', row=0, col=0, width=2})) end) it('can be placed relative window or cursor', function() @@ -1866,6 +1884,293 @@ describe('float window', function() end end) + it('always anchor to corner including border', function() + screen:try_resize(40,13) + meths.buf_set_lines(0, 0, -1, true, {'just some example text', 'some more example text'}) + feed('ggeee') + command('below split') + if multigrid then + screen:expect([[ + ## grid 1 + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + {5:[No Name] [+] }| + [4:----------------------------------------]| + [4:----------------------------------------]| + [4:----------------------------------------]| + [4:----------------------------------------]| + [4:----------------------------------------]| + {4:[No Name] [+] }| + [3:----------------------------------------]| + ## grid 2 + just some example text | + some more example text | + {0:~ }| + {0:~ }| + {0:~ }| + ## grid 3 + | + ## grid 4 + just some exampl^e text | + some more example text | + {0:~ }| + {0:~ }| + {0:~ }| + ]]) + else + screen:expect([[ + just some example text | + some more example text | + {0:~ }| + {0:~ }| + {0:~ }| + {5:[No Name] [+] }| + just some exampl^e text | + some more example text | + {0:~ }| + {0:~ }| + {0:~ }| + {4:[No Name] [+] }| + | + ]]) + end + + local buf = meths.create_buf(false, false) + meths.buf_set_lines(buf, 0, -1, true, {' halloj! ', + ' BORDAA '}) + local win = meths.open_win(buf, false, {relative='cursor', width=9, height=2, row=1, col=-2, border="double"}) + + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + {5:[No Name] [+] }| + [4:----------------------------------------]| + [4:----------------------------------------]| + [4:----------------------------------------]| + [4:----------------------------------------]| + [4:----------------------------------------]| + {4:[No Name] [+] }| + [3:----------------------------------------]| + ## grid 2 + just some example text | + some more example text | + {0:~ }| + {0:~ }| + {0:~ }| + ## grid 3 + | + ## grid 4 + just some exampl^e text | + some more example text | + {0:~ }| + {0:~ }| + {0:~ }| + ## grid 6 + {5:╔═════════╗}| + {5:║}{1: halloj! }{5:║}| + {5:║}{1: BORDAA }{5:║}| + {5:╚═════════╝}| + ]], float_pos={ + [6] = {{id = 1003}, "NW", 4, 1, 14, true} + }} + else + screen:expect([[ + just some example text | + some more example text | + {0:~ }| + {0:~ }| + {0:~ }| + {5:[No Name] [+] }| + just some exampl^e text | + some more exam{5:╔═════════╗} | + {0:~ }{5:║}{1: halloj! }{5:║}{0: }| + {0:~ }{5:║}{1: BORDAA }{5:║}{0: }| + {0:~ }{5:╚═════════╝}{0: }| + {4:[No Name] [+] }| + | + ]]) + end + + meths.win_set_config(win, {relative='cursor', row=0, col=-2, anchor='NE'}) + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + {5:[No Name] [+] }| + [4:----------------------------------------]| + [4:----------------------------------------]| + [4:----------------------------------------]| + [4:----------------------------------------]| + [4:----------------------------------------]| + {4:[No Name] [+] }| + [3:----------------------------------------]| + ## grid 2 + just some example text | + some more example text | + {0:~ }| + {0:~ }| + {0:~ }| + ## grid 3 + | + ## grid 4 + just some exampl^e text | + some more example text | + {0:~ }| + {0:~ }| + {0:~ }| + ## grid 6 + {5:╔═════════╗}| + {5:║}{1: halloj! }{5:║}| + {5:║}{1: BORDAA }{5:║}| + {5:╚═════════╝}| + ]], float_pos={ + [6] = {{id = 1003}, "NE", 4, 0, 14, true} + }} + else + screen:expect([[ + just some example text | + some more example text | + {0:~ }| + {0:~ }| + {0:~ }| + {5:[No Name] [+] }| + jus{5:╔═════════╗}pl^e text | + som{5:║}{1: halloj! }{5:║}ple text | + {0:~ }{5:║}{1: BORDAA }{5:║}{0: }| + {0:~ }{5:╚═════════╝}{0: }| + {0:~ }| + {4:[No Name] [+] }| + | + ]]) + end + + meths.win_set_config(win, {relative='cursor', row=1, col=-2, anchor='SE'}) + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + {5:[No Name] [+] }| + [4:----------------------------------------]| + [4:----------------------------------------]| + [4:----------------------------------------]| + [4:----------------------------------------]| + [4:----------------------------------------]| + {4:[No Name] [+] }| + [3:----------------------------------------]| + ## grid 2 + just some example text | + some more example text | + {0:~ }| + {0:~ }| + {0:~ }| + ## grid 3 + | + ## grid 4 + just some exampl^e text | + some more example text | + {0:~ }| + {0:~ }| + {0:~ }| + ## grid 6 + {5:╔═════════╗}| + {5:║}{1: halloj! }{5:║}| + {5:║}{1: BORDAA }{5:║}| + {5:╚═════════╝}| + ]], float_pos={ + [6] = {{id = 1003}, "SE", 4, 1, 14, true} + }} + else + screen:expect([[ + just some example text | + some more example text | + {0:~ }| + {0:~ }{5:╔═════════╗}{0: }| + {0:~ }{5:║}{1: halloj! }{5:║}{0: }| + {5:[No║}{1: BORDAA }{5:║ }| + jus{5:╚═════════╝}pl^e text | + some more example text | + {0:~ }| + {0:~ }| + {0:~ }| + {4:[No Name] [+] }| + | + ]]) + end + + meths.win_set_config(win, {relative='cursor', row=0, col=-2, anchor='SW'}) + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + {5:[No Name] [+] }| + [4:----------------------------------------]| + [4:----------------------------------------]| + [4:----------------------------------------]| + [4:----------------------------------------]| + [4:----------------------------------------]| + {4:[No Name] [+] }| + [3:----------------------------------------]| + ## grid 2 + just some example text | + some more example text | + {0:~ }| + {0:~ }| + {0:~ }| + ## grid 3 + | + ## grid 4 + just some exampl^e text | + some more example text | + {0:~ }| + {0:~ }| + {0:~ }| + ## grid 6 + {5:╔═════════╗}| + {5:║}{1: halloj! }{5:║}| + {5:║}{1: BORDAA }{5:║}| + {5:╚═════════╝}| + ]], float_pos={ + [6] = {{id = 1003}, "SW", 4, 0, 14, true} + }} + else + screen:expect([[ + just some example text | + some more example text | + {0:~ }{5:╔═════════╗}{0: }| + {0:~ }{5:║}{1: halloj! }{5:║}{0: }| + {0:~ }{5:║}{1: BORDAA }{5:║}{0: }| + {5:[No Name] [+] ╚═════════╝ }| + just some exampl^e text | + some more example text | + {0:~ }| + {0:~ }| + {0:~ }| + {4:[No Name] [+] }| + | + ]]) + end + end) + it('can be placed relative text in a window', function() screen:try_resize(30,5) local firstwin = meths.get_current_win().id @@ -5870,6 +6175,132 @@ describe('float window', function() end) end) + it("left drag changes visual selection in float window", function() + local buf = meths.create_buf(false,false) + meths.buf_set_lines(buf, 0, -1, true, {'foo', 'bar'}) + meths.open_win(buf, false, {relative='editor', width=20, height=3, row=2, col=5}) + if multigrid then + screen:expect{grid=[[ + ## grid 1 + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [3:----------------------------------------]| + ## grid 2 + ^ | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + ## grid 3 + | + ## grid 5 + {1:foo }| + {1:bar }| + {2:~ }| + ]], float_pos={ + [5] = {{id = 1002}, "NW", 1, 2, 5, true, 50}; + }, win_viewport={ + [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1}; + [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 2}; + }} + meths.input_mouse('left', 'press', '', 5, 0, 0) + screen:expect{grid=[[ + ## grid 1 + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [3:----------------------------------------]| + ## grid 2 + | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + ## grid 3 + | + ## grid 5 + {1:^foo }| + {1:bar }| + {2:~ }| + ]], float_pos={ + [5] = {{id = 1002}, "NW", 1, 2, 5, true, 50}; + }, win_viewport={ + [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1}; + [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 0, curcol = 0, linecount = 2}; + }} + meths.input_mouse('left', 'drag', '', 5, 1, 2) + screen:expect{grid=[[ + ## grid 1 + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [2:----------------------------------------]| + [3:----------------------------------------]| + ## grid 2 + | + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + {0:~ }| + ## grid 3 + {3:-- VISUAL --} | + ## grid 5 + {27:foo}{1: }| + {27:ba}{1:^r }| + {2:~ }| + ]], float_pos={ + [5] = {{id = 1002}, "NW", 1, 2, 5, true, 50}; + }, win_viewport={ + [2] = {win = {id = 1000}, topline = 0, botline = 2, curline = 0, curcol = 0, linecount = 1}; + [5] = {win = {id = 1002}, topline = 0, botline = 3, curline = 1, curcol = 2, linecount = 2}; + }} + else + screen:expect{grid=[[ + ^ | + {0:~ }| + {0:~ }{1:foo }{0: }| + {0:~ }{1:bar }{0: }| + {0:~ }{2:~ }{0: }| + {0:~ }| + | + ]]} + + meths.input_mouse('left', 'press', '', 0, 2, 5) + screen:expect{grid=[[ + | + {0:~ }| + {0:~ }{1:^foo }{0: }| + {0:~ }{1:bar }{0: }| + {0:~ }{2:~ }{0: }| + {0:~ }| + | + ]]} + + meths.input_mouse('left', 'drag', '', 0, 3, 7) + screen:expect{grid=[[ + | + {0:~ }| + {0:~ }{27:foo}{1: }{0: }| + {0:~ }{27:ba}{1:^r }{0: }| + {0:~ }{2:~ }{0: }| + {0:~ }| + {3:-- VISUAL --} | + ]]} + end + end) + it("'winblend' option", function() screen:try_resize(50,9) screen:set_default_attr_ids({ diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua index 712c1f377a..b6e2f2311f 100644 --- a/test/functional/ui/inccommand_spec.lua +++ b/test/functional/ui/inccommand_spec.lua @@ -1487,6 +1487,29 @@ describe("inccommand=nosplit", function() ]]) eq(eval('v:null'), eval('v:exiting')) end) + + it("does not break bar-separated command #8796", function() + source([[ + function! F() + if v:false | return | endif + endfun + ]]) + command('call timer_start(10, {-> F()}, {"repeat":-1})') + feed(':%s/') + sleep(20) -- Allow some timer activity. + screen:expect([[ + Inc substitution on | + two lines | + Inc substitution on | + two lines | + | + {15:~ }| + {15:~ }| + {15:~ }| + {15:~ }| + :%s/^ | + ]]) + end) end) describe(":substitute, 'inccommand' with a failing expression", function() diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua index 7bca741ae3..baacef358f 100644 --- a/test/functional/ui/mouse_spec.lua +++ b/test/functional/ui/mouse_spec.lua @@ -585,6 +585,69 @@ describe('ui/mouse/input', function() ]]) end) + it('left drag changes visual selection in split layout', function() + screen:try_resize(53,14) + command('set mouse=a') + command('vsplit') + command('wincmd l') + command('below split') + command('enew') + feed('ifoo\nbar<esc>') + + screen:expect{grid=[[ + testing {4:│}testing | + mouse {4:│}mouse | + support and selection {4:│}support and selection | + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│[No Name] [+] }| + {0:~ }{4:│}foo{0:$} | + {0:~ }{4:│}ba^r{0:$} | + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {4:[No Name] [+] }{5:[No Name] [+] }| + | + ]]} + + meths.input_mouse('left', 'press', '', 0, 6, 27) + screen:expect{grid=[[ + testing {4:│}testing | + mouse {4:│}mouse | + support and selection {4:│}support and selection | + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│[No Name] [+] }| + {0:~ }{4:│}^foo{0:$} | + {0:~ }{4:│}bar{0:$} | + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {4:[No Name] [+] }{5:[No Name] [+] }| + | + ]]} + meths.input_mouse('left', 'drag', '', 0, 7, 30) + + screen:expect{grid=[[ + testing {4:│}testing | + mouse {4:│}mouse | + support and selection {4:│}support and selection | + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│[No Name] [+] }| + {0:~ }{4:│}{1:foo}{3:$} | + {0:~ }{4:│}{1:bar}{0:^$} | + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {0:~ }{4:│}{0:~ }| + {4:[No Name] [+] }{5:[No Name] [+] }| + {2:-- VISUAL --} | + ]]} + end) + it('two clicks will select the word and enter VISUAL', function() feed('<LeftMouse><2,2><LeftMouse><2,2>') screen:expect([[ @@ -1384,4 +1447,128 @@ describe('ui/mouse/input', function() end) -- level 3 - wrapped end) + + it('getmousepos works correctly', function() + local winwidth = meths.get_option('winwidth') + -- Set winwidth=1 so that window sizes don't change. + meths.set_option('winwidth', 1) + command('tabedit') + local tabpage = meths.get_current_tabpage() + insert('hello') + command('vsplit') + local opts = { + relative='editor', + width=12, + height=1, + col=8, + row=1, + anchor='NW', + style='minimal', + border='single', + focusable=1 + } + local float = meths.open_win(meths.get_current_buf(), false, opts) + command('redraw') + local lines = meths.get_option('lines') + local columns = meths.get_option('columns') + + -- Test that screenrow and screencol are set properly for all positions. + for row = 0, lines - 1 do + for col = 0, columns - 1 do + -- Skip the X button that would close the tab. + if row ~= 0 or col ~= columns - 1 then + meths.input_mouse('left', 'press', '', 0, row, col) + meths.set_current_tabpage(tabpage) + local mousepos = funcs.getmousepos() + eq(row + 1, mousepos.screenrow) + eq(col + 1, mousepos.screencol) + -- All other values should be 0 when clicking on the command line. + if row == lines - 1 then + eq(0, mousepos.winid) + eq(0, mousepos.winrow) + eq(0, mousepos.wincol) + eq(0, mousepos.line) + eq(0, mousepos.column) + end + end + end + end + + -- Test that mouse position values are properly set for the floating window + -- with a border. 1 is added to the height and width to account for the + -- border. + for win_row = 0, opts.height + 1 do + for win_col = 0, opts.width + 1 do + local row = win_row + opts.row + local col = win_col + opts.col + meths.input_mouse('left', 'press', '', 0, row, col) + local mousepos = funcs.getmousepos() + eq(float.id, mousepos.winid) + eq(win_row + 1, mousepos.winrow) + eq(win_col + 1, mousepos.wincol) + local line = 0 + local column = 0 + if win_row > 0 and win_row < opts.height + 1 + and win_col > 0 and win_col < opts.width + 1 then + -- Because of border, win_row and win_col don't need to be + -- incremented by 1. + line = math.min(win_row, funcs.line('$')) + column = math.min(win_col, #funcs.getline(line) + 1) + end + eq(line, mousepos.line) + eq(column, mousepos.column) + end + end + + -- Test that mouse position values are properly set for the floating + -- window, after removing the border. + opts.border = 'none' + meths.win_set_config(float, opts) + command('redraw') + for win_row = 0, opts.height - 1 do + for win_col = 0, opts.width - 1 do + local row = win_row + opts.row + local col = win_col + opts.col + meths.input_mouse('left', 'press', '', 0, row, col) + local mousepos = funcs.getmousepos() + eq(float.id, mousepos.winid) + eq(win_row + 1, mousepos.winrow) + eq(win_col + 1, mousepos.wincol) + local line = math.min(win_row + 1, funcs.line('$')) + local column = math.min(win_col + 1, #funcs.getline(line) + 1) + eq(line, mousepos.line) + eq(column, mousepos.column) + end + end + + -- Test that mouse position values are properly set for ordinary windows. + -- Set the float to be unfocusable instead of closing, to additionally test + -- that getmousepos does not consider unfocusable floats. (see discussion + -- in PR #14937 for details). + opts.focusable = false + meths.win_set_config(float, opts) + command('redraw') + for nr = 1, 2 do + for win_row = 0, funcs.winheight(nr) - 1 do + for win_col = 0, funcs.winwidth(nr) - 1 do + local row = win_row + funcs.win_screenpos(nr)[1] - 1 + local col = win_col + funcs.win_screenpos(nr)[2] - 1 + meths.input_mouse('left', 'press', '', 0, row, col) + local mousepos = funcs.getmousepos() + eq(funcs.win_getid(nr), mousepos.winid) + eq(win_row + 1, mousepos.winrow) + eq(win_col + 1, mousepos.wincol) + local line = math.min(win_row + 1, funcs.line('$')) + local column = math.min(win_col + 1, #funcs.getline(line) + 1) + eq(line, mousepos.line) + eq(column, mousepos.column) + end + end + end + + -- Restore state and release mouse. + command('tabclose!') + meths.set_option('winwidth', winwidth) + meths.input_mouse('left', 'release', '', 0, 0, 0) + end) end) |