diff options
Diffstat (limited to 'test/functional/editor')
-rw-r--r-- | test/functional/editor/K_spec.lua | 25 | ||||
-rw-r--r-- | test/functional/editor/completion_spec.lua | 589 | ||||
-rw-r--r-- | test/functional/editor/ctrl_c_spec.lua | 40 | ||||
-rw-r--r-- | test/functional/editor/fold_spec.lua | 226 | ||||
-rw-r--r-- | test/functional/editor/jump_spec.lua | 310 | ||||
-rw-r--r-- | test/functional/editor/lang_spec.lua | 46 | ||||
-rw-r--r-- | test/functional/editor/langmap_spec.lua | 44 | ||||
-rw-r--r-- | test/functional/editor/macro_spec.lua | 102 | ||||
-rw-r--r-- | test/functional/editor/mark_spec.lua | 426 | ||||
-rw-r--r-- | test/functional/editor/meta_key_spec.lua | 8 | ||||
-rw-r--r-- | test/functional/editor/mode_cmdline_spec.lua | 62 | ||||
-rw-r--r-- | test/functional/editor/mode_insert_spec.lua | 49 | ||||
-rw-r--r-- | test/functional/editor/mode_normal_spec.lua | 22 | ||||
-rw-r--r-- | test/functional/editor/put_spec.lua | 361 | ||||
-rw-r--r-- | test/functional/editor/search_spec.lua | 7 | ||||
-rw-r--r-- | test/functional/editor/tabpage_spec.lua | 81 | ||||
-rw-r--r-- | test/functional/editor/undo_spec.lua | 38 |
17 files changed, 1343 insertions, 1093 deletions
diff --git a/test/functional/editor/K_spec.lua b/test/functional/editor/K_spec.lua index b964fb3467..1fbdd1c142 100644 --- a/test/functional/editor/K_spec.lua +++ b/test/functional/editor/K_spec.lua @@ -1,6 +1,6 @@ local helpers = require('test.functional.helpers')(after_each) -local eq, clear, eval, feed, meths, retry = - helpers.eq, helpers.clear, helpers.eval, helpers.feed, helpers.meths, helpers.retry +local eq, clear, eval, feed, api, retry = + helpers.eq, helpers.clear, helpers.eval, helpers.feed, helpers.api, helpers.retry describe('K', function() local test_file = 'K_spec_out' @@ -30,13 +30,15 @@ describe('K', function() set keywordprg=echo\ fnord>>]]) -- K on the text "K_spec_out" resolves to `!echo fnord >> K_spec_out`. - feed('i'..test_file..'<ESC>K') - retry(nil, nil, function() eq(1, eval('filereadable("'..test_file..'")')) end) - eq({'fnord'}, eval("readfile('"..test_file.."')")) + feed('i' .. test_file .. '<ESC>K') + retry(nil, nil, function() + eq(1, eval('filereadable("' .. test_file .. '")')) + end) + eq({ 'fnord' }, eval("readfile('" .. test_file .. "')")) -- Confirm that Neovim is still in terminal mode after K is pressed (#16692). - helpers.sleep(500) + vim.uv.sleep(500) eq('t', eval('mode()')) - feed('<space>') -- Any key, not just <space>, can be used here to escape. + feed('<space>') -- Any key, not just <space>, can be used here to escape. eq('n', eval('mode()')) end) @@ -48,7 +50,7 @@ describe('K', function() -- Confirm that an arbitrary keypress doesn't escape (i.e., the process is -- still running). If the process were no longer running, an arbitrary -- keypress would escape. - helpers.sleep(500) + vim.uv.sleep(500) feed('<space>') eq('t', eval('mode()')) -- Confirm that <esc> kills the buffer for the running command. @@ -59,10 +61,9 @@ describe('K', function() end) it('empty string falls back to :help #19298', function() - meths.set_option_value('keywordprg', '', {}) - meths.buf_set_lines(0, 0, -1, true, {'doesnotexist'}) + api.nvim_set_option_value('keywordprg', '', {}) + api.nvim_buf_set_lines(0, 0, -1, true, { 'doesnotexist' }) feed('K') - eq('E149: Sorry, no help for doesnotexist', meths.get_vvar('errmsg')) + eq('E149: Sorry, no help for doesnotexist', api.nvim_get_vvar('errmsg')) end) - end) diff --git a/test/functional/editor/completion_spec.lua b/test/functional/editor/completion_spec.lua index cbaf401f06..33d0d47499 100644 --- a/test/functional/editor/completion_spec.lua +++ b/test/functional/editor/completion_spec.lua @@ -4,10 +4,9 @@ local assert_alive = helpers.assert_alive local clear, feed = helpers.clear, helpers.feed local eval, eq, neq = helpers.eval, helpers.eq, helpers.neq local feed_command, source, expect = helpers.feed_command, helpers.source, helpers.expect -local funcs = helpers.funcs -local curbufmeths = helpers.curbufmeths +local fn = helpers.fn local command = helpers.command -local meths = helpers.meths +local api = helpers.api local poke_eventloop = helpers.poke_eventloop describe('completion', function() @@ -18,17 +17,17 @@ describe('completion', function() screen = Screen.new(60, 8) screen:attach() screen:set_default_attr_ids({ - [0] = {bold=true, foreground=Screen.colors.Blue}, - [1] = {background = Screen.colors.LightMagenta}, - [2] = {background = Screen.colors.Grey}, - [3] = {bold = true}, - [4] = {bold = true, foreground = Screen.colors.SeaGreen}, - [5] = {foreground = Screen.colors.Red}, - [6] = {background = Screen.colors.Black}, - [7] = {foreground = Screen.colors.White, background = Screen.colors.Red}, - [8] = {reverse = true}, - [9] = {bold = true, reverse = true}, - [10] = {foreground = Screen.colors.Grey0, background = Screen.colors.Yellow}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { background = Screen.colors.LightMagenta }, + [2] = { background = Screen.colors.Grey }, + [3] = { bold = true }, + [4] = { bold = true, foreground = Screen.colors.SeaGreen }, + [5] = { foreground = Screen.colors.Red }, + [6] = { background = Screen.colors.Black }, + [7] = { foreground = Screen.colors.White, background = Screen.colors.Red }, + [8] = { reverse = true }, + [9] = { bold = true, reverse = true }, + [10] = { foreground = Screen.colors.Grey0, background = Screen.colors.Yellow }, }) end) @@ -41,22 +40,14 @@ describe('completion', function() screen:expect([[ foo | foo^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- Keyword Local completion (^N^P) The only match} | ]]) feed('<C-e>') screen:expect([[ foo | ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- INSERT --} | ]]) feed('<ESC>') @@ -65,9 +56,10 @@ describe('completion', function() it('returns expected dict in normal completion', function() feed('ifoo<ESC>o<C-x><C-n>') eq('foo', eval('getline(2)')) - eq({word = 'foo', abbr = '', menu = '', - info = '', kind = '', user_data = ''}, - eval('v:completed_item')) + eq( + { word = 'foo', abbr = '', menu = '', info = '', kind = '', user_data = '' }, + eval('v:completed_item') + ) end) it('is readonly', function() screen:try_resize(80, 8) @@ -112,15 +104,17 @@ describe('completion', function() foo^ | {2:bar foobaz baz }{0: }| {1:abbr kind menu }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- Omni completion (^O^N^P) }{4:match 1 of 2} | ]]) - eq({word = 'foo', abbr = 'bar', menu = 'baz', - info = 'foobar', kind = 'foobaz', user_data = ''}, - eval('v:completed_item')) + eq({ + word = 'foo', + abbr = 'bar', + menu = 'baz', + info = 'foobar', + kind = 'foobaz', + user_data = '', + }, eval('v:completed_item')) end) end) @@ -140,11 +134,7 @@ describe('completion', function() screen:expect([[ foo | ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- INSERT --} | ]]) feed('<C-x>') @@ -152,11 +142,7 @@ describe('completion', function() screen:expect([[ foo | ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)} | ]]) feed('<C-n>') @@ -164,10 +150,7 @@ describe('completion', function() foo | foo^ | {2:foo }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- Keyword Local completion (^N^P) The only match} | ]]) feed('bar<ESC>') @@ -178,9 +161,7 @@ describe('completion', function() foobar | foo^ | {2:foo }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- INSERT --} | ]]) eq('foo', eval('getline(3)')) @@ -192,34 +173,24 @@ describe('completion', function() foo | ^ | {2:foo }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- Keyword Local completion (^N^P) The only match} | ]]) feed('<C-y>') screen:expect([[ foo | foo^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- INSERT --} | ]]) feed('<ESC>') eq('foo', eval('getline(2)')) feed('o<C-r>=TestComplete()<CR>') screen:expect([[ - foo | - foo | + foo |*2 ^ | {2:foo }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- INSERT --} | ]]) feed('<C-y><ESC>') @@ -232,21 +203,14 @@ describe('completion', function() foo | ^ | {1:foo }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- Keyword Local completion (^N^P) }{5:Back at original} | ]]) feed('b') screen:expect([[ foo | b^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- Keyword Local completion (^N^P) }{5:Back at original} | ]]) feed('ar<ESC>') @@ -257,9 +221,7 @@ describe('completion', function() bar | ^ | {1:foo }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- INSERT --} | ]]) feed('bar<ESC>') @@ -272,21 +234,14 @@ describe('completion', function() foo | ^ | {1:foo }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- Keyword Local completion (^N^P) }{5:Back at original} | ]]) feed('<ESC>') screen:expect([[ foo | ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) eq('', eval('getline(2)')) @@ -296,9 +251,7 @@ describe('completion', function() | ^ | {1:foo }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- INSERT --} | ]]) feed('<ESC>') @@ -306,10 +259,7 @@ describe('completion', function() foo | | ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) eq('', eval('getline(3)')) @@ -341,8 +291,8 @@ describe('completion', function() end) local tests = { - ['<up>, <down>, <cr>'] = {'<down><cr>', '<up><cr>'}, - ['<c-n>, <c-p>, <c-y>'] = {'<c-n><c-y>', '<c-p><c-y>'}, + ['<up>, <down>, <cr>'] = { '<down><cr>', '<up><cr>' }, + ['<c-n>, <c-p>, <c-y>'] = { '<c-n><c-y>', '<c-p><c-y>' }, } for name, seq in pairs(tests) do @@ -358,13 +308,13 @@ describe('completion', function() feed('A<right><esc>A<right><esc>') local expected = { - {'foo', 'bar', 'foo'}, - {'foo', 'bar', 'ccc'}, - {'foo', 'bar'}, - {'foo', 'bbb'}, - {'foo'}, - {'aaa'}, - {''}, + { 'foo', 'bar', 'foo' }, + { 'foo', 'bar', 'ccc' }, + { 'foo', 'bar' }, + { 'foo', 'bbb' }, + { 'foo' }, + { 'aaa' }, + { '' }, } for i = 1, #expected do @@ -384,7 +334,7 @@ describe('completion', function() end end) - describe("refresh:always", function() + describe('refresh:always', function() before_each(function() source([[ function! TestCompletion(findstart, base) abort @@ -409,9 +359,9 @@ describe('completion', function() set completeopt=menuone,noselect set completefunc=TestCompletion ]]) - end ) + end) - it('completes on each input char', function () + it('completes on each input char', function() feed('i<C-x><C-u>') screen:expect([[ ^ | @@ -438,48 +388,32 @@ describe('completion', function() screen:expect([[ ug^ | {1:August }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- User defined completion (^U^N^P) }{5:Back at original} | ]]) feed('<Down>') screen:expect([[ ug^ | {2:August }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- User defined completion (^U^N^P) The only match} | ]]) feed('<C-y>') screen:expect([[ August^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 {3:-- INSERT --} | ]]) expect('August') end) - it("repeats correctly after backspace #2674", function () + it('repeats correctly after backspace #2674', function() feed('o<C-x><C-u>Ja') screen:expect([[ | Ja^ | {1:January }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- User defined completion (^U^N^P) }{5:Back at original} | ]]) feed('<BS>') @@ -489,8 +423,7 @@ describe('completion', function() {1:January }{0: }| {1:June }{0: }| {1:July }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:-- User defined completion (^U^N^P) }{5:Back at original} | ]]) feed('<C-n>') @@ -500,8 +433,7 @@ describe('completion', function() {2:January }{0: }| {1:June }{0: }| {1:July }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:-- User defined completion (^U^N^P) }{4:match 1 of 3} | ]]) feed('<C-n>') @@ -511,19 +443,14 @@ describe('completion', function() {1:January }{0: }| {2:June }{0: }| {1:July }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:-- User defined completion (^U^N^P) }{4:match 2 of 3} | ]]) feed('<Esc>') screen:expect([[ | Jun^e | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) feed('.') @@ -531,10 +458,7 @@ describe('completion', function() | June | Jun^e | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) expect([[ @@ -552,10 +476,10 @@ describe('completion', function() return '' endfunction ]]) - feed_command("set completeopt=menuone,noselect") + feed_command('set completeopt=menuone,noselect') end) - it("works", function() + it('works', function() feed('i<C-r>=TestComplete()<CR>') screen:expect([[ ^ | @@ -705,18 +629,13 @@ describe('completion', function() feed('<cr>') screen:expect([[ 96^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 {3:-- INSERT --} | ]]) end) end) - it("does not indent until an item is selected #8345", function () + it('does not indent until an item is selected #8345', function() -- Indents on "ind", unindents on "unind". source([[ function! TestIndent() @@ -735,129 +654,106 @@ describe('completion', function() ]]) -- Give some words to complete. - feed("iinc uninc indent unindent<CR>") + feed('iinc uninc indent unindent<CR>') -- Does not indent when "ind" is typed. - feed("in<C-X><C-N>") + feed('in<C-X><C-N>') -- Completion list is generated incorrectly if we send everything at once -- via nvim_input(). So poke_eventloop() before sending <BS>. #8480 poke_eventloop() - feed("<BS>d") + feed('<BS>d') screen:expect([[ inc uninc indent unindent | ind^ | {2:indent }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- Keyword Local completion (^N^P) }{4:match 1 of 2} | ]]) -- Indents when the item is selected - feed("<C-Y>") + feed('<C-Y>') screen:expect([[ inc uninc indent unindent | indent^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- INSERT --} | ]]) -- Indents when completion is exited using ESC. - feed("<CR>in<C-N><BS>d<Esc>") + feed('<CR>in<C-N><BS>d<Esc>') screen:expect([[ inc uninc indent unindent | indent | in^d | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 | ]]) -- Works for unindenting too. - feed("ounin<C-X><C-N>") - helpers.poke_eventloop() - feed("<BS>d") + feed('ounin<C-X><C-N>') + poke_eventloop() + feed('<BS>d') screen:expect([[ inc uninc indent unindent | indent | ind | unind^ | {0:~ }{2: unindent }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:-- Keyword Local completion (^N^P) }{4:match 1 of 2} | ]]) -- Works when going back and forth. - feed("<BS>c") + feed('<BS>c') screen:expect([[ inc uninc indent unindent | indent | ind | uninc^ | {0:~ }{2: uninc }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:-- Keyword Local completion (^N^P) }{4:match 1 of 2} | ]]) - feed("<BS>d") + feed('<BS>d') screen:expect([[ inc uninc indent unindent | indent | ind | unind^ | {0:~ }{2: unindent }{0: }| - {0:~ }| - {0:~ }| + {0:~ }|*2 {3:-- Keyword Local completion (^N^P) }{4:match 1 of 2} | ]]) - feed("<C-N><C-N><C-Y><Esc>") + feed('<C-N><C-N><C-Y><Esc>') screen:expect([[ inc uninc indent unindent | indent | ind | uninden^t | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 | ]]) end) - it('disables folding during completion', function () - feed_command("set foldmethod=indent") + it('disables folding during completion', function() + feed_command('set foldmethod=indent') feed('i<Tab>foo<CR><Tab>bar<Esc>gg') screen:expect([[ ^foo | bar | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 | ]]) feed('A<C-x><C-l>') screen:expect([[ foo^ | bar | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- Whole line completion (^L^N^P) }{7:Pattern not found} | ]]) eq(-1, eval('foldclosed(1)')) end) - it('popupmenu is not interrupted by events', function () - feed_command("set complete=.") + it('popupmenu is not interrupted by events', function() + feed_command('set complete=.') feed('ifoobar fooegg<cr>f<c-p>') screen:expect([[ @@ -865,24 +761,23 @@ describe('completion', function() fooegg^ | {1:foobar }{0: }| {2:fooegg }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- Keyword completion (^N^P) }{4:match 1 of 2} | ]]) assert_alive() -- popupmenu still visible - screen:expect{grid=[[ + screen:expect { + grid = [[ foobar fooegg | fooegg^ | {1:foobar }{0: }| {2:fooegg }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- Keyword completion (^N^P) }{4:match 1 of 2} | - ]], unchanged=true} + ]], + unchanged = true, + } feed('<c-p>') -- Didn't restart completion: old matches still used @@ -891,9 +786,7 @@ describe('completion', function() foobar^ | {2:foobar }{0: }| {1:fooegg }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- Keyword completion (^N^P) }{4:match 2 of 2} | ]]) end) @@ -902,68 +795,62 @@ describe('completion', function() it('expands when there is only one match', function() feed(':lua CURRENT_TESTING_VAR = 1<CR>') feed(':lua CURRENT_TESTING_<TAB>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 :lua CURRENT_TESTING_VAR^ | - ]]} + ]], + } end) it('expands when there is only one match', function() feed(':lua CURRENT_TESTING_FOO = 1<CR>') feed(':lua CURRENT_TESTING_BAR = 1<CR>') feed(':lua CURRENT_TESTING_<TAB>') - screen:expect{ grid = [[ + screen:expect { + grid = [[ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {10:CURRENT_TESTING_BAR}{9: CURRENT_TESTING_FOO }| :lua CURRENT_TESTING_BAR^ | - ]], unchanged = true } + ]], + unchanged = true, + } end) it('provides completion from `getcompletion()`', function() - eq({'vim'}, funcs.getcompletion('vi', 'lua')) - eq({'api'}, funcs.getcompletion('vim.ap', 'lua')) - eq({'tbl_filter'}, funcs.getcompletion('vim.tbl_fil', 'lua')) - eq({'vim'}, funcs.getcompletion('print(vi', 'lua')) + eq({ 'vim' }, fn.getcompletion('vi', 'lua')) + eq({ 'api' }, fn.getcompletion('vim.ap', 'lua')) + eq({ 'tbl_filter' }, fn.getcompletion('vim.tbl_fil', 'lua')) + eq({ 'vim' }, fn.getcompletion('print(vi', 'lua')) -- fuzzy completion is not supported, so the result should be the same command('set wildoptions+=fuzzy') - eq({'vim'}, funcs.getcompletion('vi', 'lua')) + eq({ 'vim' }, fn.getcompletion('vi', 'lua')) end) end) it('cmdline completion supports various string options', function() - eq('auto', funcs.getcompletion('set foldcolumn=', 'cmdline')[2]) - eq({'nosplit', 'split'}, funcs.getcompletion('set inccommand=', 'cmdline')) - eq({'ver:3,hor:6', 'hor:', 'ver:'}, funcs.getcompletion('set mousescroll=', 'cmdline')) - eq('BS', funcs.getcompletion('set termpastefilter=', 'cmdline')[2]) - eq('SpecialKey', funcs.getcompletion('set winhighlight=', 'cmdline')[1]) - eq('SpecialKey', funcs.getcompletion('set winhighlight=NonText:', 'cmdline')[1]) + eq('auto', fn.getcompletion('set foldcolumn=', 'cmdline')[2]) + eq({ 'nosplit', 'split' }, fn.getcompletion('set inccommand=', 'cmdline')) + eq({ 'ver:3,hor:6', 'hor:', 'ver:' }, fn.getcompletion('set mousescroll=', 'cmdline')) + eq('BS', fn.getcompletion('set termpastefilter=', 'cmdline')[2]) + eq('SpecialKey', fn.getcompletion('set winhighlight=', 'cmdline')[1]) + eq('SpecialKey', fn.getcompletion('set winhighlight=NonText:', 'cmdline')[1]) end) describe('from the commandline window', function() - it('is cleared after CTRL-C', function () + it('is cleared after CTRL-C', function() feed('q:') feed('ifoo faa fee f') screen:expect([[ | {8:[No Name] }| {0::}foo faa fee f^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {9:[Command Line] }| {3:-- INSERT --} | - ]] ) + ]]) feed('<c-x><c-n>') screen:expect([[ | @@ -980,9 +867,7 @@ describe('completion', function() | {8:[No Name] }| {0::}foo faa fee foo | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {9:[Command Line] }| :foo faa fee foo^ | ]]) @@ -997,17 +882,19 @@ describe('completion', function() return '' endfunction ]]) - meths.set_option_value('completeopt', 'menuone,noselect', {}) - meths.set_var('_complist', {{ - word=0, - abbr=1, - menu=2, - kind=3, - info=4, - icase=5, - dup=6, - empty=7, - }}) + api.nvim_set_option_value('completeopt', 'menuone,noselect', {}) + api.nvim_set_var('_complist', { + { + word = 0, + abbr = 1, + menu = 2, + kind = 3, + info = 4, + icase = 5, + dup = 6, + empty = 7, + }, + }) end) it('shows correct variant as word', function() @@ -1015,11 +902,7 @@ describe('completion', function() screen:expect([[ ^ | {1:1 3 2 }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- INSERT --} | ]]) end) @@ -1027,22 +910,24 @@ describe('completion', function() it("'ignorecase' 'infercase' CTRL-X CTRL-N #6451", function() feed_command('set ignorecase infercase') - feed_command('edit BACKERS.md') + feed_command('edit runtime/doc/backers.txt') feed('oX<C-X><C-N>') - screen:expect([[ - # Bountysource Backers | + screen:expect { + grid = [[ + *backers.txt* Nvim | Xnull^ | {2:Xnull }{6: } | - {1:Xoxomoon }{6: }ryone who backed our [Bountysource fundraise| - {1:Xu }{6: }ountysource.com/teams/neovim/fundraiser)! | + {1:Xoxomoon }{6: } | + {1:Xu }{6: } NVIM REFERENCE MANUAL | {1:Xpayn }{2: } | - {1:Xinity }{2: }d URL in BACKERS.md. | + {1:Xinity }{2: } | {3:-- Keyword Local completion (^N^P) }{4:match 1 of 7} | - ]]) + ]], + } end) it('CompleteChanged autocommand', function() - curbufmeths.set_lines(0, 1, false, { 'foo', 'bar', 'foobar', ''}) + api.nvim_buf_set_lines(0, 0, 1, false, { 'foo', 'bar', 'foobar', '' }) source([[ set complete=. completeopt=noinsert,noselect,menuone function! OnPumChange() @@ -1057,43 +942,45 @@ describe('completion', function() -- v:event.size should be set with ext_popupmenu #20646 screen:set_option('ext_popupmenu', true) feed('Sf<C-N>') - screen:expect({grid = [[ + screen:expect({ + grid = [[ foo | bar | foobar | f^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- Keyword completion (^N^P) }{5:Back at original} | - ]], popupmenu = { - anchor = { 1, 3, 0 }, - items = { { "foo", "", "", "" }, { "foobar", "", "", "" } }, - pos = -1 - }}) - eq({completed_item = {}, width = 0, - height = 2, size = 2, - col = 0, row = 4, scrollbar = false}, - eval('g:event')) + ]], + popupmenu = { + anchor = { 1, 3, 0 }, + items = { { 'foo', '', '', '' }, { 'foobar', '', '', '' } }, + pos = -1, + }, + }) + eq( + { completed_item = {}, width = 0, height = 2, size = 2, col = 0, row = 4, scrollbar = false }, + eval('g:event') + ) feed('oob') - screen:expect({grid = [[ + screen:expect({ + grid = [[ foo | bar | foobar | foob^ | - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- Keyword completion (^N^P) }{5:Back at original} | - ]], popupmenu = { - anchor = { 1, 3, 0 }, - items = { { "foobar", "", "", "" } }, - pos = -1 - }}) - eq({completed_item = {}, width = 0, - height = 1, size = 1, - col = 0, row = 4, scrollbar = false}, - eval('g:event')) + ]], + popupmenu = { + anchor = { 1, 3, 0 }, + items = { { 'foobar', '', '', '' } }, + pos = -1, + }, + }) + eq( + { completed_item = {}, width = 0, height = 1, size = 1, col = 0, row = 4, scrollbar = false }, + eval('g:event') + ) feed('<Esc>') screen:set_option('ext_popupmenu', false) @@ -1108,10 +995,10 @@ describe('completion', function() {0:~ }| {3:-- Keyword completion (^N^P) }{5:Back at original} | ]]) - eq({completed_item = {}, width = 15, - height = 2, size = 2, - col = 0, row = 4, scrollbar = false}, - eval('g:event')) + eq( + { completed_item = {}, width = 15, height = 2, size = 2, col = 0, row = 4, scrollbar = false }, + eval('g:event') + ) feed('<C-N>') screen:expect([[ foo | @@ -1164,7 +1051,7 @@ describe('completion', function() end) it('is stopped by :stopinsert from timer #12976', function() - screen:try_resize(32,14) + screen:try_resize(32, 14) command([[call setline(1, ['hello', 'hullo', 'heeee', ''])]]) feed('Gah<c-x><c-n>') screen:expect([[ @@ -1175,36 +1062,40 @@ describe('completion', function() {2:hello }{0: }| {1:hullo }{0: }| {1:heeee }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*6 {3:-- }{4:match 1 of 3} | ]]) command([[call timer_start(100, { -> execute('stopinsert') })]]) - helpers.sleep(200) - feed('k') -- cursor should move up in Normal mode + vim.uv.sleep(200) + feed('k') -- cursor should move up in Normal mode screen:expect([[ hello | hullo | heee^e | hello | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*9 | ]]) end) - it('does not crash if text is changed by first call to complete function #17489', function() + -- oldtest: Test_complete_changed_complete_info() + it('no crash calling complete_info() in CompleteChanged', function() + source([[ + set completeopt=menuone + autocmd CompleteChanged * call complete_info(['items']) + call feedkeys("iii\<cr>\<c-p>") + ]]) + screen:expect([[ + ii | + ii^ | + {2:ii }{0: }| + {0:~ }|*4 + {3:-- Keyword completion (^N^P) The only match} | + ]]) + assert_alive() + end) + + it('no crash if text changed by first call to complete function #17489', function() source([[ func Complete(findstart, base) abort if a:findstart @@ -1223,7 +1114,7 @@ describe('completion', function() assert_alive() end) - it('does not crash when using i_CTRL-X_CTRL-V to complete non-existent colorscheme', function() + it('no crash using i_CTRL-X_CTRL-V to complete non-existent colorscheme', function() feed('icolorscheme NOSUCHCOLORSCHEME<C-X><C-V>') expect('colorscheme NOSUCHCOLORSCHEME') assert_alive() @@ -1233,28 +1124,70 @@ describe('completion', function() screen:try_resize(20, 9) command('set complete+=f | edit foo | edit bar |edit foa |edit .hidden') feed('i<C-n>') - screen:expect{grid=[[ + screen:expect { + grid = [[ foo^ | {2:foo }{0: }| {1:bar }{0: }| {1:foa }{0: }| {1:.hidden }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*3 {3:-- }{4:match 1 of 4} | - ]]} + ]], + } feed('<Esc>ccf<C-n>') - screen:expect{grid=[[ + screen:expect { + grid = [[ foo^ | {2:foo }{0: }| {1:foa }{0: }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*5 {3:-- }{4:match 1 of 2} | - ]]} + ]], + } + end) + + it('restores extmarks if original text is restored #23653', function() + screen:try_resize(screen._width, 4) + command([[ + call setline(1, ['aaaa']) + let ns_id = nvim_create_namespace('extmark') + let mark_id = nvim_buf_set_extmark(0, ns_id, 0, 0, { 'end_col':2, 'hl_group':'Error'}) + let mark = nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 }) + inoremap <C-x> <C-r>=Complete()<CR> + function Complete() abort + call complete(1, [{ 'word': 'aaaaa' }]) + return '' + endfunction + ]]) + feed('A<C-X><C-E><Esc>') + eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })")) + feed('A<C-N>') + eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })")) + feed('<Esc>0Yppia<Esc>ggI<C-N>') + screen:expect([[ + aaaa{7:^aa}aa | + {2:aaaa } | + {1:aaaaa } | + {3:-- Keyword completion (^N^P) }{4:match 1 of 2} | + ]]) + feed('<C-N><C-N><Esc>') + eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })")) + feed('A<C-N>') + eq(eval('mark'), eval("nvim_buf_get_extmark_by_id(0, ns_id, mark_id, { 'details':1 })")) + feed('<C-N>') + screen:expect([[ + aaaaa^ | + {1:aaaa } | + {2:aaaaa } | + {3:-- Keyword completion (^N^P) }{4:match 2 of 2} | + ]]) + feed('<C-E>') + screen:expect([[ + {7:aa}aa^ | + aaaa | + aaaaa | + {3:-- INSERT --} | + ]]) end) end) diff --git a/test/functional/editor/ctrl_c_spec.lua b/test/functional/editor/ctrl_c_spec.lua index 4548e1aa34..e6a6ea808a 100644 --- a/test/functional/editor/ctrl_c_spec.lua +++ b/test/functional/editor/ctrl_c_spec.lua @@ -3,9 +3,9 @@ local Screen = require('test.functional.ui.screen') local clear, feed, source = helpers.clear, helpers.feed, helpers.source local command = helpers.command local poke_eventloop = helpers.poke_eventloop -local sleep = helpers.sleep +local sleep = vim.uv.sleep -describe("CTRL-C (mapped)", function() +describe('CTRL-C (mapped)', function() local screen before_each(function() @@ -14,7 +14,7 @@ describe("CTRL-C (mapped)", function() screen:attach() end) - it("interrupts :global", function() + it('interrupts :global', function() -- Crashes luajit. if helpers.skip_fragile(pending) then return @@ -25,7 +25,7 @@ describe("CTRL-C (mapped)", function() nnoremap <C-C> <NOP> ]]) - command("silent edit! test/functional/fixtures/bigfile.txt") + command('silent edit! test/functional/fixtures/bigfile.txt') screen:expect([[ ^0000;<control>;Cc;0;BN;;;;;N;NULL;;;; | @@ -37,19 +37,21 @@ describe("CTRL-C (mapped)", function() ]]) local function test_ctrl_c(ms) - feed(":global/^/p<CR>") + feed(':global/^/p<CR>') screen:sleep(ms) - feed("<C-C>") - screen:expect{any="Interrupt"} + feed('<C-C>') + screen:expect { any = 'Interrupt' } end -- The test is time-sensitive. Try different sleep values. - local ms_values = {100, 1000, 10000} + local ms_values = { 100, 1000, 10000 } for i, ms in ipairs(ms_values) do if i < #ms_values then local status, _ = pcall(test_ctrl_c, ms) - if status then break end - else -- Call the last attempt directly. + if status then + break + end + else -- Call the last attempt directly. test_ctrl_c(ms) end end @@ -58,16 +60,13 @@ describe("CTRL-C (mapped)", function() it('interrupts :sleep', function() command('nnoremap <C-C> <Nop>') feed(':sleep 100<CR>') - poke_eventloop() -- wait for :sleep to start + poke_eventloop() -- wait for :sleep to start feed('foo<C-C>') - poke_eventloop() -- wait for input buffer to be flushed + poke_eventloop() -- wait for input buffer to be flushed feed('i') screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | + ~ |*4 -- INSERT -- | ]]) end) @@ -76,16 +75,13 @@ describe("CTRL-C (mapped)", function() command('nnoremap <C-C> <Nop>') command('nmap <F2> <Ignore><F2>') feed('<F2>') - sleep(10) -- wait for the key to enter typeahead + sleep(10) -- wait for the key to enter typeahead feed('foo<C-C>') - poke_eventloop() -- wait for input buffer to be flushed + poke_eventloop() -- wait for input buffer to be flushed feed('i') screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | + ~ |*4 -- INSERT -- | ]]) end) diff --git a/test/functional/editor/fold_spec.lua b/test/functional/editor/fold_spec.lua index 424ce839a2..7950f6aea4 100644 --- a/test/functional/editor/fold_spec.lua +++ b/test/functional/editor/fold_spec.lua @@ -2,19 +2,24 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear local insert = helpers.insert +local exec = helpers.exec local feed = helpers.feed local expect = helpers.expect local command = helpers.command -local funcs = helpers.funcs +local fn = helpers.fn local eq = helpers.eq local neq = helpers.neq -describe('Folds', function() +describe('Folding', function() local tempfname = 'Xtest-fold.txt' setup(clear) - before_each(function() command('bwipe! | new') end) - after_each(function() os.remove(tempfname) end) + before_each(function() + command('bwipe! | new') + end) + after_each(function() + os.remove(tempfname) + end) it('manual folding adjusts with filter', function() insert([[ @@ -71,8 +76,8 @@ describe('Folds', function() local function get_folds() local rettab = {} - for i = 1, funcs.line('$') do - table.insert(rettab, funcs.foldlevel(i)) + for i = 1, fn.line('$') do + table.insert(rettab, fn.foldlevel(i)) end return rettab end @@ -94,7 +99,8 @@ describe('Folds', function() end it('neither closes nor corrupts folds', function() - test_move_indent([[ + test_move_indent( + [[ a a a @@ -112,7 +118,9 @@ a a a a - a]], '7,12m0') + a]], + '7,12m0' + ) expect([[ a a @@ -133,25 +141,26 @@ a a a]]) -- lines are not closed, folds are correct - for i = 1,funcs.line('$') do - eq(-1, funcs.foldclosed(i)) + for i = 1, fn.line('$') do + eq(-1, fn.foldclosed(i)) if i == 1 or i == 7 or i == 13 then - eq(0, funcs.foldlevel(i)) + eq(0, fn.foldlevel(i)) elseif i == 4 then - eq(2, funcs.foldlevel(i)) + eq(2, fn.foldlevel(i)) else - eq(1, funcs.foldlevel(i)) + eq(1, fn.foldlevel(i)) end end -- folds are not corrupted feed('zM') - eq(6, funcs.foldclosedend(2)) - eq(12, funcs.foldclosedend(8)) - eq(18, funcs.foldclosedend(14)) + eq(6, fn.foldclosedend(2)) + eq(12, fn.foldclosedend(8)) + eq(18, fn.foldclosedend(14)) end) it("doesn't split a fold when the move is within it", function() - test_move_indent([[ + test_move_indent( + [[ a a a @@ -161,24 +170,30 @@ a a a a -a]], '5m6') - eq({0, 1, 1, 2, 2, 2, 2, 1, 1, 0}, get_folds()) +a]], + '5m6' + ) + eq({ 0, 1, 1, 2, 2, 2, 2, 1, 1, 0 }, get_folds()) end) it('truncates folds that end in the moved range', function() - test_move_indent([[ + test_move_indent( + [[ a a a a a a -a]], '4,5m6') - eq({0, 1, 2, 0, 0, 0, 0}, get_folds()) +a]], + '4,5m6' + ) + eq({ 0, 1, 2, 0, 0, 0, 0 }, get_folds()) end) it('moves folds that start between moved range and destination', function() - test_move_indent([[ + test_move_indent( + [[ a a a @@ -191,12 +206,15 @@ a a a a - a]], '3,4m$') - eq({0, 1, 1, 0, 0, 1, 2, 1, 0, 0, 1, 0, 0}, get_folds()) + a]], + '3,4m$' + ) + eq({ 0, 1, 1, 0, 0, 1, 2, 1, 0, 0, 1, 0, 0 }, get_folds()) end) it('does not affect folds outside changed lines', function() - test_move_indent([[ + test_move_indent( + [[ a a a @@ -205,12 +223,15 @@ a a a a - a]], '4m5') - eq({1, 1, 1, 0, 0, 0, 1, 1, 1}, get_folds()) + a]], + '4m5' + ) + eq({ 1, 1, 1, 0, 0, 0, 1, 1, 1 }, get_folds()) end) it('moves and truncates folds that start in moved range', function() - test_move_indent([[ + test_move_indent( + [[ a a a @@ -220,34 +241,43 @@ a a a a -a]], '1,3m7') - eq({0, 0, 0, 0, 0, 1, 2, 0, 0, 0}, get_folds()) +a]], + '1,3m7' + ) + eq({ 0, 0, 0, 0, 0, 1, 2, 0, 0, 0 }, get_folds()) end) it('breaks a fold when moving text into it', function() - test_move_indent([[ + test_move_indent( + [[ a a a a a a -a]], '$m4') - eq({0, 1, 2, 2, 0, 0, 0}, get_folds()) +a]], + '$m4' + ) + eq({ 0, 1, 2, 2, 0, 0, 0 }, get_folds()) end) it('adjusts correctly when moving a range backwards', function() - test_move_indent([[ + test_move_indent( + [[ a a a a -a]], '2,3m0') - eq({1, 2, 0, 0, 0}, get_folds()) +a]], + '2,3m0' + ) + eq({ 1, 2, 0, 0, 0 }, get_folds()) end) it('handles shifting all remaining folds', function() - test_move_indent([[ + test_move_indent( + [[ a a a @@ -262,18 +292,23 @@ a]], '2,3m0') a a a -a]], '13m7') - eq({1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0}, get_folds()) +a]], + '13m7' + ) + eq({ 1, 2, 2, 2, 1, 2, 2, 1, 1, 1, 2, 2, 2, 1, 0 }, get_folds()) end) end) it('updates correctly on :read', function() -- luacheck: ignore 621 - helpers.write_file(tempfname, [[ + helpers.write_file( + tempfname, + [[ a - a]]) + a]] + ) insert([[ a a @@ -295,14 +330,14 @@ a]], '13m7') a a ]]) - for i = 1,2 do - eq(1, funcs.foldlevel(i)) + for i = 1, 2 do + eq(1, fn.foldlevel(i)) end - for i = 3,5 do - eq(0, funcs.foldlevel(i)) + for i = 3, 5 do + eq(0, fn.foldlevel(i)) end - for i = 6,8 do - eq(1, funcs.foldlevel(i)) + for i = 6, 8 do + eq(1, fn.foldlevel(i)) end end) @@ -320,7 +355,7 @@ a]], '13m7') ]]) command('setlocal foldmethod=indent') command('3,5d') - eq(5, funcs.foldclosedend(1)) + eq(5, fn.foldclosedend(1)) end) it("doesn't combine folds that have a specified end", function() @@ -337,7 +372,7 @@ a]], '13m7') command('setlocal foldmethod=marker') command('3,5d') command('%foldclose') - eq(2, funcs.foldclosedend(1)) + eq(2, fn.foldclosedend(1)) end) it('splits folds according to >N and <N with foldexpr', function() @@ -356,7 +391,9 @@ a]], '13m7') return 0 endfunction ]]) - helpers.write_file(tempfname, [[ + helpers.write_file( + tempfname, + [[ b b a @@ -364,7 +401,8 @@ a]], '13m7') d a a - c]]) + c]] + ) insert([[ a a @@ -378,20 +416,56 @@ a]], '13m7') command('foldopen') command('read ' .. tempfname) command('%foldclose') - eq(2, funcs.foldclosedend(1)) - eq(0, funcs.foldlevel(3)) - eq(0, funcs.foldlevel(4)) - eq(6, funcs.foldclosedend(5)) - eq(10, funcs.foldclosedend(7)) - eq(14, funcs.foldclosedend(11)) + eq(2, fn.foldclosedend(1)) + eq(0, fn.foldlevel(3)) + eq(0, fn.foldlevel(4)) + eq(6, fn.foldclosedend(5)) + eq(10, fn.foldclosedend(7)) + eq(14, fn.foldclosedend(11)) + end) + + it('fdm=expr works correctly with :move #18668', function() + exec([[ + set foldmethod=expr foldexpr=indent(v:lnum) + let content = ['', '', 'Line1', ' Line2', ' Line3', + \ 'Line4', ' Line5', ' Line6', + \ 'Line7', ' Line8', ' Line9'] + call append(0, content) + normal! zM + call cursor(4, 1) + move 2 + move 1 + ]]) + expect([[ + + Line2 + Line3 + + Line1 + Line4 + Line5 + Line6 + Line7 + Line8 + Line9 + ]]) + eq(0, fn.foldlevel(1)) + eq(3, fn.foldclosedend(2)) + eq(0, fn.foldlevel(4)) + eq(0, fn.foldlevel(5)) + eq(0, fn.foldlevel(6)) + eq(8, fn.foldclosedend(7)) + eq(0, fn.foldlevel(9)) + eq(11, fn.foldclosedend(10)) + eq(0, fn.foldlevel(12)) end) it('no folds remain if :delete makes buffer empty #19671', function() command('setlocal foldmethod=manual') - funcs.setline(1, {'foo', 'bar', 'baz'}) + fn.setline(1, { 'foo', 'bar', 'baz' }) command('2,3fold') command('%delete') - eq(0, funcs.foldlevel(1)) + eq(0, fn.foldlevel(1)) end) it('multibyte fold markers work #20438', function() @@ -405,21 +479,21 @@ a]], '13m7') bbbbb/*«*/ bbbbb bbbbb/*»*/]]) - eq(1, funcs.foldlevel(1)) + eq(1, fn.foldlevel(1)) end) - it('updates correctly with indent method and visual blockwise insertion #22898', function() + it('fdm=indent updates correctly with visual blockwise insertion #22898', function() insert([[ a b ]]) command('setlocal foldmethod=indent shiftwidth=2') feed('gg0<C-v>jI <Esc>') -- indent both lines using visual blockwise mode - eq(1, funcs.foldlevel(1)) - eq(1, funcs.foldlevel(2)) + eq(1, fn.foldlevel(1)) + eq(1, fn.foldlevel(2)) end) - it("doesn't open folds with indent method when inserting lower foldlevel line", function() + it("fdm=indent doesn't open folds when inserting lower foldlevel line", function() insert([[ insert an unindented line under this line keep the lines under this line folded @@ -427,22 +501,22 @@ a]], '13m7') keep this line folded 2 ]]) command('set foldmethod=indent shiftwidth=2 noautoindent') - eq(1, funcs.foldlevel(1)) - eq(1, funcs.foldlevel(2)) - eq(2, funcs.foldlevel(3)) - eq(2, funcs.foldlevel(4)) + eq(1, fn.foldlevel(1)) + eq(1, fn.foldlevel(2)) + eq(2, fn.foldlevel(3)) + eq(2, fn.foldlevel(4)) feed('zo') -- open the outer fold - neq(-1, funcs.foldclosed(3)) -- make sure the inner fold is not open + neq(-1, fn.foldclosed(3)) -- make sure the inner fold is not open feed('gg0oa<Esc>') -- insert unindented line - eq(1, funcs.foldlevel(1)) --| insert an unindented line under this line - eq(0, funcs.foldlevel(2)) --|a - eq(1, funcs.foldlevel(3)) --| keep the lines under this line folded - eq(2, funcs.foldlevel(4)) --| keep this line folded 1 - eq(2, funcs.foldlevel(5)) --| keep this line folded 2 + eq(1, fn.foldlevel(1)) --| insert an unindented line under this line + eq(0, fn.foldlevel(2)) --|a + eq(1, fn.foldlevel(3)) --| keep the lines under this line folded + eq(2, fn.foldlevel(4)) --| keep this line folded 1 + eq(2, fn.foldlevel(5)) --| keep this line folded 2 - neq(-1, funcs.foldclosed(4)) -- make sure the inner fold is still not open + neq(-1, fn.foldclosed(4)) -- make sure the inner fold is still not open end) end) diff --git a/test/functional/editor/jump_spec.lua b/test/functional/editor/jump_spec.lua index dc056cb252..fe03d82164 100644 --- a/test/functional/editor/jump_spec.lua +++ b/test/functional/editor/jump_spec.lua @@ -3,16 +3,17 @@ local Screen = require('test.functional.ui.screen') local clear = helpers.clear local command = helpers.command +local dedent = helpers.dedent local eq = helpers.eq -local funcs = helpers.funcs +local fn = helpers.fn local feed = helpers.feed local exec_capture = helpers.exec_capture local write_file = helpers.write_file -local curbufmeths = helpers.curbufmeths +local api = helpers.api describe('jumplist', function() local fname1 = 'Xtest-functional-normal-jump' - local fname2 = fname1..'2' + local fname2 = fname1 .. '2' before_each(clear) after_each(function() os.remove(fname1) @@ -20,33 +21,33 @@ describe('jumplist', function() end) it('does not add a new entry on startup', function() - eq('\n jump line col file/text\n>', funcs.execute('jumps')) + eq('\n jump line col file/text\n>', fn.execute('jumps')) end) it('does not require two <C-O> strokes to jump back', function() write_file(fname1, 'first file contents') write_file(fname2, 'second file contents') - command('args '..fname1..' '..fname2) - local buf1 = funcs.bufnr(fname1) - local buf2 = funcs.bufnr(fname2) + command('args ' .. fname1 .. ' ' .. fname2) + local buf1 = fn.bufnr(fname1) + local buf2 = fn.bufnr(fname2) command('next') feed('<C-O>') - eq(buf1, funcs.bufnr('%')) + eq(buf1, fn.bufnr('%')) command('first') command('snext') feed('<C-O>') - eq(buf1, funcs.bufnr('%')) + eq(buf1, fn.bufnr('%')) feed('<C-I>') - eq(buf2, funcs.bufnr('%')) + eq(buf2, fn.bufnr('%')) feed('<C-O>') - eq(buf1, funcs.bufnr('%')) + eq(buf1, fn.bufnr('%')) - command('drop '..fname2) + command('drop ' .. fname2) feed('<C-O>') - eq(buf1, funcs.bufnr('%')) + eq(buf1, fn.bufnr('%')) end) it('<C-O> scrolls cursor halfway when switching buffer #25763', function() @@ -56,11 +57,12 @@ describe('jumplist', function() local screen = Screen.new(5, 25) screen:attach() command('set number') - command('edit '..fname1) + command('edit ' .. fname1) feed('35gg') - command('edit '..fname2) + command('edit ' .. fname2) feed('<C-O>') - screen:expect{grid=[[ + screen:expect { + grid = [[ {1: 24 }foobar | {1: 25 }foobar | {1: 26 }foobar | @@ -86,9 +88,11 @@ describe('jumplist', function() {1: 46 }foobar | {1: 47 }foobar | | - ]], attr_ids={ - [1] = {foreground = Screen.colors.Brown}; - }} + ]], + attr_ids = { + [1] = { foreground = Screen.colors.Brown }, + }, + } end) end) @@ -98,9 +102,8 @@ describe("jumpoptions=stack behaves like 'tagstack'", function() feed(':clearjumps<cr>') -- Add lines so that we have locations to jump to. - for i = 1,101,1 - do - feed('iLine ' .. i .. '<cr><esc>') + for i = 1, 101, 1 do + feed('iLine ' .. i .. '<cr><esc>') end -- Jump around to add some locations to the jump list. @@ -115,82 +118,215 @@ describe("jumpoptions=stack behaves like 'tagstack'", function() end) after_each(function() - feed('set jumpoptions=') + feed('set jumpoptions=') end) it('discards the tail when navigating from the middle', function() feed('<C-O>') feed('<C-O>') - eq( '' - .. ' jump line col file/text\n' - .. ' 4 102 0 \n' - .. ' 3 1 0 Line 1\n' - .. ' 2 10 0 Line 10\n' - .. ' 1 20 0 Line 20\n' - .. '> 0 30 0 Line 30\n' - .. ' 1 40 0 Line 40\n' - .. ' 2 50 0 Line 50', - exec_capture('jumps')) + eq( + '' + .. ' jump line col file/text\n' + .. ' 4 102 0 \n' + .. ' 3 1 0 Line 1\n' + .. ' 2 10 0 Line 10\n' + .. ' 1 20 0 Line 20\n' + .. '> 0 30 0 Line 30\n' + .. ' 1 40 0 Line 40\n' + .. ' 2 50 0 Line 50', + exec_capture('jumps') + ) feed('90gg') - eq( '' - .. ' jump line col file/text\n' - .. ' 5 102 0 \n' - .. ' 4 1 0 Line 1\n' - .. ' 3 10 0 Line 10\n' - .. ' 2 20 0 Line 20\n' - .. ' 1 30 0 Line 30\n' - .. '>', - exec_capture('jumps')) + eq( + '' + .. ' jump line col file/text\n' + .. ' 5 102 0 \n' + .. ' 4 1 0 Line 1\n' + .. ' 3 10 0 Line 10\n' + .. ' 2 20 0 Line 20\n' + .. ' 1 30 0 Line 30\n' + .. '>', + exec_capture('jumps') + ) end) it('does not add the same location twice adjacently', function() feed('60gg') feed('60gg') - eq( '' - .. ' jump line col file/text\n' - .. ' 7 102 0 \n' - .. ' 6 1 0 Line 1\n' - .. ' 5 10 0 Line 10\n' - .. ' 4 20 0 Line 20\n' - .. ' 3 30 0 Line 30\n' - .. ' 2 40 0 Line 40\n' - .. ' 1 50 0 Line 50\n' - .. '>', - exec_capture('jumps')) + eq( + '' + .. ' jump line col file/text\n' + .. ' 7 102 0 \n' + .. ' 6 1 0 Line 1\n' + .. ' 5 10 0 Line 10\n' + .. ' 4 20 0 Line 20\n' + .. ' 3 30 0 Line 30\n' + .. ' 2 40 0 Line 40\n' + .. ' 1 50 0 Line 50\n' + .. '>', + exec_capture('jumps') + ) end) it('does add the same location twice nonadjacently', function() feed('10gg') feed('20gg') - eq( '' - .. ' jump line col file/text\n' - .. ' 8 102 0 \n' - .. ' 7 1 0 Line 1\n' - .. ' 6 10 0 Line 10\n' - .. ' 5 20 0 Line 20\n' - .. ' 4 30 0 Line 30\n' - .. ' 3 40 0 Line 40\n' - .. ' 2 50 0 Line 50\n' - .. ' 1 10 0 Line 10\n' - .. '>', - exec_capture('jumps')) + eq( + '' + .. ' jump line col file/text\n' + .. ' 8 102 0 \n' + .. ' 7 1 0 Line 1\n' + .. ' 6 10 0 Line 10\n' + .. ' 5 20 0 Line 20\n' + .. ' 4 30 0 Line 30\n' + .. ' 3 40 0 Line 40\n' + .. ' 2 50 0 Line 50\n' + .. ' 1 10 0 Line 10\n' + .. '>', + exec_capture('jumps') + ) end) end) -describe("jumpoptions=view", function() +describe('buffer deletion', function() + local base_file = 'Xtest-functional-buffer-deletion' + local file1 = base_file .. '1' + local file2 = base_file .. '2' + local file3 = base_file .. '3' + local base_content = 'text' + local content1 = base_content .. '1' + local content2 = base_content .. '2' + local content3 = base_content .. '3' + + local function format_jumplist(input) + return dedent(input) + :gsub('%{file1%}', file1) + :gsub('%{file2%}', file2) + :gsub('%{file3%}', file3) + :gsub('%{content1%}', content1) + :gsub('%{content2%}', content2) + :gsub('%{content3%}', content3) + end + + before_each(function() + clear() + command('clearjumps') + + write_file(file1, content1, false, false) + write_file(file2, content2, false, false) + write_file(file3, content3, false, false) + + command('edit ' .. file1) + command('edit ' .. file2) + command('edit ' .. file3) + end) + + it('deletes jump list entries when the current buffer is deleted', function() + command('edit ' .. file1) + + eq( + format_jumplist([[ + jump line col file/text + 3 1 0 {content1} + 2 1 0 {file2} + 1 1 0 {file3} + >]]), + exec_capture('jumps') + ) + + command('bwipeout') + + eq( + format_jumplist([[ + jump line col file/text + 1 1 0 {file2} + > 0 1 0 {content3}]]), + exec_capture('jumps') + ) + end) + + it('deletes jump list entries when another buffer is deleted', function() + eq( + format_jumplist([[ + jump line col file/text + 2 1 0 {file1} + 1 1 0 {file2} + >]]), + exec_capture('jumps') + ) + + command('bwipeout ' .. file2) + + eq( + format_jumplist([[ + jump line col file/text + 1 1 0 {file1} + >]]), + exec_capture('jumps') + ) + end) + + it('sets the correct jump index when the current buffer is deleted', function() + feed('<C-O>') + + eq( + format_jumplist([[ + jump line col file/text + 1 1 0 {file1} + > 0 1 0 {content2} + 1 1 0 {file3}]]), + exec_capture('jumps') + ) + + command('bw') + + eq( + format_jumplist([[ + jump line col file/text + 1 1 0 {file1} + > 0 1 0 {content3}]]), + exec_capture('jumps') + ) + end) + + it('sets the correct jump index when the another buffer is deleted', function() + feed('<C-O>') + + eq( + format_jumplist([[ + jump line col file/text + 1 1 0 {file1} + > 0 1 0 {content2} + 1 1 0 {file3}]]), + exec_capture('jumps') + ) + + command('bwipeout ' .. file1) + + eq( + format_jumplist([[ + jump line col file/text + > 0 1 0 {content2} + 1 1 0 {file3}]]), + exec_capture('jumps') + ) + end) +end) + +describe('jumpoptions=view', function() local file1 = 'Xtestfile-functional-editor-jumps' local file2 = 'Xtestfile-functional-editor-jumps-2' local function content() local c = {} - for i=1,30 do - c[i] = i .. " line" + for i = 1, 30 do + c[i] = i .. ' line' end - return table.concat(c, "\n") + return table.concat(c, '\n') end before_each(function() clear() @@ -206,9 +342,9 @@ describe("jumpoptions=view", function() it('restores the view', function() local screen = Screen.new(5, 8) screen:attach() - command("edit " .. file1) - feed("12Gztj") - feed("gg<C-o>") + command('edit ' .. file1) + feed('12Gztj') + feed('gg<C-o>') screen:expect([[ 12 line | ^13 line | @@ -224,10 +360,10 @@ describe("jumpoptions=view", function() it('restores the view across files', function() local screen = Screen.new(5, 5) screen:attach() - command("args " .. file1 .. " " .. file2) - feed("12Gzt") - command("next") - feed("G") + command('args ' .. file1 .. ' ' .. file2) + feed('12Gzt') + command('next') + feed('G') screen:expect([[ 27 line | 28 line | @@ -235,7 +371,7 @@ describe("jumpoptions=view", function() ^30 line | | ]]) - feed("<C-o><C-o>") + feed('<C-o><C-o>') screen:expect([[ ^12 line | 13 line | @@ -248,10 +384,10 @@ describe("jumpoptions=view", function() it('restores the view across files with <C-^>', function() local screen = Screen.new(5, 5) screen:attach() - command("args " .. file1 .. " " .. file2) - feed("12Gzt") - command("next") - feed("G") + command('args ' .. file1 .. ' ' .. file2) + feed('12Gzt') + command('next') + feed('G') screen:expect([[ 27 line | 28 line | @@ -259,7 +395,7 @@ describe("jumpoptions=view", function() ^30 line | | ]]) - feed("<C-^>") + feed('<C-^>') screen:expect([[ ^12 line | 13 line | @@ -269,19 +405,19 @@ describe("jumpoptions=view", function() ]]) end) - it('falls back to standard behavior when view can\'t be recovered', function() + it("falls back to standard behavior when view can't be recovered", function() local screen = Screen.new(5, 8) screen:attach() - command("edit " .. file1) - feed("7GzbG") - curbufmeths.set_lines(0, 2, true, {}) + command('edit ' .. file1) + feed('7GzbG') + api.nvim_buf_set_lines(0, 0, 2, true, {}) -- Move to line 7, and set it as the last line visible on the view with zb, meaning to recover -- the view it needs to put the cursor 7 lines from the top line. Then go to the end of the -- file, delete 2 lines before line 7, meaning the jump/mark is moved 2 lines up to line 5. -- Therefore when trying to jump back to it it's not possible to set a 7 line offset from the -- mark position to the top line, since there's only 5 lines from the mark position to line 0. -- Therefore falls back to standard behavior which is centering the view/line. - feed("<C-o>") + feed('<C-o>') screen:expect([[ 4 line | 5 line | diff --git a/test/functional/editor/lang_spec.lua b/test/functional/editor/lang_spec.lua index 24d1262f5f..ee7cfac057 100644 --- a/test/functional/editor/lang_spec.lua +++ b/test/functional/editor/lang_spec.lua @@ -9,11 +9,11 @@ describe('gu and gU', function() it('works in any locale with default casemap', function() eq('internal,keepascii', eval('&casemap')) - insert("iI") - feed("VgU") - expect("II") - feed("Vgu") - expect("ii") + insert('iI') + feed('VgU') + expect('II') + feed('Vgu') + expect('ii') end) describe('works in Turkish locale', function() @@ -21,7 +21,7 @@ describe('gu and gU', function() local err = exc_exec('lang ctype tr_TR.UTF-8') if err ~= 0 then - pending("Locale tr_TR.UTF-8 not supported", function() end) + pending('Locale tr_TR.UTF-8 not supported', function() end) return end @@ -32,29 +32,29 @@ describe('gu and gU', function() it('with default casemap', function() eq('internal,keepascii', eval('&casemap')) -- expect ASCII behavior - insert("iI") - feed("VgU") - expect("II") - feed("Vgu") - expect("ii") + insert('iI') + feed('VgU') + expect('II') + feed('Vgu') + expect('ii') end) it('with casemap=""', function() command('set casemap=') -- expect either Turkish locale behavior or ASCII behavior local iupper = eval("toupper('i')") - if iupper == "İ" then - insert("iI") - feed("VgU") - expect("İI") - feed("Vgu") - expect("iı") - elseif iupper == "I" then - insert("iI") - feed("VgU") - expect("II") - feed("Vgu") - expect("ii") + if iupper == 'İ' then + insert('iI') + feed('VgU') + expect('İI') + feed('Vgu') + expect('iı') + elseif iupper == 'I' then + insert('iI') + feed('VgU') + expect('II') + feed('Vgu') + expect('ii') else error("expected toupper('i') to be either 'I' or 'İ'") end diff --git a/test/functional/editor/langmap_spec.lua b/test/functional/editor/langmap_spec.lua index b1070ecddc..b2a4b21a89 100644 --- a/test/functional/editor/langmap_spec.lua +++ b/test/functional/editor/langmap_spec.lua @@ -4,7 +4,7 @@ local eq, neq, call = helpers.eq, helpers.neq, helpers.call local eval, feed, clear = helpers.eval, helpers.feed, helpers.clear local command, insert, expect = helpers.command, helpers.insert, helpers.expect local feed_command = helpers.feed_command -local curwin = helpers.curwin +local curwin = helpers.api.nvim_get_current_win describe("'langmap'", function() before_each(function() @@ -14,13 +14,13 @@ describe("'langmap'", function() feed('gg0') end) - it("converts keys in normal mode", function() + it('converts keys in normal mode', function() feed('ix') expect('iii ww') feed('whello<esc>') expect('iii helloww') end) - it("gives characters that are mapped by :nmap.", function() + it('gives characters that are mapped by :nmap.', function() command('map i 0x') feed('w') expect('ii www') @@ -32,20 +32,18 @@ describe("'langmap'", function() it("'langnoremap' is by default ON", function() eq(1, eval('&langnoremap')) end) - it("Results of maps are not converted when 'langnoremap' ON.", - function() + it("Results of maps are not converted when 'langnoremap' ON.", function() command('nmap x i') feed('xdl<esc>') expect('dliii www') end) - it("applies when deciding whether to map recursively", function() + it('applies when deciding whether to map recursively', function() command('nmap l i') command('nmap w j') feed('ll') expect('liii www') end) - it("does not stop applying 'langmap' on first character of a mapping", - function() + it("does not stop applying 'langmap' on first character of a mapping", function() command('1t1') command('1t1') command('goto 1') @@ -56,8 +54,7 @@ describe("'langmap'", function() iii www ihelloii www]]) end) - it("Results of maps are converted when 'langnoremap' OFF.", - function() + it("Results of maps are converted when 'langnoremap' OFF.", function() command('set nolangnoremap') command('nmap x i') feed('xdl<esc>') @@ -65,8 +62,7 @@ describe("'langmap'", function() end) end) -- e.g. CTRL-W_j , mj , 'j and "jp - it('conversions are applied to keys in middle of command', - function() + it('conversions are applied to keys in middle of command', function() -- Works in middle of window command feed('<C-w>s') local origwin = curwin() @@ -74,12 +70,12 @@ describe("'langmap'", function() neq(origwin, curwin()) -- Works when setting a mark feed('yy3p3gg0mwgg0mi') - eq({0, 3, 1, 0}, call('getpos', "'i")) - eq({0, 1, 1, 0}, call('getpos', "'w")) + eq({ 0, 3, 1, 0 }, call('getpos', "'i")) + eq({ 0, 1, 1, 0 }, call('getpos', "'w")) feed('3dd') -- Works when moving to a mark feed("'i") - eq({0, 1, 1, 0}, call('getpos', '.')) + eq({ 0, 1, 1, 0 }, call('getpos', '.')) -- Works when selecting a register feed('qillqqwhhq') eq('hh', eval('@i')) @@ -193,8 +189,7 @@ describe("'langmap'", function() eq(1, eval('gotten_one')) end) end) - it('conversions are not applied during setreg()', - function() + it('conversions are not applied during setreg()', function() call('setreg', 'i', 'ww') eq('ww', eval('@i')) end) @@ -214,12 +209,18 @@ describe("'langmap'", function() end) local function testrecording(command_string, expect_string, setup_function, expect_macro) - if setup_function then setup_function() end + if setup_function then + setup_function() + end feed('qa' .. command_string .. 'q') expect(expect_string) - eq(expect_macro or helpers.funcs.nvim_replace_termcodes(command_string, true, true, true), - eval('@a')) - if setup_function then setup_function() end + eq( + expect_macro or helpers.fn.nvim_replace_termcodes(command_string, true, true, true), + eval('@a') + ) + if setup_function then + setup_function() + end -- n.b. may need nvim_replace_termcodes() here. feed('@a') expect(expect_string) @@ -276,5 +277,4 @@ describe("'langmap'", function() testrecording('<C-w>', 'whello', local_setup, eval([["\<*C-w>"]])) testrecording('<C-i>', 'ihello', local_setup, eval([["\<*C-i>"]])) end) - end) diff --git a/test/functional/editor/macro_spec.lua b/test/functional/editor/macro_spec.lua index 53be7dcc62..c97befdf07 100644 --- a/test/functional/editor/macro_spec.lua +++ b/test/functional/editor/macro_spec.lua @@ -6,14 +6,14 @@ local feed = helpers.feed local clear = helpers.clear local expect = helpers.expect local command = helpers.command -local funcs = helpers.funcs -local meths = helpers.meths +local fn = helpers.fn +local api = helpers.api local insert = helpers.insert -local curbufmeths = helpers.curbufmeths - -before_each(clear) describe('macros', function() + before_each(function() + clear({ args_rm = { '--cmd' } }) + end) it('can be recorded and replayed', function() feed('qiahello<esc>q') expect('hello') @@ -40,31 +40,100 @@ hello]] feed [[gg]] feed [[qqAFOO<esc>q]] - eq({'helloFOO', 'hello', 'hello'}, curbufmeths.get_lines(0, -1, false)) + eq({ 'helloFOO', 'hello', 'hello' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[Q]] + eq({ 'helloFOOFOO', 'hello', 'hello' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[G3Q]] + eq({ 'helloFOOFOO', 'hello', 'helloFOOFOOFOO' }, api.nvim_buf_get_lines(0, 0, -1, false)) - feed[[Q]] - eq({'helloFOOFOO', 'hello', 'hello'}, curbufmeths.get_lines(0, -1, false)) + feed [[ggV3jQ]] + eq( + { 'helloFOOFOOFOO', 'helloFOO', 'helloFOOFOOFOOFOO' }, + api.nvim_buf_get_lines(0, 0, -1, false) + ) + end) - feed[[G3Q]] - eq({'helloFOOFOO', 'hello', 'helloFOOFOOFOO'}, curbufmeths.get_lines(0, -1, false)) + it('can be replayed with @', function() + insert [[hello +hello +hello]] + feed [[gg]] + + feed [[qqAFOO<esc>q]] + eq({ 'helloFOO', 'hello', 'hello' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[Q]] + eq({ 'helloFOOFOO', 'hello', 'hello' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[G3@@]] + eq({ 'helloFOOFOO', 'hello', 'helloFOOFOOFOO' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[ggV2j@@]] + eq( + { 'helloFOOFOOFOO', 'helloFOO', 'helloFOOFOOFOOFOO' }, + api.nvim_buf_get_lines(0, 0, -1, false) + ) + end) + + it('can be replayed with @q and @w', function() + insert [[hello +hello +hello]] + feed [[gg]] + + feed [[qqAFOO<esc>qu]] + eq({ 'hello', 'hello', 'hello' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[qwA123<esc>qu]] + eq({ 'hello', 'hello', 'hello' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[V3j@q]] + eq({ 'helloFOO', 'helloFOO', 'helloFOO' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[gg]] + feed [[Vj@w]] + eq({ 'helloFOO123', 'helloFOO123', 'helloFOO' }, api.nvim_buf_get_lines(0, 0, -1, false)) + end) + + it('can be replayed with @q and @w visual-block', function() + insert [[hello +hello +hello]] + feed [[gg]] + + feed [[qqAFOO<esc>qu]] + eq({ 'hello', 'hello', 'hello' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[qwA123<esc>qu]] + eq({ 'hello', 'hello', 'hello' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[<C-v>3j@q]] + eq({ 'helloFOO', 'helloFOO', 'helloFOO' }, api.nvim_buf_get_lines(0, 0, -1, false)) + + feed [[gg]] + feed [[<C-v>j@w]] + eq({ 'helloFOO123', 'helloFOO123', 'helloFOO' }, api.nvim_buf_get_lines(0, 0, -1, false)) end) end) describe('immediately after a macro has finished executing,', function() before_each(function() + clear() command([[let @a = 'gg0']]) end) describe('reg_executing() from RPC returns an empty string', function() it('if the macro does not end with a <Nop> mapping', function() feed('@a') - eq('', funcs.reg_executing()) + eq('', fn.reg_executing()) end) it('if the macro ends with a <Nop> mapping', function() command('nnoremap 0 <Nop>') feed('@a') - eq('', funcs.reg_executing()) + eq('', fn.reg_executing()) end) end) @@ -74,16 +143,16 @@ describe('immediately after a macro has finished executing,', function() end) it('if the macro does not end with a <Nop> mapping', function() - feed('@asq') -- "q" from "s" mapping should start recording a macro instead of being no-op - eq({mode = 'n', blocking = false}, meths.get_mode()) + feed('@asq') -- "q" from "s" mapping should start recording a macro instead of being no-op + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) expect('') eq('', eval('@a')) end) it('if the macro ends with a <Nop> mapping', function() command('nnoremap 0 <Nop>') - feed('@asq') -- "q" from "s" mapping should start recording a macro instead of being no-op - eq({mode = 'n', blocking = false}, meths.get_mode()) + feed('@asq') -- "q" from "s" mapping should start recording a macro instead of being no-op + eq({ mode = 'n', blocking = false }, api.nvim_get_mode()) expect('') eq('', eval('@a')) end) @@ -91,6 +160,7 @@ describe('immediately after a macro has finished executing,', function() end) describe('reg_recorded()', function() + before_each(clear) it('returns the correct value', function() feed [[qqyyq]] eq('q', eval('reg_recorded()')) diff --git a/test/functional/editor/mark_spec.lua b/test/functional/editor/mark_spec.lua index e669d7f2bb..6b20a736c0 100644 --- a/test/functional/editor/mark_spec.lua +++ b/test/functional/editor/mark_spec.lua @@ -1,15 +1,16 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local meths = helpers.meths -local curbufmeths = helpers.curbufmeths +local api = helpers.api local clear = helpers.clear local command = helpers.command -local funcs = helpers.funcs +local fn = helpers.fn local eq = helpers.eq local feed = helpers.feed local write_file = helpers.write_file local pcall_err = helpers.pcall_err -local cursor = function() return helpers.meths.win_get_cursor(0) end +local cursor = function() + return helpers.api.nvim_win_get_cursor(0) +end describe('named marks', function() local file1 = 'Xtestfile-functional-editor-marks' @@ -24,153 +25,153 @@ describe('named marks', function() os.remove(file2) end) - it("can be set", function() - command("edit " .. file1) - command("mark a") - eq({1, 0}, curbufmeths.get_mark("a")) - feed("jmb") - eq({2, 0}, curbufmeths.get_mark("b")) - feed("jmB") - eq({3, 0}, curbufmeths.get_mark("B")) - command("4kc") - eq({4, 0}, curbufmeths.get_mark("c")) + it('can be set', function() + command('edit ' .. file1) + command('mark a') + eq({ 1, 0 }, api.nvim_buf_get_mark(0, 'a')) + feed('jmb') + eq({ 2, 0 }, api.nvim_buf_get_mark(0, 'b')) + feed('jmB') + eq({ 3, 0 }, api.nvim_buf_get_mark(0, 'B')) + command('4kc') + eq({ 4, 0 }, api.nvim_buf_get_mark(0, 'c')) end) - it("errors when set out of range with :mark", function() - command("edit " .. file1) - local err = pcall_err(helpers.exec_capture, "1000mark x") - eq("nvim_exec2(): Vim(mark):E16: Invalid range: 1000mark x", err) + it('errors when set out of range with :mark', function() + command('edit ' .. file1) + local err = pcall_err(helpers.exec_capture, '1000mark x') + eq('nvim_exec2(): Vim(mark):E16: Invalid range: 1000mark x', err) end) - it("errors when set out of range with :k", function() - command("edit " .. file1) - local err = pcall_err(helpers.exec_capture, "1000kx") - eq("nvim_exec2(): Vim(k):E16: Invalid range: 1000kx", err) + it('errors when set out of range with :k', function() + command('edit ' .. file1) + local err = pcall_err(helpers.exec_capture, '1000kx') + eq('nvim_exec2(): Vim(k):E16: Invalid range: 1000kx', err) end) - it("errors on unknown mark name with :mark", function() - command("edit " .. file1) - local err = pcall_err(helpers.exec_capture, "mark #") - eq("nvim_exec2(): Vim(mark):E191: Argument must be a letter or forward/backward quote", err) + it('errors on unknown mark name with :mark', function() + command('edit ' .. file1) + local err = pcall_err(helpers.exec_capture, 'mark #') + eq('nvim_exec2(): Vim(mark):E191: Argument must be a letter or forward/backward quote', err) end) it("errors on unknown mark name with '", function() - command("edit " .. file1) + command('edit ' .. file1) local err = pcall_err(helpers.exec_capture, "normal! '#") - eq("nvim_exec2(): Vim(normal):E78: Unknown mark", err) + eq('nvim_exec2(): Vim(normal):E78: Unknown mark', err) end) - it("errors on unknown mark name with `", function() - command("edit " .. file1) - local err = pcall_err(helpers.exec_capture, "normal! `#") - eq("nvim_exec2(): Vim(normal):E78: Unknown mark", err) + it('errors on unknown mark name with `', function() + command('edit ' .. file1) + local err = pcall_err(helpers.exec_capture, 'normal! `#') + eq('nvim_exec2(): Vim(normal):E78: Unknown mark', err) end) it("errors when moving to a mark that is not set with '", function() - command("edit " .. file1) + command('edit ' .. file1) local err = pcall_err(helpers.exec_capture, "normal! 'z") - eq("nvim_exec2(): Vim(normal):E20: Mark not set", err) + eq('nvim_exec2(): Vim(normal):E20: Mark not set', err) err = pcall_err(helpers.exec_capture, "normal! '.") - eq("nvim_exec2(): Vim(normal):E20: Mark not set", err) + eq('nvim_exec2(): Vim(normal):E20: Mark not set', err) end) - it("errors when moving to a mark that is not set with `", function() - command("edit " .. file1) - local err = pcall_err(helpers.exec_capture, "normal! `z") - eq("nvim_exec2(): Vim(normal):E20: Mark not set", err) - err = pcall_err(helpers.exec_capture, "normal! `>") - eq("nvim_exec2(): Vim(normal):E20: Mark not set", err) + it('errors when moving to a mark that is not set with `', function() + command('edit ' .. file1) + local err = pcall_err(helpers.exec_capture, 'normal! `z') + eq('nvim_exec2(): Vim(normal):E20: Mark not set', err) + err = pcall_err(helpers.exec_capture, 'normal! `>') + eq('nvim_exec2(): Vim(normal):E20: Mark not set', err) end) it("errors when moving to a global mark that is not set with '", function() - command("edit " .. file1) + command('edit ' .. file1) local err = pcall_err(helpers.exec_capture, "normal! 'Z") - eq("nvim_exec2(): Vim(normal):E20: Mark not set", err) + eq('nvim_exec2(): Vim(normal):E20: Mark not set', err) end) - it("errors when moving to a global mark that is not set with `", function() - command("edit " .. file1) - local err = pcall_err(helpers.exec_capture, "normal! `Z") - eq("nvim_exec2(): Vim(normal):E20: Mark not set", err) + it('errors when moving to a global mark that is not set with `', function() + command('edit ' .. file1) + local err = pcall_err(helpers.exec_capture, 'normal! `Z') + eq('nvim_exec2(): Vim(normal):E20: Mark not set', err) end) it("can move to them using '", function() - command("args " .. file1 .. " " .. file2) - feed("j") - feed("ma") + command('args ' .. file1 .. ' ' .. file2) + feed('j') + feed('ma') feed("G'a") - eq({2, 0}, cursor()) - feed("mA") - command("next") + eq({ 2, 0 }, cursor()) + feed('mA') + command('next') feed("'A") - eq(1, meths.get_current_buf().id) - eq({2, 0}, cursor()) + eq(1, api.nvim_get_current_buf()) + eq({ 2, 0 }, cursor()) end) - it("can move to them using `", function() - command("args " .. file1 .. " " .. file2) - feed("jll") - feed("ma") - feed("G`a") - eq({2, 2}, cursor()) - feed("mA") - command("next") - feed("`A") - eq(1, meths.get_current_buf().id) - eq({2, 2}, cursor()) + it('can move to them using `', function() + command('args ' .. file1 .. ' ' .. file2) + feed('jll') + feed('ma') + feed('G`a') + eq({ 2, 2 }, cursor()) + feed('mA') + command('next') + feed('`A') + eq(1, api.nvim_get_current_buf()) + eq({ 2, 2 }, cursor()) end) it("can move to them using g'", function() - command("args " .. file1 .. " " .. file2) - feed("jll") - feed("ma") + command('args ' .. file1 .. ' ' .. file2) + feed('jll') + feed('ma') feed("Gg'a") - eq({2, 0}, cursor()) - feed("mA") - command("next") + eq({ 2, 0 }, cursor()) + feed('mA') + command('next') feed("g'A") - eq(1, meths.get_current_buf().id) - eq({2, 0}, cursor()) + eq(1, api.nvim_get_current_buf()) + eq({ 2, 0 }, cursor()) end) - it("can move to them using g`", function() - command("args " .. file1 .. " " .. file2) - feed("jll") - feed("ma") - feed("Gg`a") - eq({2, 2}, cursor()) - feed("mA") - command("next") - feed("g`A") - eq(1, meths.get_current_buf().id) - eq({2, 2}, cursor()) + it('can move to them using g`', function() + command('args ' .. file1 .. ' ' .. file2) + feed('jll') + feed('ma') + feed('Gg`a') + eq({ 2, 2 }, cursor()) + feed('mA') + command('next') + feed('g`A') + eq(1, api.nvim_get_current_buf()) + eq({ 2, 2 }, cursor()) end) it("can move to them using :'", function() - command("args " .. file1 .. " " .. file2) - feed("j") - feed("ma") - feed("G") + command('args ' .. file1 .. ' ' .. file2) + feed('j') + feed('ma') + feed('G') command("'a") - eq({2, 0}, cursor()) - feed("mA") - command("next") + eq({ 2, 0 }, cursor()) + feed('mA') + command('next') command("'A") - eq(1, meths.get_current_buf().id) - eq({2, 0}, cursor()) + eq(1, api.nvim_get_current_buf()) + eq({ 2, 0 }, cursor()) end) it("errors when it can't find the buffer", function() - command("args " .. file1 .. " " .. file2) - feed("mA") - command("next") - command("bw! " .. file1 ) + command('args ' .. file1 .. ' ' .. file2) + feed('mA') + command('next') + command('bw! ' .. file1) local err = pcall_err(helpers.exec_capture, "normal! 'A") - eq("nvim_exec2(): Vim(normal):E92: Buffer 1 not found", err) + eq('nvim_exec2(): Vim(normal):E92: Buffer 1 not found', err) os.remove(file1) end) - it("errors when using a mark in another buffer in command range", function() + it('errors when using a mark in another buffer in command range', function() feed('ifoo<Esc>mA') command('enew') feed('ibar<Esc>') @@ -178,147 +179,147 @@ describe('named marks', function() end) it("leave a context mark when moving with '", function() - command("edit " .. file1) - feed("llmamA") - feed("10j0") -- first col, last line + command('edit ' .. file1) + feed('llmamA') + feed('10j0') -- first col, last line local pos = cursor() feed("'a") - feed("<C-o>") + feed('<C-o>') eq(pos, cursor()) feed("'A") - feed("<C-o>") + feed('<C-o>') eq(pos, cursor()) end) - it("leave a context mark when moving with `", function() - command("edit " .. file1) - feed("llmamA") - feed("10j0") -- first col, last line + it('leave a context mark when moving with `', function() + command('edit ' .. file1) + feed('llmamA') + feed('10j0') -- first col, last line local pos = cursor() - feed("`a") - feed("<C-o>") + feed('`a') + feed('<C-o>') eq(pos, cursor()) - feed("`A") - feed("<C-o>") + feed('`A') + feed('<C-o>') eq(pos, cursor()) end) it("leave a context mark when the mark changes buffer with g'", function() - command("args " .. file1 .. " " .. file2) + command('args ' .. file1 .. ' ' .. file2) local pos - feed("GmA") - command("next") + feed('GmA') + command('next') pos = cursor() - command("clearjumps") - feed("g'A") -- since the mark is in another buffer, it leaves a context mark - feed("<C-o>") + command('clearjumps') + feed("g'A") -- since the mark is in another buffer, it leaves a context mark + feed('<C-o>') eq(pos, cursor()) end) - it("leave a context mark when the mark changes buffer with g`", function() - command("args " .. file1 .. " " .. file2) + it('leave a context mark when the mark changes buffer with g`', function() + command('args ' .. file1 .. ' ' .. file2) local pos - feed("GmA") - command("next") + feed('GmA') + command('next') pos = cursor() - command("clearjumps") - feed("g`A") -- since the mark is in another buffer, it leaves a context mark - feed("<C-o>") + command('clearjumps') + feed('g`A') -- since the mark is in another buffer, it leaves a context mark + feed('<C-o>') eq(pos, cursor()) end) it("do not leave a context mark when moving with g'", function() - command("edit " .. file1) + command('edit ' .. file1) local pos - feed("ma") + feed('ma') pos = cursor() -- Mark pos - feed("10j0") -- first col, last line + feed('10j0') -- first col, last line feed("g'a") - feed("<C-o>") -- should do nothing + feed('<C-o>') -- should do nothing eq(pos, cursor()) - feed("mA") + feed('mA') pos = cursor() -- Mark pos - feed("10j0") -- first col, last line + feed('10j0') -- first col, last line feed("g'a") - feed("<C-o>") -- should do nothing + feed('<C-o>') -- should do nothing eq(pos, cursor()) end) - it("do not leave a context mark when moving with g`", function() - command("edit " .. file1) + it('do not leave a context mark when moving with g`', function() + command('edit ' .. file1) local pos - feed("ma") + feed('ma') pos = cursor() -- Mark pos - feed("10j0") -- first col, last line - feed("g`a") - feed("<C-o>") -- should do nothing + feed('10j0') -- first col, last line + feed('g`a') + feed('<C-o>') -- should do nothing eq(pos, cursor()) - feed("mA") + feed('mA') pos = cursor() -- Mark pos - feed("10j0") -- first col, last line + feed('10j0') -- first col, last line feed("g'a") - feed("<C-o>") -- should do nothing + feed('<C-o>') -- should do nothing eq(pos, cursor()) end) - it("open folds when moving to them", function() - command("edit " .. file1) - feed("jzfG") -- Fold from the second line to the end - command("3mark a") - feed("G") -- On top of the fold - assert(funcs.foldclosed('.') ~= -1) -- folded + it('open folds when moving to them', function() + command('edit ' .. file1) + feed('jzfG') -- Fold from the second line to the end + command('3mark a') + feed('G') -- On top of the fold + assert(fn.foldclosed('.') ~= -1) -- folded feed("'a") - eq(-1, funcs.foldclosed('.')) + eq(-1, fn.foldclosed('.')) - feed("zc") - assert(funcs.foldclosed('.') ~= -1) -- folded + feed('zc') + assert(fn.foldclosed('.') ~= -1) -- folded -- TODO: remove this workaround after fixing #15873 - feed("k`a") - eq(-1, funcs.foldclosed('.')) + feed('k`a') + eq(-1, fn.foldclosed('.')) - feed("zc") - assert(funcs.foldclosed('.') ~= -1) -- folded + feed('zc') + assert(fn.foldclosed('.') ~= -1) -- folded feed("kg'a") - eq(-1, funcs.foldclosed('.')) + eq(-1, fn.foldclosed('.')) - feed("zc") - assert(funcs.foldclosed('.') ~= -1) -- folded - feed("kg`a") - eq(-1, funcs.foldclosed('.')) + feed('zc') + assert(fn.foldclosed('.') ~= -1) -- folded + feed('kg`a') + eq(-1, fn.foldclosed('.')) end) it("do not open folds when moving to them doesn't move the cursor", function() - command("edit " .. file1) - feed("jzfG") -- Fold from the second line to the end - assert(funcs.foldclosed('.') == 2) -- folded - feed("ma") + command('edit ' .. file1) + feed('jzfG') -- Fold from the second line to the end + assert(fn.foldclosed('.') == 2) -- folded + feed('ma') feed("'a") - feed("`a") + feed('`a') feed("g'a") - feed("g`a") + feed('g`a') -- should still be folded - eq(2, funcs.foldclosed('.')) + eq(2, fn.foldclosed('.')) end) it("getting '{ '} '( ') does not move cursor", function() - meths.buf_set_lines(0, 0, 0, true, {'aaaaa', 'bbbbb', 'ccccc', 'ddddd', 'eeeee'}) - meths.win_set_cursor(0, {2, 0}) - funcs.getpos("'{") - eq({2, 0}, meths.win_get_cursor(0)) - funcs.getpos("'}") - eq({2, 0}, meths.win_get_cursor(0)) - funcs.getpos("'(") - eq({2, 0}, meths.win_get_cursor(0)) - funcs.getpos("')") - eq({2, 0}, meths.win_get_cursor(0)) + api.nvim_buf_set_lines(0, 0, 0, true, { 'aaaaa', 'bbbbb', 'ccccc', 'ddddd', 'eeeee' }) + api.nvim_win_set_cursor(0, { 2, 0 }) + fn.getpos("'{") + eq({ 2, 0 }, api.nvim_win_get_cursor(0)) + fn.getpos("'}") + eq({ 2, 0 }, api.nvim_win_get_cursor(0)) + fn.getpos("'(") + eq({ 2, 0 }, api.nvim_win_get_cursor(0)) + fn.getpos("')") + eq({ 2, 0 }, api.nvim_win_get_cursor(0)) end) it('in command range does not move cursor #19248', function() - meths.create_user_command('Test', ':', {range = true}) - meths.buf_set_lines(0, 0, 0, true, {'aaaaa', 'bbbbb', 'ccccc', 'ddddd', 'eeeee'}) - meths.win_set_cursor(0, {2, 0}) + api.nvim_create_user_command('Test', ':', { range = true }) + api.nvim_buf_set_lines(0, 0, 0, true, { 'aaaaa', 'bbbbb', 'ccccc', 'ddddd', 'eeeee' }) + api.nvim_win_set_cursor(0, { 2, 0 }) command([['{,'}Test]]) - eq({2, 0}, meths.win_get_cursor(0)) + eq({ 2, 0 }, api.nvim_win_get_cursor(0)) end) end) @@ -327,16 +328,16 @@ describe('named marks view', function() local file2 = 'Xtestfile-functional-editor-marks-2' local function content() local c = {} - for i=1,30 do - c[i] = i .. " line" + for i = 1, 30 do + c[i] = i .. ' line' end - return table.concat(c, "\n") + return table.concat(c, '\n') end before_each(function() clear() write_file(file1, content(), false, false) write_file(file2, content(), false, false) - command("set jumpoptions+=view") + command('set jumpoptions+=view') end) after_each(function() os.remove(file1) @@ -344,12 +345,12 @@ describe('named marks view', function() end) it('is restored in normal mode but not op-pending mode', function() - local screen = Screen.new(5, 8) - screen:attach() - command("edit " .. file1) - feed("<C-e>jWma") - feed("G'a") - local expected = [[ + local screen = Screen.new(5, 8) + screen:attach() + command('edit ' .. file1) + feed('<C-e>jWma') + feed("G'a") + local expected = [[ 2 line | ^3 line | 4 line | @@ -359,9 +360,9 @@ describe('named marks view', function() 8 line | | ]] - screen:expect({grid=expected}) - feed("G`a") - screen:expect([[ + screen:expect({ grid = expected }) + feed('G`a') + screen:expect([[ 2 line | 3 ^line | 4 line | @@ -371,9 +372,9 @@ describe('named marks view', function() 8 line | | ]]) - -- not in op-pending mode #20886 - feed("ggj=`a") - screen:expect([[ + -- not in op-pending mode #20886 + feed('ggj=`a') + screen:expect([[ 1 line | ^2 line | 3 line | @@ -388,8 +389,8 @@ describe('named marks view', function() it('is restored across files', function() local screen = Screen.new(5, 5) screen:attach() - command("args " .. file1 .. " " .. file2) - feed("<C-e>mA") + command('args ' .. file1 .. ' ' .. file2) + feed('<C-e>mA') local mark_view = [[ ^2 line | 3 line | @@ -398,7 +399,7 @@ describe('named marks view', function() | ]] screen:expect(mark_view) - command("next") + command('next') screen:expect([[ ^1 line | 2 line | @@ -410,18 +411,16 @@ describe('named marks view', function() screen:expect(mark_view) end) - it('fallback to standard behavior when view can\'t be recovered', function() - local screen = Screen.new(10, 10) - screen:attach() - command("edit " .. file1) - feed("7GzbmaG") -- Seven lines from the top - command("new") -- Screen size for window is now half the height can't be restored - feed("<C-w>p'a") - screen:expect([[ + it("fallback to standard behavior when view can't be recovered", function() + local screen = Screen.new(10, 10) + screen:attach() + command('edit ' .. file1) + feed('7GzbmaG') -- Seven lines from the top + command('new') -- Screen size for window is now half the height can't be restored + feed("<C-w>p'a") + screen:expect([[ | - ~ | - ~ | - ~ | + ~ |*3 [No Name] | 6 line | ^7 line | @@ -454,10 +453,7 @@ describe('named marks view', function() command('bwipe!') screen:expect([[ ^ | - ~ | - ~ | - ~ | - ~ | + ~ |*4 | ]]) command('rshada!') diff --git a/test/functional/editor/meta_key_spec.lua b/test/functional/editor/meta_key_spec.lua index 825b20138a..b57f5c3c35 100644 --- a/test/functional/editor/meta_key_spec.lua +++ b/test/functional/editor/meta_key_spec.lua @@ -4,7 +4,7 @@ local command = helpers.command local exec_lua = helpers.exec_lua local eval = helpers.eval local expect = helpers.expect -local funcs = helpers.funcs +local fn = helpers.fn local eq = helpers.eq describe('meta-keys #8226 #13042', function() @@ -66,11 +66,11 @@ describe('meta-keys #8226 #13042', function() command('inoremap <A-j> alt-j') feed('i<M-l> xxx <A-j><M-h>a<A-h>') expect('meta-l xxx alt-j') - eq({ 0, 1, 14, 0, }, funcs.getpos('.')) + eq({ 0, 1, 14, 0 }, fn.getpos('.')) -- Unmapped ALT-chord behaves as ESC+c. command('iunmap <M-l>') feed('0i<M-l>') - eq({ 0, 1, 2, 0, }, funcs.getpos('.')) + eq({ 0, 1, 2, 0 }, fn.getpos('.')) -- Unmapped ALT-chord has same `undo` characteristics as ESC+<key> command('0,$d') feed('ahello<M-.>') @@ -101,7 +101,7 @@ describe('meta-keys #8226 #13042', function() eq(meta_l_seq .. 'yyy' .. meta_l_seq .. 'alt-j', exec_lua([[return _G.input_data]])) eq('t', eval('mode(1)')) feed('<Esc>j') - eq({ 0, 2, 1, 0, }, funcs.getpos('.')) + eq({ 0, 2, 1, 0 }, fn.getpos('.')) eq('nt', eval('mode(1)')) end) diff --git a/test/functional/editor/mode_cmdline_spec.lua b/test/functional/editor/mode_cmdline_spec.lua index d34b5a1a28..06efe53718 100644 --- a/test/functional/editor/mode_cmdline_spec.lua +++ b/test/functional/editor/mode_cmdline_spec.lua @@ -2,11 +2,11 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') -local clear, insert, funcs, eq, feed = - helpers.clear, helpers.insert, helpers.funcs, helpers.eq, helpers.feed +local clear, insert, fn, eq, feed = + helpers.clear, helpers.insert, helpers.fn, helpers.eq, helpers.feed local eval = helpers.eval local command = helpers.command -local meths = helpers.meths +local api = helpers.api describe('cmdline', function() before_each(clear) @@ -20,22 +20,22 @@ describe('cmdline', function() -- Yank 2 lines linewise, then paste to cmdline. feed([[<C-\><C-N>gg0yj:<C-R>0]]) -- <CR> inserted between lines, NOT after the final line. - eq('line1abc\rline2somemoretext', funcs.getcmdline()) + eq('line1abc\rline2somemoretext', fn.getcmdline()) -- Yank 2 lines charwise, then paste to cmdline. feed([[<C-\><C-N>gg05lyvj:<C-R>0]]) -- <CR> inserted between lines, NOT after the final line. - eq('abc\rline2', funcs.getcmdline()) + eq('abc\rline2', fn.getcmdline()) -- Yank 1 line linewise, then paste to cmdline. feed([[<C-\><C-N>ggyy:<C-R>0]]) -- No <CR> inserted. - eq('line1abc', funcs.getcmdline()) + eq('line1abc', fn.getcmdline()) end) it('pasting special register inserts <CR>, <NL>', function() feed([[:<C-R>="foo\nbar\rbaz"<CR>]]) - eq('foo\nbar\rbaz', funcs.getcmdline()) + eq('foo\nbar\rbaz', fn.getcmdline()) end) end) @@ -48,55 +48,59 @@ describe('cmdline', function() it('redraws statusline when toggling overstrike', function() local screen = Screen.new(60, 4) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {reverse = true, bold = true}, -- StatusLine + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { reverse = true, bold = true }, -- StatusLine }) screen:attach() command('set laststatus=2 statusline=%!mode(1)') feed(':') - screen:expect{grid=[[ + screen:expect { + grid = [[ | {0:~ }| {1:c }| :^ | - ]]} + ]], + } feed('<Insert>') - screen:expect{grid=[[ + screen:expect { + grid = [[ | {0:~ }| {1:cr }| :^ | - ]]} + ]], + } end) describe('history', function() it('correctly clears start of the history', function() -- Regression test: check absence of the memory leak when clearing start of - -- the history using ex_getln.c/clr_history(). - eq(1, funcs.histadd(':', 'foo')) - eq(1, funcs.histdel(':')) - eq('', funcs.histget(':', -1)) + -- the history using cmdhist.c/clr_history(). + eq(1, fn.histadd(':', 'foo')) + eq(1, fn.histdel(':')) + eq('', fn.histget(':', -1)) end) it('correctly clears end of the history', function() -- Regression test: check absence of the memory leak when clearing end of - -- the history using ex_getln.c/clr_history(). - meths.set_option_value('history', 1, {}) - eq(1, funcs.histadd(':', 'foo')) - eq(1, funcs.histdel(':')) - eq('', funcs.histget(':', -1)) + -- the history using cmdhist.c/clr_history(). + api.nvim_set_option_value('history', 1, {}) + eq(1, fn.histadd(':', 'foo')) + eq(1, fn.histdel(':')) + eq('', fn.histget(':', -1)) end) it('correctly removes item from history', function() - -- Regression test: check that ex_getln.c/del_history_idx() correctly clears + -- Regression test: check that cmdhist.c/del_history_idx() correctly clears -- history index after removing history entry. If it does not then deleting -- history will result in a double free. - eq(1, funcs.histadd(':', 'foo')) - eq(1, funcs.histadd(':', 'bar')) - eq(1, funcs.histadd(':', 'baz')) - eq(1, funcs.histdel(':', -2)) - eq(1, funcs.histdel(':')) - eq('', funcs.histget(':', -1)) + eq(1, fn.histadd(':', 'foo')) + eq(1, fn.histadd(':', 'bar')) + eq(1, fn.histadd(':', 'baz')) + eq(1, fn.histdel(':', -2)) + eq(1, fn.histdel(':')) + eq('', fn.histget(':', -1)) end) end) end) diff --git a/test/functional/editor/mode_insert_spec.lua b/test/functional/editor/mode_insert_spec.lua index 37651164f5..e96813b6f7 100644 --- a/test/functional/editor/mode_insert_spec.lua +++ b/test/functional/editor/mode_insert_spec.lua @@ -53,31 +53,25 @@ describe('insert-mode', function() it('double quote is removed after hit-enter prompt #22609', function() local screen = Screen.new(60, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText - [1] = {foreground = Screen.colors.Blue}, -- SpecialKey - [2] = {foreground = Screen.colors.SlateBlue}, - [3] = {bold = true}, -- ModeMsg - [4] = {reverse = true, bold = true}, -- MsgSeparator - [5] = {background = Screen.colors.Red, foreground = Screen.colors.White}, -- ErrorMsg - [6] = {foreground = Screen.colors.SeaGreen, bold = true}, -- MoreMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { foreground = Screen.colors.Blue }, -- SpecialKey + [2] = { foreground = Screen.colors.SlateBlue }, + [3] = { bold = true }, -- ModeMsg + [4] = { reverse = true, bold = true }, -- MsgSeparator + [5] = { background = Screen.colors.Red, foreground = Screen.colors.White }, -- ErrorMsg + [6] = { foreground = Screen.colors.SeaGreen, bold = true }, -- MoreMsg }) screen:attach() feed('i<C-R>') screen:expect([[ {1:^"} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- INSERT --} | ]]) feed('={}') screen:expect([[ {1:"} | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 ={2:{}}^ | ]]) feed('<CR>') @@ -92,10 +86,7 @@ describe('insert-mode', function() feed('<CR>') screen:expect([[ ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {3:-- INSERT --} | ]]) end) @@ -196,10 +187,10 @@ describe('insert-mode', function() it('multi-char mapping updates screen properly #25626', function() local screen = Screen.new(60, 6) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}; -- NonText - [1] = {bold = true, reverse = true}; -- StatusLine - [2] = {reverse = true}; -- StatusLineNC - [3] = {bold = true}; -- ModeMsg + [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText + [1] = { bold = true, reverse = true }, -- StatusLine + [2] = { reverse = true }, -- StatusLineNC + [3] = { bold = true }, -- ModeMsg }) screen:attach() command('vnew') @@ -208,22 +199,26 @@ describe('insert-mode', function() command('set timeoutlen=10000') command('inoremap jk <Esc>') feed('i<CR>βββ<Left><Left>j') - screen:expect{grid=[[ + screen:expect { + grid = [[ foo │ | foo │β^jβ | foo │{0:~ }| {0:~ }│{0:~ }| {2:[No Name] [+] }{1:[No Name] [+] }| {3:-- INSERT --} | - ]]} + ]], + } feed('k') - screen:expect{grid=[[ + screen:expect { + grid = [[ foo │ | foo │^βββ | foo │{0:~ }| {0:~ }│{0:~ }| {2:[No Name] [+] }{1:[No Name] [+] }| | - ]]} + ]], + } end) end) diff --git a/test/functional/editor/mode_normal_spec.lua b/test/functional/editor/mode_normal_spec.lua new file mode 100644 index 0000000000..89bab3f6c9 --- /dev/null +++ b/test/functional/editor/mode_normal_spec.lua @@ -0,0 +1,22 @@ +-- Normal mode tests. + +local helpers = require('test.functional.helpers')(after_each) +local clear = helpers.clear +local feed = helpers.feed +local fn = helpers.fn +local command = helpers.command +local eq = helpers.eq + +describe('Normal mode', function() + before_each(clear) + + it('setting &winhighlight or &winblend does not change curswant #27470', function() + fn.setline(1, { 'long long lone line', 'short line' }) + feed('ggfi') + local pos = fn.getcurpos() + feed('j') + command('setlocal winblend=10 winhighlight=Visual:Search') + feed('k') + eq(pos, fn.getcurpos()) + end) +end) diff --git a/test/functional/editor/put_spec.lua b/test/functional/editor/put_spec.lua index 47068470bb..414b289222 100644 --- a/test/functional/editor/put_spec.lua +++ b/test/functional/editor/put_spec.lua @@ -6,12 +6,12 @@ local insert = helpers.insert local feed = helpers.feed local expect = helpers.expect local eq = helpers.eq -local map = helpers.tbl_map -local filter = helpers.tbl_filter +local map = vim.tbl_map +local filter = vim.tbl_filter local feed_command = helpers.feed_command local command = helpers.command local curbuf_contents = helpers.curbuf_contents -local funcs = helpers.funcs +local fn = helpers.fn local dedent = helpers.dedent local function reset() @@ -21,9 +21,9 @@ local function reset() Line of words 2]]) command('goto 1') feed('itest_string.<esc>u') - funcs.setreg('a', 'test_stringa', 'V') - funcs.setreg('b', 'test_stringb\ntest_stringb\ntest_stringb', 'b') - funcs.setreg('"', 'test_string"', 'v') + fn.setreg('a', 'test_stringa', 'V') + fn.setreg('b', 'test_stringb\ntest_stringb\ntest_stringb', 'b') + fn.setreg('"', 'test_string"', 'v') end -- We check the last inserted register ". in each of these tests because it is @@ -35,12 +35,12 @@ describe('put command', function() before_each(reset) local function visual_marks_zero() - for _,v in pairs(funcs.getpos("'<")) do + for _, v in pairs(fn.getpos("'<")) do if v ~= 0 then return false end end - for _,v in pairs(funcs.getpos("'>")) do + for _, v in pairs(fn.getpos("'>")) do if v ~= 0 then return false end @@ -51,10 +51,12 @@ describe('put command', function() -- {{{ Where test definitions are run local function run_test_variations(test_variations, extra_setup) reset() - if extra_setup then extra_setup() end + if extra_setup then + extra_setup() + end local init_contents = curbuf_contents() - local init_cursorpos = funcs.getcurpos() - local assert_no_change = function (exception_table, after_undo) + local init_cursorpos = fn.getcurpos() + local assert_no_change = function(exception_table, after_undo) expect(init_contents) -- When putting the ". register forwards, undo doesn't move -- the cursor back to where it was before. @@ -63,14 +65,16 @@ describe('put command', function() -- one place to the right (unless we were at the end of the -- line when we pasted). if not (exception_table.undo_position and after_undo) then - eq(init_cursorpos, funcs.getcurpos()) + eq(init_cursorpos, fn.getcurpos()) end end for _, test in pairs(test_variations) do it(test.description, function() - if extra_setup then extra_setup() end - local orig_dotstr = funcs.getreg('.') + if extra_setup then + extra_setup() + end + local orig_dotstr = fn.getreg('.') helpers.ok(visual_marks_zero()) -- Make sure every test starts from the same conditions assert_no_change(test.exception_table, false) @@ -85,7 +89,7 @@ describe('put command', function() -- If we paste the ". register with a count we can't avoid -- changing this register, hence avoid this check. if not test.exception_table.dot_reg_changed then - eq(orig_dotstr, funcs.getreg('.')) + eq(orig_dotstr, fn.getreg('.')) end -- Doing something, undoing it, and then redoing it should @@ -101,7 +105,7 @@ describe('put command', function() end if test.exception_table.undo_position then - funcs.setpos('.', init_cursorpos) + fn.setpos('.', init_cursorpos) end if was_cli then feed('@:') @@ -115,8 +119,13 @@ describe('put command', function() end -- run_test_variations() -- }}} - local function create_test_defs(test_defs, command_base, command_creator, -- {{{ - expect_base, expect_creator) + local function create_test_defs( + test_defs, + command_base, + command_creator, -- {{{ + expect_base, + expect_creator + ) local rettab = {} local exceptions for _, v in pairs(test_defs) do @@ -125,8 +134,7 @@ describe('put command', function() else exceptions = {} end - table.insert(rettab, - { + table.insert(rettab, { test_action = command_creator(command_base, v[1]), test_assertions = expect_creator(expect_base, v[2]), description = v[3], @@ -143,10 +151,10 @@ describe('put command', function() -- it was in. -- This returns the cursor position that would leave the 'x' in that -- place if we feed 'ix<esc>' and the string existed before it. - for linenum, line in pairs(funcs.split(expect_string, '\n', 1)) do + for linenum, line in pairs(fn.split(expect_string, '\n', 1)) do local column = line:find('x') if column then - return {linenum, column}, expect_string:gsub('x', '') + return { linenum, column }, expect_string:gsub('x', '') end end end -- find_cursor_position() }}} @@ -176,17 +184,17 @@ describe('put command', function() return function(exception_table, after_redo) expect(expect_string) - -- Have to use getcurpos() instead of curwinmeths.get_cursor() in + -- Have to use getcurpos() instead of api.nvim_win_get_cursor(0) in -- order to account for virtualedit. -- We always want the curswant element in getcurpos(), which is -- sometimes different to the column element in - -- curwinmeths.get_cursor(). + -- api.nvim_win_get_cursor(0). -- NOTE: The ".gp command leaves the cursor after the pasted text -- when running, but does not when the command is redone with the -- '.' command. if not (exception_table.redo_position and after_redo) then - local actual_position = funcs.getcurpos() - eq(cursor_position, {actual_position[2], actual_position[5]}) + local actual_position = fn.getcurpos() + eq(cursor_position, { actual_position[2], actual_position[5] }) end end end -- expect_creator() }}} @@ -195,13 +203,13 @@ describe('put command', function() local function copy_def(def) local rettab = { '', {}, '', nil } rettab[1] = def[1] - for k,v in pairs(def[2]) do + for k, v in pairs(def[2]) do rettab[2][k] = v end rettab[3] = def[3] if def[4] then rettab[4] = {} - for k,v in pairs(def[4]) do + for k, v in pairs(def[4]) do rettab[4][k] = v end end @@ -211,52 +219,52 @@ describe('put command', function() local normal_command_defs = { { 'p', - {cursor_after = false, put_backwards = false, dot_register = false}, + { cursor_after = false, put_backwards = false, dot_register = false }, 'pastes after cursor with p', }, { 'gp', - {cursor_after = true, put_backwards = false, dot_register = false}, + { cursor_after = true, put_backwards = false, dot_register = false }, 'leaves cursor after text with gp', }, { '".p', - {cursor_after = false, put_backwards = false, dot_register = true}, + { cursor_after = false, put_backwards = false, dot_register = true }, 'works with the ". register', }, { '".gp', - {cursor_after = true, put_backwards = false, dot_register = true}, + { cursor_after = true, put_backwards = false, dot_register = true }, 'gp works with the ". register', - {redo_position = true}, + { redo_position = true }, }, { 'P', - {cursor_after = false, put_backwards = true, dot_register = false}, + { cursor_after = false, put_backwards = true, dot_register = false }, 'pastes before cursor with P', }, { 'gP', - {cursor_after = true, put_backwards = true, dot_register = false}, + { cursor_after = true, put_backwards = true, dot_register = false }, 'gP pastes before cursor and leaves cursor after text', }, { '".P', - {cursor_after = false, put_backwards = true, dot_register = true}, + { cursor_after = false, put_backwards = true, dot_register = true }, 'P works with ". register', }, { '".gP', - {cursor_after = true, put_backwards = true, dot_register = true}, + { cursor_after = true, put_backwards = true, dot_register = true }, 'gP works with ". register', - {redo_position = true}, + { redo_position = true }, }, } -- Add a definition applying a count for each definition above. -- Could do this for each transformation (p -> P, p -> gp etc), but I think -- it's neater this way (balance between being explicit and too verbose). - for i = 1,#normal_command_defs do + for i = 1, #normal_command_defs do local cur = normal_command_defs[i] -- Make modified copy of current definition that includes a count. @@ -279,35 +287,36 @@ describe('put command', function() local ex_command_defs = { { 'put', - {put_backwards = false, dot_register = false}, + { put_backwards = false, dot_register = false }, 'pastes linewise forwards with :put', }, { 'put!', - {put_backwards = true, dot_register = false}, + { put_backwards = true, dot_register = false }, 'pastes linewise backwards with :put!', }, { 'put .', - {put_backwards = false, dot_register = true}, + { put_backwards = false, dot_register = true }, 'pastes linewise with the dot register', }, { 'put! .', - {put_backwards = true, dot_register = true}, + { put_backwards = true, dot_register = true }, 'pastes linewise backwards with the dot register', }, } local function non_dotdefs(def_table) - return filter(function(d) return not d[2].dot_register end, def_table) + return filter(function(d) + return not d[2].dot_register + end, def_table) end -- }}} -- Conversion functions {{{ - local function convert_charwise(expect_base, conversion_table, - virtualedit_end, visual_put) + local function convert_charwise(expect_base, conversion_table, virtualedit_end, visual_put) expect_base = dedent(expect_base) -- There is no difference between 'P' and 'p' when VIsual_active if not visual_put then @@ -324,7 +333,7 @@ describe('put command', function() end if conversion_table.count > 1 then local rep_string = 'test_string"' - local extra_puts = rep_string:rep(conversion_table.count - 1) + local extra_puts = rep_string:rep(conversion_table.count - 1) expect_base = expect_base:gsub('test_stringx"', extra_puts .. 'test_stringx"') end if conversion_table.cursor_after then @@ -340,7 +349,7 @@ describe('put command', function() local prev_line local rettab = {} local string_found = false - for _, line in pairs(funcs.split(string, '\n', 1)) do + for _, line in pairs(fn.split(string, '\n', 1)) do if line:find('test_string') then string_found = true table.insert(rettab, line) @@ -395,7 +404,7 @@ describe('put command', function() indent = '' end local rep_string = indent .. p_str .. '\n' - local extra_puts = rep_string:rep(conversion_table.count - 1) + local extra_puts = rep_string:rep(conversion_table.count - 1) local orig_string, new_string if conversion_table.cursor_after then orig_string = indent .. p_str .. '\nx' @@ -420,8 +429,13 @@ describe('put command', function() return orig_line:sub(1, prev_end - 1) .. 'x' .. orig_line:sub(prev_end) end - local function convert_blockwise(expect_base, conversion_table, visual, - use_b, trailing_whitespace) + local function convert_blockwise( + expect_base, + conversion_table, + visual, + use_b, + trailing_whitespace + ) expect_base = dedent(expect_base) local p_str = 'test_string"' if use_b then @@ -452,11 +466,9 @@ describe('put command', function() if conversion_table.count and conversion_table.count > 1 then local p_pattern = p_str:gsub('%.', '%%.') - expect_base = expect_base:gsub(p_pattern, - p_str:rep(conversion_table.count)) - expect_base = expect_base:gsub('test_stringx([b".])', - p_str:rep(conversion_table.count - 1) - .. '%0') + expect_base = expect_base:gsub(p_pattern, p_str:rep(conversion_table.count)) + expect_base = + expect_base:gsub('test_stringx([b".])', p_str:rep(conversion_table.count - 1) .. '%0') end if conversion_table.cursor_after then @@ -464,7 +476,7 @@ describe('put command', function() local prev_line local rettab = {} local prev_in_block = false - for _, line in pairs(funcs.split(expect_base, '\n', 1)) do + for _, line in pairs(fn.split(expect_base, '\n', 1)) do if line:find('test_string') then if prev_line then prev_line = prev_line:gsub('x', '') @@ -496,8 +508,13 @@ describe('put command', function() -- }}} -- Convenience functions {{{ - local function run_normal_mode_tests(test_string, base_map, extra_setup, - virtualedit_end, selection_string) + local function run_normal_mode_tests( + test_string, + base_map, + extra_setup, + virtualedit_end, + selection_string + ) local function convert_closure(e, c) return convert_charwise(e, c, virtualedit_end, selection_string) end @@ -507,10 +524,10 @@ describe('put command', function() test_expect(exception_table, after_redo) if selection_string then if not conversion_table.put_backwards then - eq(selection_string, funcs.getreg('"')) + eq(selection_string, fn.getreg('"')) end else - eq('test_string"', funcs.getreg('"')) + eq('test_string"', fn.getreg('"')) end end end @@ -532,8 +549,12 @@ describe('put command', function() local function run_linewise_tests(expect_base, base_command, extra_setup) local linewise_test_defs = create_test_defs( - ex_command_defs, base_command, - create_put_action, expect_base, convert_linewiseer) + ex_command_defs, + base_command, + create_put_action, + expect_base, + convert_linewiseer + ) run_test_variations(linewise_test_defs, extra_setup) end -- run_linewise_tests() -- }}} @@ -545,7 +566,8 @@ describe('put command', function() Line of words 2]] run_normal_mode_tests(expect_string, 'p') - run_linewise_tests([[ + run_linewise_tests( + [[ Line of words 1 xtest_string" Line of words 2]], @@ -585,11 +607,12 @@ describe('put command', function() run_test_variations( create_test_defs( linewise_put_defs, - 'put a', create_put_action, - base_expect_string, convert_linewiseer + 'put a', + create_put_action, + base_expect_string, + convert_linewiseer ) ) - end) describe('blockwise register', function() @@ -600,18 +623,13 @@ describe('put command', function() test_stringb]] local function expect_block_creator(expect_base, conversion_table) - return expect_creator(function(e,c) return convert_blockwise(e,c,nil,true) end, - expect_base, conversion_table) + return expect_creator(function(e, c) + return convert_blockwise(e, c, nil, true) + end, expect_base, conversion_table) end run_test_variations( - create_test_defs( - blockwise_put_defs, - '"bp', - create_p_action, - test_base, - expect_block_creator - ) + create_test_defs(blockwise_put_defs, '"bp', create_p_action, test_base, expect_block_creator) ) end) @@ -632,17 +650,17 @@ describe('put command', function() describe('linewise paste with autoindent', function() -- luacheck: ignore - run_linewise_tests([[ + run_linewise_tests( + [[ Line of words 1 Line of words 2 xtest_string"]], - 'put' - , + 'put', function() - funcs.setline('$', ' Line of words 2') + fn.setline('$', ' Line of words 2') -- Set curswant to '8' to be at the end of the tab character -- This is where the cursor is put back after the 'u' command. - funcs.setpos('.', {0, 2, 1, 0, 8}) + fn.setpos('.', { 0, 2, 1, 0, 8 }) command('set autoindent') end ) @@ -653,9 +671,9 @@ describe('put command', function() Line of words 1 test_stringx" Line of words 2]] run_normal_mode_tests(test_string, 'p', function() - funcs.setline('$', ' Line of words 2') + fn.setline('$', ' Line of words 2') command('setlocal virtualedit=all') - funcs.setpos('.', {0, 2, 1, 2, 3}) + fn.setpos('.', { 0, 2, 1, 2, 3 }) end) end) @@ -665,9 +683,9 @@ describe('put command', function() Line of words 1 test_stringx" Line of words 2]] run_normal_mode_tests(test_string, 'p', function() - funcs.setline('$', ' Line of words 2') + fn.setline('$', ' Line of words 2') command('setlocal virtualedit=all') - funcs.setpos('.', {0, 1, 16, 1, 17}) + fn.setpos('.', { 0, 1, 16, 1, 17 }) end, true) end) @@ -679,12 +697,10 @@ describe('put command', function() run_normal_mode_tests(test_string, 'v2ep', nil, nil, 'Line of') end) describe('over trailing newline', function() - local test_string = 'Line of test_stringx"Line of words 2' + local test_string = 'Line of test_stringx"Line of words 2' run_normal_mode_tests(test_string, 'v$p', function() - funcs.setpos('.', {0, 1, 9, 0, 9}) - end, - nil, - 'words 1\n') + fn.setpos('.', { 0, 1, 9, 0, 9 }) + end, nil, 'words 1\n') end) describe('linewise mode', function() local test_string = [[ @@ -693,8 +709,7 @@ describe('put command', function() local function expect_vis_linewise(expect_base, conversion_table) return expect_creator(function(e, c) return convert_linewise(e, c, nil, nil) - end, - expect_base, conversion_table) + end, expect_base, conversion_table) end run_test_variations( create_test_defs( @@ -704,19 +719,20 @@ describe('put command', function() test_string, expect_vis_linewise ), - function() funcs.setpos('.', {0, 1, 1, 0, 1}) end + function() + fn.setpos('.', { 0, 1, 1, 0, 1 }) + end ) describe('with whitespace at bol', function() local function expect_vis_lineindented(expect_base, conversion_table) local test_expect = expect_creator(function(e, c) - return convert_linewise(e, c, nil, nil, ' ') - end, - expect_base, conversion_table) + return convert_linewise(e, c, nil, nil, ' ') + end, expect_base, conversion_table) return function(exception_table, after_redo) test_expect(exception_table, after_redo) if not conversion_table.put_backwards then - eq('Line of words 1\n', funcs.getreg('"')) + eq('Line of words 1\n', fn.getreg('"')) end end end @@ -733,11 +749,10 @@ describe('put command', function() ), function() feed('i test_string.<esc>u') - funcs.setreg('"', ' test_string"', 'v') + fn.setreg('"', ' test_string"', 'v') end ) end) - end) describe('blockwise visual mode', function() @@ -747,39 +762,37 @@ describe('put command', function() local function expect_block_creator(expect_base, conversion_table) local test_expect = expect_creator(function(e, c) - return convert_blockwise(e, c, true) - end, expect_base, conversion_table) - return function(e,c) - test_expect(e,c) + return convert_blockwise(e, c, true) + end, expect_base, conversion_table) + return function(e, c) + test_expect(e, c) if not conversion_table.put_backwards then - eq('Lin\nLin', funcs.getreg('"')) + eq('Lin\nLin', fn.getreg('"')) end end end local select_down_test_defs = create_test_defs( - normal_command_defs, - '<C-v>jllp', - create_p_action, - test_base, - expect_block_creator + normal_command_defs, + '<C-v>jllp', + create_p_action, + test_base, + expect_block_creator ) run_test_variations(select_down_test_defs) - -- Undo and redo of a visual block put leave the cursor in the top -- left of the visual block area no matter where the cursor was -- when it started. local undo_redo_no = map(function(table) - local rettab = copy_def(table) - if not rettab[4] then - rettab[4] = {} - end - rettab[4].undo_position = true - rettab[4].redo_position = true - return rettab - end, - normal_command_defs) + local rettab = copy_def(table) + if not rettab[4] then + rettab[4] = {} + end + rettab[4].undo_position = true + rettab[4].redo_position = true + return rettab + end, normal_command_defs) -- Selection direction doesn't matter run_test_variations( @@ -790,7 +803,9 @@ describe('put command', function() test_base, expect_block_creator ), - function() funcs.setpos('.', {0, 2, 1, 0, 1}) end + function() + fn.setpos('.', { 0, 2, 1, 0, 1 }) + end ) describe('blockwise cursor after undo', function() @@ -800,62 +815,45 @@ describe('put command', function() -- the same pattern as everything else. -- Here we fix this by directly checking the undo/redo position -- in the test_assertions of our test definitions. - local function assertion_creator(_,_) - return function(_,_) + local function assertion_creator(_, _) + return function(_, _) feed('u') -- Have to use feed('u') here to set curswant, because -- ex_undo() doesn't do that. - eq({0, 1, 1, 0, 1}, funcs.getcurpos()) + eq({ 0, 1, 1, 0, 1 }, fn.getcurpos()) feed('<C-r>') - eq({0, 1, 1, 0, 1}, funcs.getcurpos()) + eq({ 0, 1, 1, 0, 1 }, fn.getcurpos()) end end run_test_variations( - create_test_defs( - undo_redo_no, - '<C-v>kllp', - create_p_action, - test_base, - assertion_creator - ), - function() funcs.setpos('.', {0, 2, 1, 0, 1}) end + create_test_defs(undo_redo_no, '<C-v>kllp', create_p_action, test_base, assertion_creator), + function() + fn.setpos('.', { 0, 2, 1, 0, 1 }) + end ) end) end) - describe("with 'virtualedit'", function() describe('splitting a tab character', function() local base_expect_string = [[ Line of words 1 test_stringx" Line of words 2]] - run_normal_mode_tests( - base_expect_string, - 'vp', - function() - funcs.setline('$', ' Line of words 2') - command('setlocal virtualedit=all') - funcs.setpos('.', {0, 2, 1, 2, 3}) - end, - nil, - ' ' - ) + run_normal_mode_tests(base_expect_string, 'vp', function() + fn.setline('$', ' Line of words 2') + command('setlocal virtualedit=all') + fn.setpos('.', { 0, 2, 1, 2, 3 }) + end, nil, ' ') end) describe('after end of line', function() local base_expect_string = [[ Line of words 1 test_stringx" Line of words 2]] - run_normal_mode_tests( - base_expect_string, - 'vp', - function() - command('setlocal virtualedit=all') - funcs.setpos('.', {0, 1, 16, 2, 18}) - end, - true, - ' ' - ) + run_normal_mode_tests(base_expect_string, 'vp', function() + command('setlocal virtualedit=all') + fn.setpos('.', { 0, 1, 16, 2, 18 }) + end, true, ' ') end) end) end) @@ -873,9 +871,12 @@ describe('put command', function() Line of words 1 Line of words 2]]) feed('u1go<C-v>j".p') - eq([[ + eq( + [[ ine of words 1 - ine of words 2]], curbuf_contents()) + ine of words 2]], + curbuf_contents() + ) end) local screen @@ -891,33 +892,42 @@ describe('put command', function() end helpers.ok(not screen.bell and not screen.visualbell) actions() - screen:expect{condition=function() - if should_ring then - if not screen.bell and not screen.visualbell then - error('Bell was not rung after action') - end - else - if screen.bell or screen.visualbell then - error('Bell was rung after action') + screen:expect { + condition = function() + if should_ring then + if not screen.bell and not screen.visualbell then + error('Bell was not rung after action') + end + else + if screen.bell or screen.visualbell then + error('Bell was rung after action') + end end - end - end, unchanged=(not should_ring)} + end, + unchanged = not should_ring, + } screen.bell = false screen.visualbell = false end it('should not ring the bell with gp at end of line', function() - bell_test(function() feed('$".gp') end) + bell_test(function() + feed('$".gp') + end) -- Even if the last character is a multibyte character. reset() - funcs.setline(1, 'helloม') - bell_test(function() feed('$".gp') end) + fn.setline(1, 'helloม') + bell_test(function() + feed('$".gp') + end) end) it('should not ring the bell with gp and end of file', function() - funcs.setpos('.', {0, 2, 1, 0}) - bell_test(function() feed('$vl".gp') end) + fn.setpos('.', { 0, 2, 1, 0 }) + bell_test(function() + feed('$vl".gp') + end) end) it('should ring the bell when deleting if not appropriate', function() @@ -926,13 +936,15 @@ describe('put command', function() expect([[ ine of words 1 Line of words 2]]) - bell_test(function() feed('".P') end, true) + bell_test(function() + feed('".P') + end, true) end) it('should restore cursor position after undo of ".p', function() - local origpos = funcs.getcurpos() + local origpos = fn.getcurpos() feed('".pu') - eq(origpos, funcs.getcurpos()) + eq(origpos, fn.getcurpos()) end) it("should be unaffected by 'autoindent' with V\".2p", function() @@ -946,4 +958,3 @@ describe('put command', function() end) end) end) - diff --git a/test/functional/editor/search_spec.lua b/test/functional/editor/search_spec.lua index d5df131725..46a3e298b7 100644 --- a/test/functional/editor/search_spec.lua +++ b/test/functional/editor/search_spec.lua @@ -8,10 +8,7 @@ describe('search (/)', function() before_each(clear) it('fails with huge column (%c) value #9930', function() - eq([[Vim:E951: \% value too large]], - pcall_err(command, "/\\v%18446744071562067968c")) - eq([[Vim:E951: \% value too large]], - pcall_err(command, "/\\v%2147483648c")) + eq([[Vim:E951: \% value too large]], pcall_err(command, '/\\v%18446744071562067968c')) + eq([[Vim:E951: \% value too large]], pcall_err(command, '/\\v%2147483648c')) end) end) - diff --git a/test/functional/editor/tabpage_spec.lua b/test/functional/editor/tabpage_spec.lua index a7f629a76b..0cbc2dbf3d 100644 --- a/test/functional/editor/tabpage_spec.lua +++ b/test/functional/editor/tabpage_spec.lua @@ -8,9 +8,9 @@ local neq = helpers.neq local feed = helpers.feed local eval = helpers.eval local exec = helpers.exec -local funcs = helpers.funcs -local meths = helpers.meths -local curwin = helpers.curwin +local fn = helpers.fn +local api = helpers.api +local curwin = helpers.api.nvim_get_current_win local assert_alive = helpers.assert_alive describe('tabpage', function() @@ -58,7 +58,9 @@ describe('tabpage', function() end) it('no segfault with strange WinClosed autocommand #20290', function() - pcall(exec, [[ + pcall( + exec, + [[ set nohidden edit Xa split Xb @@ -66,45 +68,46 @@ describe('tabpage', function() new autocmd WinClosed * tabprev | bwipe! close - ]]) + ]] + ) assert_alive() end) it('nvim_win_close and nvim_win_hide update tabline #20285', function() - eq(1, #meths.list_tabpages()) - eq({1, 1}, funcs.win_screenpos(0)) - local win1 = curwin().id + eq(1, #api.nvim_list_tabpages()) + eq({ 1, 1 }, fn.win_screenpos(0)) + local win1 = curwin() command('tabnew') - eq(2, #meths.list_tabpages()) - eq({2, 1}, funcs.win_screenpos(0)) - local win2 = curwin().id + eq(2, #api.nvim_list_tabpages()) + eq({ 2, 1 }, fn.win_screenpos(0)) + local win2 = curwin() - meths.win_close(win1, true) - eq(win2, curwin().id) - eq(1, #meths.list_tabpages()) - eq({1, 1}, funcs.win_screenpos(0)) + api.nvim_win_close(win1, true) + eq(win2, curwin()) + eq(1, #api.nvim_list_tabpages()) + eq({ 1, 1 }, fn.win_screenpos(0)) command('tabnew') - eq(2, #meths.list_tabpages()) - eq({2, 1}, funcs.win_screenpos(0)) - local win3 = curwin().id - - meths.win_hide(win2) - eq(win3, curwin().id) - eq(1, #meths.list_tabpages()) - eq({1, 1}, funcs.win_screenpos(0)) + eq(2, #api.nvim_list_tabpages()) + eq({ 2, 1 }, fn.win_screenpos(0)) + local win3 = curwin() + + api.nvim_win_hide(win2) + eq(win3, curwin()) + eq(1, #api.nvim_list_tabpages()) + eq({ 1, 1 }, fn.win_screenpos(0)) end) it('switching tabpage after setting laststatus=3 #19591', function() local screen = Screen.new(40, 8) screen:set_default_attr_ids({ - [0] = {bold = true, foreground = Screen.colors.Blue}, - [1] = {bold = true, reverse = true}, -- StatusLine - [2] = {reverse = true}, -- TabLineFill - [3] = {bold = true}, -- TabLineSel - [4] = {background = Screen.colors.LightGrey, underline = true}, -- TabLine - [5] = {bold = true, foreground = Screen.colors.Magenta}, + [0] = { bold = true, foreground = Screen.colors.Blue }, + [1] = { bold = true, reverse = true }, -- StatusLine + [2] = { reverse = true }, -- TabLineFill + [3] = { bold = true }, -- TabLineSel + [4] = { background = Screen.colors.LightGrey, underline = true }, -- TabLine + [5] = { bold = true, foreground = Screen.colors.Magenta }, }) screen:attach() @@ -116,10 +119,7 @@ describe('tabpage', function() screen:expect([[ {4: [No Name] }{3: [No Name] }{2: }{4:X}| ^ | - {0:~ }| - {0:~ }| - {0:~ }| - {0:~ }| + {0:~ }|*4 {1:[No Name] }| "[No Name]" --No lines in buffer-- | ]]) @@ -127,26 +127,23 @@ describe('tabpage', function() screen:expect([[ {4: [No Name] }{3: }{5:2}{3: [No Name] }{2: }{4:X}| ^ │ | - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| - {0:~ }│{0:~ }| + {0:~ }│{0:~ }|*4 {1:[No Name] }| "[No Name]" --No lines in buffer-- | ]]) end) - it(":tabmove handles modifiers and addr", function() + it(':tabmove handles modifiers and addr', function() command('tabnew | tabnew | tabnew') - eq(4, funcs.nvim_tabpage_get_number(0)) + eq(4, fn.nvim_tabpage_get_number(0)) command(' silent :keepalt :: ::: silent! - tabmove') - eq(3, funcs.nvim_tabpage_get_number(0)) + eq(3, fn.nvim_tabpage_get_number(0)) command(' silent :keepalt :: ::: silent! -2 tabmove') - eq(1, funcs.nvim_tabpage_get_number(0)) + eq(1, fn.nvim_tabpage_get_number(0)) end) it(':tabs does not overflow IObuff with long path with comma #20850', function() - meths.buf_set_name(0, ('x'):rep(1024) .. ',' .. ('x'):rep(1024)) + api.nvim_buf_set_name(0, ('x'):rep(1024) .. ',' .. ('x'):rep(1024)) command('tabs') assert_alive() end) diff --git a/test/functional/editor/undo_spec.lua b/test/functional/editor/undo_spec.lua index d66ab352ef..c101bf02a0 100644 --- a/test/functional/editor/undo_spec.lua +++ b/test/functional/editor/undo_spec.lua @@ -8,12 +8,12 @@ local eq = helpers.eq local feed = helpers.feed local feed_command = helpers.feed_command local insert = helpers.insert -local funcs = helpers.funcs +local fn = helpers.fn local exec = helpers.exec local exec_lua = helpers.exec_lua local function lastmessage() - local messages = funcs.split(funcs.execute('messages'), '\n') + local messages = fn.split(fn.execute('messages'), '\n') return messages[#messages] end @@ -21,15 +21,23 @@ describe('u CTRL-R g- g+', function() before_each(clear) local function create_history(num_steps) - if num_steps == 0 then return end + if num_steps == 0 then + return + end insert('1') - if num_steps == 1 then return end + if num_steps == 1 then + return + end feed('o2<esc>') feed('o3<esc>') feed('u') - if num_steps == 2 then return end + if num_steps == 2 then + return + end feed('o4<esc>') - if num_steps == 3 then return end + if num_steps == 3 then + return + end feed('u') end @@ -57,13 +65,23 @@ describe('u CTRL-R g- g+', function() undo_and_redo(2, 'g-', 'g+', '1') end) it('undoes properly around a branch point', function() - undo_and_redo(3, 'u', '<C-r>', [[ + undo_and_redo( + 3, + 'u', + '<C-r>', + [[ 1 - 2]]) - undo_and_redo(3, 'g-', 'g+', [[ + 2]] + ) + undo_and_redo( + 3, + 'g-', + 'g+', + [[ 1 2 - 3]]) + 3]] + ) end) it('can find the previous sequence after undoing to a branch', function() undo_and_redo(4, 'u', '<C-r>', '1') |