diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/functional/api/keymap_spec.lua | 14 | ||||
-rw-r--r-- | test/functional/plugin/health_spec.lua | 56 | ||||
-rw-r--r-- | test/functional/plugin/lsp/inlay_hint_spec.lua | 44 | ||||
-rw-r--r-- | test/functional/plugin/lsp_spec.lua | 35 | ||||
-rw-r--r-- | test/functional/treesitter/parser_spec.lua | 34 | ||||
-rw-r--r-- | test/functional/ui/cmdline_spec.lua | 34 | ||||
-rw-r--r-- | test/functional/ui/cursor_spec.lua | 4 | ||||
-rw-r--r-- | test/functional/ui/decorations_spec.lua | 22 | ||||
-rw-r--r-- | test/functional/ui/diff_spec.lua | 534 | ||||
-rw-r--r-- | test/functional/ui/messages_spec.lua | 8 | ||||
-rw-r--r-- | test/functional/ui/mouse_spec.lua | 14 | ||||
-rw-r--r-- | test/functional/ui/popupmenu_spec.lua | 727 | ||||
-rw-r--r-- | test/old/testdir/gen_opt_test.vim | 6 | ||||
-rw-r--r-- | test/old/testdir/setup.vim | 2 | ||||
-rw-r--r-- | test/old/testdir/test_diffmode.vim | 203 | ||||
-rw-r--r-- | test/old/testdir/test_let.vim | 20 | ||||
-rw-r--r-- | test/old/testdir/test_normal.vim | 16 | ||||
-rw-r--r-- | test/old/testdir/test_options.vim | 18 | ||||
-rw-r--r-- | test/old/testdir/test_popup.vim | 84 | ||||
-rw-r--r-- | test/old/testdir/test_search.vim | 33 | ||||
-rw-r--r-- | test/old/testdir/test_shell.vim | 14 |
21 files changed, 1820 insertions, 102 deletions
diff --git a/test/functional/api/keymap_spec.lua b/test/functional/api/keymap_spec.lua index 995711507f..acaccee4e5 100644 --- a/test/functional/api/keymap_spec.lua +++ b/test/functional/api/keymap_spec.lua @@ -803,11 +803,23 @@ describe('nvim_set_keymap, nvim_del_keymap', function() it('throws appropriate error messages when setting <unique> maps', function() api.nvim_set_keymap('l', 'lhs', 'rhs', {}) eq( - 'E227: mapping already exists for lhs', + 'E227: Mapping already exists for lhs', pcall_err(api.nvim_set_keymap, 'l', 'lhs', 'rhs', { unique = true }) ) -- different mapmode, no error should be thrown api.nvim_set_keymap('t', 'lhs', 'rhs', { unique = true }) + + api.nvim_set_keymap('n', '<tab>', 'rhs', {}) + eq( + 'E227: Mapping already exists for <tab>', + pcall_err(api.nvim_set_keymap, 'n', '<tab>', 'rhs', { unique = true }) + ) + + api.nvim_set_keymap('ia', 'lhs', 'rhs', {}) + eq( + 'E226: Abbreviation already exists for lhs', + pcall_err(api.nvim_set_keymap, 'ia', 'lhs', 'rhs', { unique = true }) + ) end) it('can set <expr> mappings whose RHS change dynamically', function() diff --git a/test/functional/plugin/health_spec.lua b/test/functional/plugin/health_spec.lua index 3632774bff..58634460c8 100644 --- a/test/functional/plugin/health_spec.lua +++ b/test/functional/plugin/health_spec.lua @@ -86,7 +86,7 @@ describe('vim.health', function() end) describe(':checkhealth', function() - it('functions report_*() render correctly', function() + it('report_xx() renders correctly', function() command('checkhealth full_render') n.expect([[ @@ -94,15 +94,15 @@ describe('vim.health', function() test_plug.full_render: require("test_plug.full_render.health").check() report 1 ~ - - OK life is fine - - WARNING no what installed + - ✅ OK life is fine + - ⚠️ WARNING no what installed - ADVICE: - pip what - make what report 2 ~ - stuff is stable - - ERROR why no hardcopy + - ❌ ERROR why no hardcopy - ADVICE: - :help |:hardcopy| - :help |:TOhtml| @@ -117,25 +117,25 @@ describe('vim.health', function() test_plug: require("test_plug.health").check() report 1 ~ - - OK everything is fine + - ✅ OK everything is fine report 2 ~ - - OK nothing to see here + - ✅ OK nothing to see here ============================================================================== test_plug.success1: require("test_plug.success1.health").check() report 1 ~ - - OK everything is fine + - ✅ OK everything is fine report 2 ~ - - OK nothing to see here + - ✅ OK nothing to see here ============================================================================== test_plug.success2: require("test_plug.success2.health").check() another 1 ~ - - OK ok + - ✅ OK ok ]]) end) @@ -147,10 +147,10 @@ describe('vim.health', function() test_plug.submodule: require("test_plug.submodule.health").check() report 1 ~ - - OK everything is fine + - ✅ OK everything is fine report 2 ~ - - OK nothing to see here + - ✅ OK nothing to see here ]]) end) @@ -161,7 +161,7 @@ describe('vim.health', function() ============================================================================== test_plug.submodule_empty: require("test_plug.submodule_empty.health").check() - - ERROR The healthcheck report for "test_plug.submodule_empty" plugin is empty. + - ❌ ERROR The healthcheck report for "test_plug.submodule_empty" plugin is empty. ]]) end) @@ -182,13 +182,13 @@ describe('vim.health', function() {Bar: }| {h1:foo: }| | - - {Error:ERROR} No healthcheck found for "foo" plugin. | + - ❌ {Error:ERROR} No healthcheck found for "foo" plugin. | | {Bar: }| {h1:test_plug.success1: require("test_pl}| | {h2:report 1} | - - {Ok:OK} everything is fine | + - ✅ {Ok:OK} everything is fine | | ]], } @@ -202,11 +202,11 @@ describe('vim.health', function() ============================================================================== non_existent_healthcheck: - - ERROR No healthcheck found for "non_existent_healthcheck" plugin. + - ❌ ERROR No healthcheck found for "non_existent_healthcheck" plugin. ]]) end) - it('does not use vim.health as a healtcheck', function() + it('does not use vim.health as a healthcheck', function() -- vim.health is not a healthcheck command('checkhealth vim') n.expect([[ @@ -221,7 +221,7 @@ describe('vim.health', function() test_plug.lua: require("test_plug.lua.health").check() nested lua/ directory ~ - - OK everything is ok + - ✅ OK everything is ok ]]) end) @@ -239,19 +239,19 @@ describe('vim.health', function() nest: require("nest.health").check() healthy pack ~ - - OK healthy ok + - ✅ OK healthy ok ]]) end) end) end) -describe(':checkhealth provider', function() +describe(':checkhealth vim.provider', function() it("works correctly with a wrongly configured 'shell'", function() clear() command([[set shell=echo\ WRONG!!!]]) command('let g:loaded_perl_provider = 0') command('let g:loaded_python3_provider = 0') - command('checkhealth provider') + command('checkhealth vim.provider') eq(nil, string.match(curbuf_contents(), 'WRONG!!!')) end) end) @@ -285,10 +285,10 @@ describe(':checkhealth window', function() {h1:require("test_plug.success1.health").check()} | | {h2:report 1} | - - {32:OK} everything is fine | + - ✅ {32:OK} everything is fine | | {h2:report 2} | - - {32:OK} nothing to see here | + - ✅ {32:OK} nothing to see here | ## grid 3 | ]], @@ -328,12 +328,14 @@ describe(':checkhealth window', function() {h1:success1.health").check()}| | {h2:report 1} | - - {32:OK} everything is fine | + - ✅ {32:OK} everything is | + fine | | {h2:report 2} | - - {32:OK} nothing to see here | + - ✅ {32:OK} nothing to see | + here | | - {1:~ }|*3 + {1:~ }| ]]):format( left and '[4:-------------------------]│[2:------------------------]|*19' or '[2:------------------------]│[4:-------------------------]|*19', @@ -385,10 +387,10 @@ describe(':checkhealth window', function() require("test_plug.success1.health").check() | | report 1 | - - OK everything is fine | + - ✅ OK everything is fine | | report 2 | - - OK nothing to see here | + - ✅ OK nothing to see here | | ]]):format( top diff --git a/test/functional/plugin/lsp/inlay_hint_spec.lua b/test/functional/plugin/lsp/inlay_hint_spec.lua index e410a54c31..3ff190fb55 100644 --- a/test/functional/plugin/lsp/inlay_hint_spec.lua +++ b/test/functional/plugin/lsp/inlay_hint_spec.lua @@ -297,6 +297,50 @@ int main() { end) ) end) + + it('does not request hints from lsp when disabled', function() + exec_lua(function() + _G.server2 = _G._create_server({ + capabilities = { + inlayHintProvider = true, + }, + handlers = { + ['textDocument/inlayHint'] = function(_, _, callback) + _G.got_inlay_hint_request = true + callback(nil, {}) + end, + }, + }) + _G.client2 = vim.lsp.start({ name = 'dummy2', cmd = _G.server2.cmd }) + end) + + local function was_request_sent() + return exec_lua(function() + return _G.got_inlay_hint_request == true + end) + end + + eq(false, was_request_sent()) + + exec_lua(function() + vim.lsp.inlay_hint.get() + end) + + eq(false, was_request_sent()) + + exec_lua(function() + vim.lsp.inlay_hint.enable(false, { bufnr = bufnr }) + vim.lsp.inlay_hint.get() + end) + + eq(false, was_request_sent()) + + exec_lua(function() + vim.lsp.inlay_hint.enable(true, { bufnr = bufnr }) + end) + + eq(true, was_request_sent()) + end) end) end) diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 614c49a41f..856c086add 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -6414,5 +6414,40 @@ describe('LSP', function() filetypes = true, }, 'cannot start foo due to config error: .* filetypes: expected table, got boolean') end) + + it('does not start without workspace if workspace_required=true', function() + exec_lua(create_server_definition) + + local tmp1 = t.tmpname(true) + + eq( + { workspace_required = false }, + exec_lua(function() + local server = _G._create_server({ + handlers = { + initialize = function(_, _, callback) + callback(nil, { capabilities = {} }) + end, + }, + }) + + local ws_required = { cmd = server.cmd, workspace_required = true, filetypes = { 'foo' } } + local ws_not_required = vim.deepcopy(ws_required) + ws_not_required.workspace_required = false + + vim.lsp.config('ws_required', ws_required) + vim.lsp.config('ws_not_required', ws_not_required) + vim.lsp.enable('ws_required') + vim.lsp.enable('ws_not_required') + + vim.cmd.edit(assert(tmp1)) + vim.bo.filetype = 'foo' + + local clients = vim.lsp.get_clients({ bufnr = vim.api.nvim_get_current_buf() }) + assert(1 == #clients) + return { workspace_required = clients[1].config.workspace_required } + end) + ) + end) end) end) diff --git a/test/functional/treesitter/parser_spec.lua b/test/functional/treesitter/parser_spec.lua index b348f77b38..510eacb958 100644 --- a/test/functional/treesitter/parser_spec.lua +++ b/test/functional/treesitter/parser_spec.lua @@ -575,22 +575,22 @@ int x = INT_MAX; eq(5, exec_lua('return #parser:children().c:trees()')) eq({ { 0, 0, 7, 0 }, -- root tree + { 1, 26, 1, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) + { 2, 29, 2, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) { 3, 14, 3, 17 }, -- VALUE 123 { 4, 15, 4, 18 }, -- VALUE1 123 { 5, 15, 5, 18 }, -- VALUE2 123 - { 1, 26, 1, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) - { 2, 29, 2, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) }, get_ranges()) n.feed('ggo<esc>') eq(5, exec_lua('return #parser:children().c:trees()')) eq({ { 0, 0, 8, 0 }, -- root tree + { 2, 26, 2, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) + { 3, 29, 3, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) { 4, 14, 4, 17 }, -- VALUE 123 { 5, 15, 5, 18 }, -- VALUE1 123 { 6, 15, 6, 18 }, -- VALUE2 123 - { 2, 26, 2, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) - { 3, 29, 3, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) }, get_ranges()) end) end) @@ -613,11 +613,11 @@ int x = INT_MAX; eq(2, exec_lua('return #parser:children().c:trees()')) eq({ { 0, 0, 7, 0 }, -- root tree + { 1, 26, 2, 66 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) + -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) { 3, 14, 5, 18 }, -- VALUE 123 -- VALUE1 123 -- VALUE2 123 - { 1, 26, 2, 66 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) - -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) }, get_ranges()) n.feed('ggo<esc>') @@ -625,11 +625,11 @@ int x = INT_MAX; eq(2, exec_lua('return #parser:children().c:trees()')) eq({ { 0, 0, 8, 0 }, -- root tree - { 4, 14, 6, 18 }, -- VALUE 123 - -- VALUE1 123 - -- VALUE2 123 { 2, 26, 3, 66 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) + -- VALUE 123 + { 4, 14, 6, 18 }, -- VALUE1 123 + -- VALUE2 123 }, get_ranges()) n.feed('7ggI//<esc>') @@ -638,10 +638,10 @@ int x = INT_MAX; eq(2, exec_lua('return #parser:children().c:trees()')) eq({ { 0, 0, 8, 0 }, -- root tree - { 4, 14, 5, 18 }, -- VALUE 123 - -- VALUE1 123 { 2, 26, 3, 66 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) + -- VALUE 123 + { 4, 14, 5, 18 }, -- VALUE1 123 }, get_ranges()) end) @@ -794,22 +794,22 @@ int x = INT_MAX; eq(5, exec_lua('return #parser:children().c:trees()')) eq({ { 0, 0, 7, 0 }, -- root tree + { 1, 26, 1, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) + { 2, 29, 2, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) { 3, 14, 3, 17 }, -- VALUE 123 { 4, 15, 4, 18 }, -- VALUE1 123 { 5, 15, 5, 18 }, -- VALUE2 123 - { 1, 26, 1, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) - { 2, 29, 2, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) }, get_ranges()) n.feed('ggo<esc>') eq(5, exec_lua('return #parser:children().c:trees()')) eq({ { 0, 0, 8, 0 }, -- root tree + { 2, 26, 2, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) + { 3, 29, 3, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) { 4, 14, 4, 17 }, -- VALUE 123 { 5, 15, 5, 18 }, -- VALUE1 123 { 6, 15, 6, 18 }, -- VALUE2 123 - { 2, 26, 2, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) - { 3, 29, 3, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) }, get_ranges()) end) end) @@ -831,11 +831,11 @@ int x = INT_MAX; eq('table', exec_lua('return type(parser:children().c)')) eq({ { 0, 0, 7, 0 }, -- root tree + { 1, 26, 1, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) + { 2, 29, 2, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) { 3, 16, 3, 16 }, -- VALUE 123 { 4, 17, 4, 17 }, -- VALUE1 123 { 5, 17, 5, 17 }, -- VALUE2 123 - { 1, 26, 1, 63 }, -- READ_STRING(x, y) (char *)read_string((x), (size_t)(y)) - { 2, 29, 2, 66 }, -- READ_STRING_OK(x, y) (char *)read_string((x), (size_t)(y)) }, get_ranges()) end) it('should list all directives', function() diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua index cb9d978a0f..fb44c2ab52 100644 --- a/test/functional/ui/cmdline_spec.lua +++ b/test/functional/ui/cmdline_spec.lua @@ -858,7 +858,7 @@ local function test_cmdline(linegrid) cmdline = { { content = { { '' } }, - hl_id = 242, + hl_id = 243, pos = 0, prompt = 'Prompt:', }, @@ -886,7 +886,7 @@ local function test_cmdline(linegrid) }, cmdline_block = { { { 'if 1' } } }, }) - feed(':let x = 1<CR>') + feed('let x = 1<CR>') screen:expect({ grid = s1, cmdline = { @@ -897,20 +897,34 @@ local function test_cmdline(linegrid) pos = 0, }, }, - cmdline_block = { { { 'if 1' } }, { { ' :let x = 1' } } }, + cmdline_block = { { { 'if 1' } }, { { ' let x = 1' } } }, }) - feed(':endif') + feed('<CR>') + eq('let x = 1', eval('@:')) screen:expect({ grid = s1, cmdline = { { - content = { { ':endif' } }, + content = { { '' } }, firstc = ':', indent = 2, - pos = 6, + pos = 0, + }, + }, + cmdline_block = { { { 'if 1' } }, { { ' let x = 1' } }, { { ' ' } } }, + }) + feed('endif') + screen:expect({ + grid = s1, + cmdline = { + { + content = { { 'endif' } }, + firstc = ':', + indent = 2, + pos = 5, }, }, - cmdline_block = { { { 'if 1' } }, { { ' :let x = 1' } } }, + cmdline_block = { { { 'if 1' } }, { { ' let x = 1' } }, { { ' ' } } }, }) feed('<CR>') screen:expect({ @@ -1352,6 +1366,12 @@ describe('cmdline height', function() -- cmdheight unchanged. eq(1, eval('&cmdheight')) end) + + it('not increased to 0 from 1 with wincmd _', function() + command('set cmdheight=0 laststatus=0') + command('wincmd _') + eq(0, eval('&cmdheight')) + end) end) describe('cmdheight=0', function() diff --git a/test/functional/ui/cursor_spec.lua b/test/functional/ui/cursor_spec.lua index ff304db54c..087ae79eb1 100644 --- a/test/functional/ui/cursor_spec.lua +++ b/test/functional/ui/cursor_spec.lua @@ -258,11 +258,11 @@ describe('ui/cursor', function() end end if m.hl_id then - m.hl_id = 65 + m.hl_id = 66 m.attr = { background = Screen.colors.DarkGray } end if m.id_lm then - m.id_lm = 72 + m.id_lm = 73 m.attr_lm = {} end end diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index 639d43b560..5ef1ef54bb 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -2956,6 +2956,28 @@ describe('extmark decorations', function() {1:~ }|*3 | ]]) + -- No scrolling for concealed topline #33033 + api.nvim_buf_clear_namespace(0, ns, 0, -1) + api.nvim_buf_set_extmark(0, ns, 1, 0, { virt_lines_above = true, virt_lines = { { { "virt_above 2" } } } }) + api.nvim_buf_set_extmark(0, ns, 0, 0, { conceal_lines = "" }) + feed('ggjj') + screen:expect([[ + {2: }virt_above 2 | + {2: 2 } local text, hl_id_cell, count = unpack(ite| + {2: }m) | + {2: 3 }^ if hl_id_cell ~= nil then | + {2: 4 } hl_id = hl_id_cell | + {2: 5 }conceal text | + {2: 6 } for _ = 1, (count or 1) do | + {2: 7 } local cell = line[colpos] | + {2: 8 } cell.text = text | + {2: 9 } cell.hl_id = hl_id | + {2: 10 } colpos = colpos+1 | + {2: 11 } end | + {2: 12 }end | + {1:~ }| + | + ]]) end) end) diff --git a/test/functional/ui/diff_spec.lua b/test/functional/ui/diff_spec.lua index e0d88771d3..223622eb6b 100644 --- a/test/functional/ui/diff_spec.lua +++ b/test/functional/ui/diff_spec.lua @@ -1555,7 +1555,6 @@ it('diff mode overlapped diff blocks will be merged', function() local screen = Screen.new(35, 20) command('set winwidth=10 diffopt=filler,internal') - command('args Xdifile1 Xdifile2 | vert all | windo diffthis') WriteDiffFiles('a\nb', 'x\nx') @@ -2252,3 +2251,536 @@ it('diff mode does not scroll with line("w0")', function() 9 | ]]) end) + +-- oldtest: Test_diff_inline() +it('diff mode inline highlighting', function() + write_file('Xdifile1', '') + write_file('Xdifile2', '') + finally(function() + os.remove('Xdifile1') + os.remove('Xdifile2') + end) + + local screen = Screen.new(37, 20) + screen:add_extra_attr_ids({ + [100] = { background = Screen.colors.Blue1 }, + [101] = { bold = true, background = Screen.colors.Red, foreground = Screen.colors.Blue1 }, + [102] = { background = Screen.colors.LightMagenta, foreground = Screen.colors.Blue1 }, + [103] = { bold = true, background = Screen.colors.Blue1, foreground = Screen.colors.Blue1 }, + [104] = { bold = true, background = Screen.colors.LightBlue, foreground = Screen.colors.Blue1 }, + }) + command('set winwidth=10') + command('args Xdifile1 Xdifile2 | vert all | windo diffthis | 1wincmd w') + + WriteDiffFiles('abcdef ghi jk n\nx\ny', 'aBcef gHi lm n\ny\nz') + command('set diffopt=internal,filler') + local s1 = [[ + {7: }{4:^a}{27:bcdef ghi jk}{4: n }│{7: }{4:a}{27:Bcef gHi lm}{4: n }| + {7: }{22:x }│{7: }{23:----------------}| + {7: }y │{7: }y | + {7: }{23:----------------}│{7: }{22:z }| + {1:~ }│{1:~ }|*14 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]] + screen:expect(s1) + command('set diffopt=internal,filler diffopt+=inline:none') + local s2 = [[ + {7: }{4:^abcdef ghi jk n }│{7: }{4:aBcef gHi lm n }| + {7: }{22:x }│{7: }{23:----------------}| + {7: }y │{7: }y | + {7: }{23:----------------}│{7: }{22:z }| + {1:~ }│{1:~ }|*14 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]] + screen:expect(s2) + + -- inline:simple is the same as default + command('set diffopt=internal,filler diffopt+=inline:simple') + screen:expect(s1) + + command('set diffopt=internal,filler diffopt+=inline:char') + local s3 = [[ + {7: }{4:^a}{27:b}{4:c}{27:d}{4:ef g}{27:h}{4:i }{27:jk}{4: n }│{7: }{4:a}{27:B}{4:cef g}{27:H}{4:i }{27:lm}{4: n }| + {7: }{22:x }│{7: }{23:----------------}| + {7: }y │{7: }y | + {7: }{23:----------------}│{7: }{22:z }| + {1:~ }│{1:~ }|*14 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]] + screen:expect(s3) + + command('set diffopt=internal,filler diffopt+=inline:word') + screen:expect([[ + {7: }{27:^abcdef}{4: }{27:ghi}{4: }{27:jk}{4: n }│{7: }{27:aBcef}{4: }{27:gHi}{4: }{27:lm}{4: n }| + {7: }{22:x }│{7: }{23:----------------}| + {7: }y │{7: }y | + {7: }{23:----------------}│{7: }{22:z }| + {1:~ }│{1:~ }|*14 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + + -- multiple inline values will the last one + command('set diffopt=internal,filler diffopt+=inline:none,inline:char,inline:simple') + screen:expect(s1) + command('set diffopt=internal,filler diffopt+=inline:simple,inline:word,inline:none') + screen:expect(s2) + command('set diffopt=internal,filler diffopt+=inline:simple,inline:word,inline:char') + screen:expect(s3) + + -- DiffTextAdd highlight + command('hi DiffTextAdd guibg=blue') + command('set diffopt=internal,filler diffopt+=inline:char') + screen:expect([[ + {7: }{4:^a}{27:b}{4:c}{100:d}{4:ef g}{27:h}{4:i }{27:jk}{4: n }│{7: }{4:a}{27:B}{4:cef g}{27:H}{4:i }{27:lm}{4: n }| + {7: }{22:x }│{7: }{23:----------------}| + {7: }y │{7: }y | + {7: }{23:----------------}│{7: }{22:z }| + {1:~ }│{1:~ }|*14 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + + -- Live update in insert mode + feed('isometext') + screen:expect([[ + {7: }{27:sometext^abcd}{4:ef g}│{7: }{27:aBc}{4:ef g}{27:H}{4:i }{27:lm}{4: n }| + {7: }{22:x }│{7: }{23:----------------}| + {7: }y │{7: }y | + {7: }{23:----------------}│{7: }{22:z }| + {1:~ }│{1:~ }|*14 + {3:Xdifile1 [+] }{2:Xdifile2 }| + {5:-- INSERT --} | + ]]) + feed('<Esc>') + command('silent! undo') + + -- icase simple scenarios + command('set diffopt=internal,filler diffopt+=inline:simple,icase') + screen:expect([[ + {7: }{4:^abc}{27:def ghi jk}{4: n }│{7: }{4:aBc}{27:ef gHi lm}{4: n }| + {7: }{22:x }│{7: }{23:----------------}| + {7: }y │{7: }y | + {7: }{23:----------------}│{7: }{22:z }| + {1:~ }│{1:~ }|*14 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + command('set diffopt=internal,filler diffopt+=inline:char,icase') + screen:expect([[ + {7: }{4:^abc}{100:d}{4:ef ghi }{27:jk}{4: n }│{7: }{4:aBcef gHi }{27:lm}{4: n }| + {7: }{22:x }│{7: }{23:----------------}| + {7: }y │{7: }y | + {7: }{23:----------------}│{7: }{22:z }| + {1:~ }│{1:~ }|*14 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + command('set diffopt=internal,filler diffopt+=inline:word,icase') + screen:expect([[ + {7: }{27:^abcdef}{4: ghi }{27:jk}{4: n }│{7: }{27:aBcef}{4: gHi }{27:lm}{4: n }| + {7: }{22:x }│{7: }{23:----------------}| + {7: }y │{7: }y | + {7: }{23:----------------}│{7: }{22:z }| + {1:~ }│{1:~ }|*14 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + + screen:try_resize(45, 20) + command('wincmd =') + -- diff algorithms should affect highlight + WriteDiffFiles('apples and oranges', 'oranges and apples') + command('set diffopt=internal,filler diffopt+=inline:char') + screen:expect([[ + {7: }{27:^appl}{4:es and }{27:orang}{4:es }│{7: }{27:orang}{4:es and }{27:appl}{4:es }| + {1:~ }│{1:~ }|*17 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + command('set diffopt=internal,filler diffopt+=inline:char,algorithm:patience') + screen:expect([[ + {7: }{100:^apples and }{4:oranges }│{7: }{4:oranges}{100: and apples}{4: }| + {1:~ }│{1:~ }|*17 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + + screen:try_resize(65, 20) + command('wincmd =') + -- icase: composing chars and Unicode fold case edge cases + WriteDiffFiles( + '1 - sigma in 6σ and Ὀδυσσεύς\n1 - angstrom in åå\n1 - composing: ii⃗I⃗', + '2 - Sigma in 6Σ and ὈΔΥΣΣΕΎΣ\n2 - Angstrom in ÅÅ\n2 - Composing: i⃗I⃗I⃗' + ) + command('set diffopt=internal,filler diffopt+=inline:char') + screen:expect([[ + {7: }{27:^1}{4: - }{27:s}{4:igma in 6}{27:σ}{4: and Ὀ}{27:δυσσεύς}{4: }│{7: }{27:2}{4: - }{27:S}{4:igma in 6}{27:Σ}{4: and Ὀ}{27:ΔΥΣΣΕΎΣ}{4: }| + {7: }{27:1}{4: - }{27:a}{4:ngstrom in }{27:åå}{4: }│{7: }{27:2}{4: - }{27:A}{4:ngstrom in }{27:ÅÅ}{4: }| + {7: }{27:1}{4: - }{27:c}{4:omposing: }{100:i}{4:i⃗I⃗ }│{7: }{27:2}{4: - }{27:C}{4:omposing: i⃗I⃗}{100:I⃗}{4: }| + {1:~ }│{1:~ }|*15 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + command('set diffopt=internal,filler diffopt+=inline:char,icase') + screen:expect([[ + {7: }{27:^1}{4: - sigma in 6σ and Ὀδυσσεύς }│{7: }{27:2}{4: - Sigma in 6Σ and ὈΔΥΣΣΕΎΣ }| + {7: }{27:1}{4: - angstrom in åå }│{7: }{27:2}{4: - Angstrom in ÅÅ }| + {7: }{27:1}{4: - composing: }{27:i}{4:i⃗I⃗ }│{7: }{27:2}{4: - Composing: }{27:i⃗}{4:I⃗I⃗ }| + {1:~ }│{1:~ }|*15 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + + screen:try_resize(35, 20) + command('wincmd =') + -- wide chars + WriteDiffFiles('abc😅xde一\nf🚀g', 'abcy😢de\n二f🚀g') + command('set diffopt=internal,filler diffopt+=inline:char,icase') + screen:expect([[ + {7: }{4:^abc}{27:😅x}{4:de}{100:一}{4: }│{7: }{4:abc}{27:y😢}{4:de }| + {7: }{4:f🚀g }│{7: }{100:二}{4:f🚀g }| + {1:~ }│{1:~ }|*16 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + + -- NUL char + WriteDiffFiles('1\00034\0005\0006', '1234\0005\n6') + command('set diffopt=internal,filler diffopt+=inline:char') + screen:expect([[ + {7: }{4:^1}{101:^@}{4:34}{102:^@}{4:5}{101:^@}{4:6 }│{7: }{4:1}{27:2}{4:34}{102:^@}{4:5 }| + {7: }{23:---------------}│{7: }{4:6 }| + {1:~ }│{1:~ }|*16 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + + -- word diff: always use first buffer's iskeyword and ignore others' for consistency + WriteDiffFiles('foo+bar test', 'foo+baz test') + command('set diffopt=internal,filler diffopt+=inline:word') + local sw1 = [[ + {7: }{4:^foo+}{27:bar}{4: test }│{7: }{4:foo+}{27:baz}{4: test }| + {1:~ }│{1:~ }|*17 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]] + screen:expect(sw1) + + command('set iskeyword+=+ | diffupdate') + screen:expect([[ + {7: }{27:^foo+bar}{4: test }│{7: }{27:foo+baz}{4: test }| + {1:~ }│{1:~ }|*17 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + + command('set iskeyword& | wincmd w') + command('set iskeyword+=+ | wincmd w | diffupdate') + -- Use the previous screen as 2nd buffer's iskeyword does not matter + screen:expect(sw1) + + command('windo set iskeyword& | 1wincmd w') + + screen:try_resize(69, 20) + command('wincmd =') + -- char diff: should slide highlight to whitespace boundary if possible for + -- better readability (by using forced indent-heuristics). A wrong result + -- would be if the highlight is "Bar, prefix". It should be "prefixBar, " + -- instead. + WriteDiffFiles('prefixFoo, prefixEnd', 'prefixFoo, prefixBar, prefixEnd') + command('set diffopt=internal,filler diffopt+=inline:char') + screen:expect([[ + {7: }{4:^prefixFoo, prefixEnd }│{7: }{4:prefixFoo, }{100:prefixBar, }{4:prefixEnd }| + {1:~ }│{1:~ }|*17 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + + screen:try_resize(39, 20) + command('wincmd =') + -- char diff: small gaps between inline diff blocks will be merged during refine step + -- - first segment: test that we iteratively merge small gaps after we merged + -- adjacent blocks, but only with limited number (set to 4) of iterations. + -- - second and third segments: show that we need a large enough adjacent block to + -- trigger a merge. + -- - fourth segment: small gaps are not merged when adjacent large block is + -- on a different line. + WriteDiffFiles( + 'abcdefghijklmno\nanchor1\n' + .. 'abcdefghijklmno\nanchor2\n' + .. 'abcdefghijklmno\nanchor3\n' + .. 'test\nmultiline', + 'a?c?e?g?i?k???o\nanchor1\n' + .. 'a??de?????klmno\nanchor2\n' + .. 'a??de??????lmno\nanchor3\n' + .. 't?s?\n??????i?e' + ) + command('set diffopt=internal,filler diffopt+=inline:char') + screen:expect([[ + {7: }{4:^a}{27:b}{4:c}{27:defghijklmn}{4:o }│{7: }{4:a}{27:?}{4:c}{27:?e?g?i?k???}{4:o }| + {7: }anchor1 │{7: }anchor1 | + {7: }{4:a}{27:bc}{4:de}{27:fghij}{4:klmno }│{7: }{4:a}{27:??}{4:de}{27:?????}{4:klmno }| + {7: }anchor2 │{7: }anchor2 | + {7: }{4:a}{27:bcdefghijk}{4:lmno }│{7: }{4:a}{27:??de??????}{4:lmno }| + {7: }anchor3 │{7: }anchor3 | + {7: }{4:t}{27:e}{4:s}{27:t}{4: }│{7: }{4:t}{27:?}{4:s}{27:?}{4: }| + {7: }{27:multilin}{4:e }│{7: }{27:??????i?}{4:e }| + {1:~ }│{1:~ }|*10 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + + screen:try_resize(49, 20) + command('wincmd =') + -- Test multi-line blocks and whitespace + WriteDiffFiles( + 'this is \nsometest text foo\nbaz abc def \none\nword another word\nadditional line', + 'this is some test\ntexts\nfoo bar abX Yef \noneword another word' + ) + command('set diffopt=internal,filler diffopt+=inline:char,iwhite') + screen:expect([[ + {7: }{4:^this is }│{7: }{4:this is some}{100: }{4:test }| + {7: }{4:sometest text foo }│{7: }{4:text}{100:s}{4: }| + {7: }{4:ba}{27:z}{4: ab}{27:c}{4: }{27:d}{4:ef }│{7: }{4:foo ba}{27:r}{4: ab}{27:X}{4: }{27:Y}{4:ef }| + {7: }{4:one }│{7: }{4:oneword another word }| + {7: }{4:word another word }│{7: }{23:----------------------}| + {7: }{22:additional line }│{7: }{23:----------------------}| + {1:~ }│{1:~ }|*12 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + command('set diffopt=internal,filler diffopt+=inline:word,iwhite') + screen:expect([[ + {7: }{4:^this is }│{7: }{4:this is }{27:some}{4: }{27:test}{4: }| + {7: }{27:sometest}{4: }{27:text}{4: }{27:foo}{4: }│{7: }{27:texts}{4: }| + {7: }{27:baz}{4: }{27:abc}{4: }{27:def}{4: }│{7: }{27:foo}{4: }{27:bar}{4: }{27:abX}{4: }{27:Yef}{4: }| + {7: }{27:one}{4: }│{7: }{27:oneword}{4: another word }| + {7: }{27:word}{4: another word }│{7: }{23:----------------------}| + {7: }{22:additional line }│{7: }{23:----------------------}| + {1:~ }│{1:~ }|*12 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + command('set diffopt=internal,filler diffopt+=inline:char,iwhiteeol') + screen:expect([[ + {7: }{4:^this }{100: }{4:is }│{7: }{4:this is some}{100: }{4:test }| + {7: }{4:sometest text foo }│{7: }{4:text}{100:s}{4: }| + {7: }{4:ba}{27:z}{4: ab}{27:c}{4: }{27:d}{4:ef }│{7: }{4:foo ba}{27:r}{4: ab}{27:X}{4: }{27:Y}{4:ef }| + {7: }{4:one }│{7: }{4:oneword another word }| + {7: }{4:word another word }│{7: }{23:----------------------}| + {7: }{22:additional line }│{7: }{23:----------------------}| + {1:~ }│{1:~ }|*12 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + command('set diffopt=internal,filler diffopt+=inline:word,iwhiteeol') + screen:expect([[ + {7: }{4:^this }{100: }{4:is }│{7: }{4:this is }{27:some}{4: }{27:test}{4: }| + {7: }{27:sometest}{4: }{27:text}{4: foo }│{7: }{27:texts}{4: }| + {7: }{27:baz}{4: }{27:abc}{4: }{27:def}{4: }│{7: }{4:foo }{27:bar}{4: }{27:abX}{4: }{27:Yef}{4: }| + {7: }{27:one}{4: }│{7: }{27:oneword}{4: another word }| + {7: }{27:word}{4: another word }│{7: }{23:----------------------}| + {7: }{22:additional line }│{7: }{23:----------------------}| + {1:~ }│{1:~ }|*12 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + command('set diffopt=internal,filler diffopt+=inline:char,iwhiteall') + screen:expect([[ + {7: }{4:^this is }│{7: }{4:this is some test }| + {7: }{4:sometest text foo }│{7: }{4:text}{100:s}{4: }| + {7: }{4:ba}{27:z}{4: ab}{27:c d}{4:ef }│{7: }{4:foo ba}{27:r}{4: ab}{27:X Y}{4:ef }| + {7: }{4:one }│{7: }{4:oneword another word }| + {7: }{4:word another word }│{7: }{23:----------------------}| + {7: }{22:additional line }│{7: }{23:----------------------}| + {1:~ }│{1:~ }|*12 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + command('set diffopt=internal,filler diffopt+=inline:word,iwhiteall') + screen:expect([[ + {7: }{4:^this is }│{7: }{4:this is }{27:some test}{4: }| + {7: }{27:sometest text}{4: foo }│{7: }{27:texts}{4: }| + {7: }{27:baz abc def }{4: }│{7: }{4:foo }{27:bar abX Yef }{4: }| + {7: }{27:one}{4: }│{7: }{27:oneword}{4: another word }| + {7: }{27:word}{4: another word }│{7: }{23:----------------------}| + {7: }{22:additional line }│{7: }{23:----------------------}| + {1:~ }│{1:~ }|*12 + {3:Xdifile1 }{2:Xdifile2 }| + | + ]]) + + -- newline should be highlighted too when 'list' is set + command('windo set list listchars=eol:$') + command('set diffopt=internal,filler diffopt+=inline:char') + screen:expect([[ + {7: }{4:this }{100: }{4:is }{100: }{103:$}{4: }│{7: }{4:^this is some}{100: }{4:test}{101:$}{4: }| + {7: }{4:sometest}{27: }{4:text}{27: }{4:foo}{101:$}{4: }│{7: }{4:text}{27:s}{101:$}{4: }| + {7: }{4:ba}{27:z}{4: ab}{27:c}{4: }{27:d}{4:ef }{11:$}{4: }│{7: }{4:foo}{27: }{4:ba}{27:r}{4: ab}{27:X}{4: }{27:Y}{4:ef }{100: }{11:$}{4: }| + {7: }{4:one}{103:$}{4: }│{7: }{4:oneword another word}{11:$}{4: }| + {7: }{4:word another word}{11:$}{4: }│{7: }{23:----------------------}| + {7: }{22:additional line}{104:$}{22: }│{7: }{23:----------------------}| + {1:~ }│{1:~ }|*12 + {2:Xdifile1 }{3:Xdifile2 }| + | + ]]) + command('set diffopt=internal,filler diffopt+=inline:char,iwhite') + screen:expect([[ + {7: }{4:this is }{11:$}{4: }│{7: }{4:^this is some}{100: }{4:test}{11:$}{4: }| + {7: }{4:sometest text foo}{11:$}{4: }│{7: }{4:text}{100:s}{11:$}{4: }| + {7: }{4:ba}{27:z}{4: ab}{27:c}{4: }{27:d}{4:ef }{11:$}{4: }│{7: }{4:foo ba}{27:r}{4: ab}{27:X}{4: }{27:Y}{4:ef }{11:$}{4: }| + {7: }{4:one}{103:$}{4: }│{7: }{4:oneword another word}{11:$}{4: }| + {7: }{4:word another word}{11:$}{4: }│{7: }{23:----------------------}| + {7: }{22:additional line}{104:$}{22: }│{7: }{23:----------------------}| + {1:~ }│{1:~ }|*12 + {2:Xdifile1 }{3:Xdifile2 }| + | + ]]) + command('set diffopt=internal,filler diffopt+=inline:char,iwhiteeol') + screen:expect([[ + {7: }{4:this }{100: }{4:is }{11:$}{4: }│{7: }{4:^this is some}{100: }{4:test}{11:$}{4: }| + {7: }{4:sometest text foo}{11:$}{4: }│{7: }{4:text}{100:s}{11:$}{4: }| + {7: }{4:ba}{27:z}{4: ab}{27:c}{4: }{27:d}{4:ef }{11:$}{4: }│{7: }{4:foo ba}{27:r}{4: ab}{27:X}{4: }{27:Y}{4:ef }{11:$}{4: }| + {7: }{4:one}{103:$}{4: }│{7: }{4:oneword another word}{11:$}{4: }| + {7: }{4:word another word}{11:$}{4: }│{7: }{23:----------------------}| + {7: }{22:additional line}{104:$}{22: }│{7: }{23:----------------------}| + {1:~ }│{1:~ }|*12 + {2:Xdifile1 }{3:Xdifile2 }| + | + ]]) + command('set diffopt=internal,filler diffopt+=inline:char,iwhiteall') + screen:expect([[ + {7: }{4:this is }{11:$}{4: }│{7: }{4:^this is some test}{11:$}{4: }| + {7: }{4:sometest text foo}{11:$}{4: }│{7: }{4:text}{100:s}{11:$}{4: }| + {7: }{4:ba}{27:z}{4: ab}{27:c d}{4:ef }{11:$}{4: }│{7: }{4:foo ba}{27:r}{4: ab}{27:X Y}{4:ef }{11:$}{4: }| + {7: }{4:one}{11:$}{4: }│{7: }{4:oneword another word}{11:$}{4: }| + {7: }{4:word another word}{11:$}{4: }│{7: }{23:----------------------}| + {7: }{22:additional line}{104:$}{22: }│{7: }{23:----------------------}| + {1:~ }│{1:~ }|*12 + {2:Xdifile1 }{3:Xdifile2 }| + | + ]]) + command('windo set nolist') +end) + +-- oldtest: Test_diff_inline_multibuffer() +it('diff mode inline highlighting with 3 buffers', function() + write_file('Xdifile1', '') + write_file('Xdifile2', '') + write_file('Xdifile3', '') + finally(function() + os.remove('Xdifile1') + os.remove('Xdifile2') + os.remove('Xdifile3') + end) + + local screen = Screen.new(75, 20) + screen:add_extra_attr_ids({ + [100] = { background = Screen.colors.Blue1 }, + }) + command('args Xdifile1 Xdifile2 Xdifile3 | vert all | windo diffthis | 1wincmd w') + command('wincmd =') + command('hi DiffTextAdd guibg=Blue') + + WriteDiffFiles3( + 'That is buffer1.\nanchor\nSome random text\nanchor', + 'This is buffer2.\nanchor\nSome text\nanchor\nbuffer2/3', + 'This is buffer3. Last.\nanchor\nSome more\ntext here.\nanchor\nonly in buffer2/3\nnot in buffer1' + ) + command('set diffopt=internal,filler diffopt+=inline:char') + local s1 = [[ + {7: }{4:^Th}{27:at}{4: is buffer}{27:1}{4:. }│{7: }{4:Th}{27:is}{4: is buffer}{27:2}{4:. }│{7: }{4:Th}{27:is}{4: is buffer}{27:3. Last}{4:.}| + {7: }anchor │{7: }anchor │{7: }anchor | + {7: }{4:Some }{27:random }{4:text }│{7: }{4:Some text }│{7: }{4:Some }{27:more}{4: }| + {7: }{23:-----------------------}│{7: }{23:----------------------}│{7: }{4:text}{100: here.}{4: }| + {7: }anchor │{7: }anchor │{7: }anchor | + {7: }{23:-----------------------}│{7: }{4:buffer2/3 }│{7: }{100:only in }{4:buffer2/3 }| + {7: }{23:-----------------------}│{7: }{23:----------------------}│{7: }{22:not in buffer1 }| + {1:~ }│{1:~ }│{1:~ }|*11 + {3:Xdifile1 }{2:Xdifile2 Xdifile3 }| + | + ]] + screen:expect(s1) + + -- Close one of the buffers and make sure it updates correctly + command('diffoff') + screen:expect([[ + ^That is buffer1. │{7: }{4:This is buffer}{27:2}{4:. }│{7: }{4:This is buffer}{27:3. Last}{4:.}| + anchor │{7: }anchor │{7: }anchor | + Some random text │{7: }{4:Some text }│{7: }{4:Some }{100:more}{4: }| + anchor │{7: }{23:----------------------}│{7: }{4:text}{100: here.}{4: }| + {1:~ }│{7: }anchor │{7: }anchor | + {1:~ }│{7: }{4:buffer2/3 }│{7: }{100:only in }{4:buffer2/3 }| + {1:~ }│{7: }{23:----------------------}│{7: }{22:not in buffer1 }| + {1:~ }│{1:~ }│{1:~ }|*11 + {3:Xdifile1 }{2:Xdifile2 Xdifile3 }| + | + ]]) + + -- Update text in the non-diff buffer and nothing should be changed + feed('isometext') + screen:expect([[ + sometext^That is buffer1. │{7: }{4:This is buffer}{27:2}{4:. }│{7: }{4:This is buffer}{27:3. Last}{4:.}| + anchor │{7: }anchor │{7: }anchor | + Some random text │{7: }{4:Some text }│{7: }{4:Some }{100:more}{4: }| + anchor │{7: }{23:----------------------}│{7: }{4:text}{100: here.}{4: }| + {1:~ }│{7: }anchor │{7: }anchor | + {1:~ }│{7: }{4:buffer2/3 }│{7: }{100:only in }{4:buffer2/3 }| + {1:~ }│{7: }{23:----------------------}│{7: }{22:not in buffer1 }| + {1:~ }│{1:~ }│{1:~ }|*11 + {3:Xdifile1 [+] }{2:Xdifile2 Xdifile3 }| + {5:-- INSERT --} | + ]]) + feed('<Esc>') + command('silent! undo') + + command('diffthis') + screen:expect(s1) + + -- Test that removing first buffer from diff will in turn use the next + -- earliest buffer's iskeyword during word diff. + WriteDiffFiles3('This+is=a-setence', 'This+is=another-setence', 'That+is=a-setence') + command('set iskeyword+=+ | 2wincmd w | set iskeyword+=- | 1wincmd w') + command('set diffopt=internal,filler diffopt+=inline:word') + local s4 = [[ + {7: }{27:^This+is}{4:=}{27:a}{4:-setence }│{7: }{27:This+is}{4:=}{27:another}{4:-setenc}│{7: }{27:That+is}{4:=}{27:a}{4:-setence }| + {1:~ }│{1:~ }│{1:~ }|*17 + {3:Xdifile1 }{2:Xdifile2 Xdifile3 }| + | + ]] + screen:expect(s4) + command('diffoff') + screen:expect([[ + ^This+is=a-setence │{7: }{27:This}{4:+is=}{27:another-setenc}│{7: }{27:That}{4:+is=}{27:a-setence}{4: }| + {1:~ }│{1:~ }│{1:~ }|*17 + {3:Xdifile1 }{2:Xdifile2 Xdifile3 }| + | + ]]) + command('diffthis') + screen:expect(s4) + + -- Test multi-buffer char diff refinement, and that removing a buffer from + -- diff will update the others properly. + WriteDiffFiles3('abcdefghijkYmYYY', 'aXXdXXghijklmnop', 'abcdefghijkYmYop') + command('set diffopt=internal,filler diffopt+=inline:char') + local s6 = [[ + {7: }{4:^a}{27:bcdef}{4:ghijk}{27:YmYYY}{4: }│{7: }{4:a}{27:XXdXX}{4:ghijk}{27:lmnop}{4: }│{7: }{4:a}{27:bcdef}{4:ghijk}{27:YmYop}{4: }| + {1:~ }│{1:~ }│{1:~ }|*17 + {3:Xdifile1 }{2:Xdifile2 Xdifile3 }| + | + ]] + screen:expect(s6) + command('diffoff') + screen:expect([[ + ^abcdefghijkYmYYY │{7: }{4:a}{27:XXdXX}{4:ghijk}{27:l}{4:m}{27:n}{4:op }│{7: }{4:a}{27:bcdef}{4:ghijk}{27:Y}{4:m}{27:Y}{4:op }| + {1:~ }│{1:~ }│{1:~ }|*17 + {3:Xdifile1 }{2:Xdifile2 Xdifile3 }| + | + ]]) + command('diffthis') + screen:expect(s6) +end) diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua index 9b01150411..94faafa9be 100644 --- a/test/functional/ui/messages_spec.lua +++ b/test/functional/ui/messages_spec.lua @@ -229,11 +229,11 @@ describe('ui/ext_messages', function() { content = { { '\n@character ' }, - { 'xxx', 26, 155 }, + { 'xxx', 26, 156 }, { ' ' }, { 'links to', 18, 5 }, { ' Character\n@character.special ' }, - { 'xxx', 16, 156 }, + { 'xxx', 16, 157 }, { ' ' }, { 'links to', 18, 5 }, { ' SpecialChar' }, @@ -300,7 +300,7 @@ describe('ui/ext_messages', function() cmdline = { { abort = false } }, messages = { { - content = { { 'Error', 9, 6 }, { 'Message', 16, 99 } }, + content = { { 'Error', 9, 6 }, { 'Message', 16, 100 } }, history = true, kind = 'echoerr', }, @@ -940,7 +940,7 @@ describe('ui/ext_messages', function() ^ | {1:~ }|*4 ]], - ruler = { { '0,0-1 All', 9, 61 } }, + ruler = { { '0,0-1 All', 9, 62 } }, }) command('hi clear MsgArea') feed('i') diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua index 3ee4d429c7..90b3094082 100644 --- a/test/functional/ui/mouse_spec.lua +++ b/test/functional/ui/mouse_spec.lua @@ -1719,6 +1719,20 @@ describe('ui/mouse/input', function() ]]) end) + it("mouse click on window separator in statusline doesn't crash", function() + api.nvim_set_option_value('winwidth', 1, {}) + api.nvim_set_option_value('statusline', '%f', {}) + + command('vsplit') + command('redraw') + + local lines = api.nvim_get_option_value('lines', {}) + local columns = api.nvim_get_option_value('columns', {}) + + api.nvim_input_mouse('left', 'press', '', 0, lines - 1, math.floor(columns / 2)) + command('redraw') + end) + it('getmousepos() works correctly', function() local winwidth = api.nvim_get_option_value('winwidth', {}) -- Set winwidth=1 so that window sizes don't change. diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua index 9403f39ba1..c73cec22a0 100644 --- a/test/functional/ui/popupmenu_spec.lua +++ b/test/functional/ui/popupmenu_spec.lua @@ -5478,7 +5478,489 @@ describe('builtin popupmenu', function() end end) - it('does not crash when displayed in the last column with rightleft #12032', function() + -- oldtest: Test_pum_maxwidth() + it('"pummaxwidth"', function() + screen:try_resize(60, 8) + api.nvim_buf_set_lines(0, 0, -1, true, { + '123456789_123456789_123456789_a', + '123456789_123456789_123456789_b', + ' 123', + }) + feed('G"zyy') + feed('A<C-X><C-N>') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:------------------------------------------------------------]|*7 + [3:------------------------------------------------------------]| + ## grid 2 + 123456789_123456789_123456789_a | + 123456789_123456789_123456789_b | + 123456789_123456789_123456789_a^ | + {1:~ }|*4 + ## grid 3 + {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} | + ## grid 4 + {s: 123456789_123456789_123456789_a }| + {n: 123456789_123456789_123456789_b }| + ]], + float_pos = { [4] = { -1, 'NW', 2, 3, 11, false, 100 } }, + }) + else + screen:expect([[ + 123456789_123456789_123456789_a | + 123456789_123456789_123456789_b | + 123456789_123456789_123456789_a^ | + {1:~ }{s: 123456789_123456789_123456789_a }{1: }| + {1:~ }{n: 123456789_123456789_123456789_b }{1: }| + {1:~ }|*2 + {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} | + ]]) + end + feed('<Esc>3Gdd"zp') + + command('set pummaxwidth=10') + feed('GA<C-X><C-N>') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:------------------------------------------------------------]|*7 + [3:------------------------------------------------------------]| + ## grid 2 + 123456789_123456789_123456789_a | + 123456789_123456789_123456789_b | + 123456789_123456789_123456789_a^ | + {1:~ }|*4 + ## grid 3 + {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} | + ## grid 4 + {s: 1234567...}| + {n: 1234567...}| + ]], + float_pos = { [4] = { -1, 'NW', 2, 3, 11, false, 100 } }, + }) + else + screen:expect([[ + 123456789_123456789_123456789_a | + 123456789_123456789_123456789_b | + 123456789_123456789_123456789_a^ | + {1:~ }{s: 1234567...}{1: }| + {1:~ }{n: 1234567...}{1: }| + {1:~ }|*2 + {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} | + ]]) + end + feed('<Esc>3Gdd"zp') + + command('set pummaxwidth=20') + feed('GA<C-X><C-N>') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:------------------------------------------------------------]|*7 + [3:------------------------------------------------------------]| + ## grid 2 + 123456789_123456789_123456789_a | + 123456789_123456789_123456789_b | + 123456789_123456789_123456789_a^ | + {1:~ }|*4 + ## grid 3 + {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} | + ## grid 4 + {s: 123456789_1234567...}| + {n: 123456789_1234567...}| + ]], + float_pos = { [4] = { -1, 'NW', 2, 3, 11, false, 100 } }, + }) + else + screen:expect([[ + 123456789_123456789_123456789_a | + 123456789_123456789_123456789_b | + 123456789_123456789_123456789_a^ | + {1:~ }{s: 123456789_1234567...}{1: }| + {1:~ }{n: 123456789_1234567...}{1: }| + {1:~ }|*2 + {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} | + ]]) + end + feed('<Esc>3Gdd"zp') + + command('set pumwidth=20 pummaxwidth=8') + feed('GA<C-X><C-N>') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:------------------------------------------------------------]|*7 + [3:------------------------------------------------------------]| + ## grid 2 + 123456789_123456789_123456789_a | + 123456789_123456789_123456789_b | + 123456789_123456789_123456789_a^ | + {1:~ }|*4 + ## grid 3 + {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} | + ## grid 4 + {s: 12345...}| + {n: 12345...}| + ]], + float_pos = { [4] = { -1, 'NW', 2, 3, 11, false, 100 } }, + }) + else + screen:expect([[ + 123456789_123456789_123456789_a | + 123456789_123456789_123456789_b | + 123456789_123456789_123456789_a^ | + {1:~ }{s: 12345...}{1: }| + {1:~ }{n: 12345...}{1: }| + {1:~ }|*2 + {2:-- Keyword Local completion (^N^P) }{5:match 1 of 2} | + ]]) + end + feed('<Esc>3Gdd"zp') + + screen:try_resize(32, 10) + feed('GA<C-X><C-N>') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*9 + [3:--------------------------------]| + ## grid 2 + 123456789_123456789_123456789_a | + 123456789_123456789_123456789_b | + 123456789_123456789_| + 123456789_a^ | + {1:~ }|*5 + ## grid 3 + {2:-- }{5:match 1 of 2} | + ## grid 4 + {s: 12345...}| + {n: 12345...}| + ]], + float_pos = { [4] = { -1, 'NW', 2, 4, 11, false, 100 } }, + }) + else + screen:expect([[ + 123456789_123456789_123456789_a | + 123456789_123456789_123456789_b | + 123456789_123456789_| + 123456789_a^ | + {1:~ }{s: 12345...}{1: }| + {1:~ }{n: 12345...}{1: }| + {1:~ }|*3 + {2:-- }{5:match 1 of 2} | + ]]) + end + feed('<Esc>3Gdd"zp') + end) + + -- oldtest: Test_pum_maxwidth_multibyte() + it("'pummaxwidth' with multibyte", function() + screen:try_resize(60, 8) + exec([[ + func Omni_test(findstart, base) + if a:findstart + return col(".") + endif + return [ + \ #{word: "123456789_123456789_123456789_"}, + \ #{word: "一二三四五六七八九十"}, + \ #{word: "abcdefghij"}, + \ #{word: "上下左右"}, + \ ] + endfunc + set omnifunc=Omni_test + ]]) + + feed('S<C-X><C-O>') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:------------------------------------------------------------]|*7 + [3:------------------------------------------------------------]| + ## grid 2 + 123456789_123456789_123456789_^ | + {1:~ }|*6 + ## grid 3 + {2:-- Omni completion (^O^N^P) }{5:match 1 of 4} | + ## grid 4 + {s:123456789_123456789_123456789_ }| + {n:一二三四五六七八九十 }| + {n:abcdefghij }| + {n:上下左右 }| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100 } }, + }) + else + screen:expect([[ + 123456789_123456789_123456789_^ | + {s:123456789_123456789_123456789_ }{1: }| + {n:一二三四五六七八九十 }{1: }| + {n:abcdefghij }{1: }| + {n:上下左右 }{1: }| + {1:~ }|*2 + {2:-- Omni completion (^O^N^P) }{5:match 1 of 4} | + ]]) + end + feed('<Esc>') + + command('set pummaxwidth=10') + feed('S<C-X><C-O>') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:------------------------------------------------------------]|*7 + [3:------------------------------------------------------------]| + ## grid 2 + 123456789_123456789_123456789_^ | + {1:~ }|*6 + ## grid 3 + {2:-- Omni completion (^O^N^P) }{5:match 1 of 4} | + ## grid 4 + {s:1234567...}| + {n:一二三 ...}| + {n:abcdefghij}| + {n:上下左右 }| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100 } }, + }) + else + screen:expect([[ + 123456789_123456789_123456789_^ | + {s:1234567...}{1: }| + {n:一二三 ...}{1: }| + {n:abcdefghij}{1: }| + {n:上下左右 }{1: }| + {1:~ }|*2 + {2:-- Omni completion (^O^N^P) }{5:match 1 of 4} | + ]]) + end + feed('<Esc>') + + command('set rightleft') + feed('S<C-X><C-O>') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:------------------------------------------------------------]|*7 + [3:------------------------------------------------------------]| + ## grid 2 + ^ _987654321_987654321_987654321| + {1: ~}|*6 + ## grid 3 + {2:-- Omni completion (^O^N^P) }{5:match 1 of 4} | + ## grid 4 + {s:...7654321}| + {n:... 三二一}| + {n:jihgfedcba}| + {n: 右左下上}| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 50, false, 100 } }, + }) + else + screen:expect([[ + ^ _987654321_987654321_987654321| + {1: }{s:...7654321}| + {1: }{n:... 三二一}| + {1: }{n:jihgfedcba}| + {1: }{n: 右左下上}| + {1: ~}|*2 + {2:-- Omni completion (^O^N^P) }{5:match 1 of 4} | + ]]) + end + feed('<Esc>') + command('set norightleft') + + command('set pummaxwidth=2') + feed('S<C-X><C-O>') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:------------------------------------------------------------]|*7 + [3:------------------------------------------------------------]| + ## grid 2 + 123456789_123456789_123456789_^ | + {1:~ }|*6 + ## grid 3 + {2:-- Omni completion (^O^N^P) }{5:match 1 of 4} | + ## grid 4 + {s:12}| + {n:一}| + {n:ab}| + {n:上}| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100 } }, + }) + else + screen:expect([[ + 123456789_123456789_123456789_^ | + {s:12}{1: }| + {n:一}{1: }| + {n:ab}{1: }| + {n:上}{1: }| + {1:~ }|*2 + {2:-- Omni completion (^O^N^P) }{5:match 1 of 4} | + ]]) + end + feed('<Esc>') + end) + + it([['pummaxwidth' works with "kind" and "menu"]], function() + exec([[ + func Omni_test(findstart, base) + if a:findstart + return col(".") + endif + return [ + \ #{word: "foo", menu: "fooMenu", kind: "fooKind"}, + \ #{word: "bar", menu: "barMenu", kind: "barKind"}, + \ #{word: "baz", menu: "bazMenu", kind: "bazKind"}, + \ ] + endfunc + set omnifunc=Omni_test + ]]) + + command('set pummaxwidth=14') + feed('S<C-X><C-O>') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*19 + [3:--------------------------------]| + ## grid 2 + foo^ | + {1:~ }|*18 + ## grid 3 + {2:-- }{5:match 1 of 3} | + ## grid 4 + {s:foo fooKind...}| + {n:bar barKind...}| + {n:baz bazKind...}| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100 } }, + }) + else + screen:expect([[ + foo^ | + {s:foo fooKind...}{1: }| + {n:bar barKind...}{1: }| + {n:baz bazKind...}{1: }| + {1:~ }|*15 + {2:-- }{5:match 1 of 3} | + ]]) + end + feed('<Esc>') + + command('set rightleft') + feed('S<C-X><C-O>') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*19 + [3:--------------------------------]| + ## grid 2 + ^ oof| + {1: ~}|*18 + ## grid 3 + {2:-- }{5:match 1 of 3} | + ## grid 4 + {s:...dniKoof oof}| + {n:...dniKrab rab}| + {n:...dniKzab zab}| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 18, false, 100 } }, + }) + else + screen:expect([[ + ^ oof| + {1: }{s:...dniKoof oof}| + {1: }{n:...dniKrab rab}| + {1: }{n:...dniKzab zab}| + {1: ~}|*15 + {2:-- }{5:match 1 of 3} | + ]]) + end + feed('<Esc>') + command('set norightleft') + + command('set pummaxwidth=13') + feed('S<C-X><C-O>') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*19 + [3:--------------------------------]| + ## grid 2 + foo^ | + {1:~ }|*18 + ## grid 3 + {2:-- }{5:match 1 of 3} | + ## grid 4 + {s:foo fooKin...}| + {n:bar barKin...}| + {n:baz bazKin...}| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100 } }, + }) + else + screen:expect([[ + foo^ | + {s:foo fooKin...}{1: }| + {n:bar barKin...}{1: }| + {n:baz bazKin...}{1: }| + {1:~ }|*15 + {2:-- }{5:match 1 of 3} | + ]]) + end + feed('<Esc>') + + command('set rightleft') + feed('S<C-X><C-O>') + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*19 + [3:--------------------------------]| + ## grid 2 + ^ oof| + {1: ~}|*18 + ## grid 3 + {2:-- }{5:match 1 of 3} | + ## grid 4 + {s:...niKoof oof}| + {n:...niKrab rab}| + {n:...niKzab zab}| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 19, false, 100 } }, + }) + else + screen:expect([[ + ^ oof| + {1: }{s:...niKoof oof}| + {1: }{n:...niKrab rab}| + {1: }{n:...niKzab zab}| + {1: ~}|*15 + {2:-- }{5:match 1 of 3} | + ]]) + end + feed('<Esc>') + command('set norightleft') + end) + + it('does not crash when displayed in last column with rightleft #12032', function() local col = 30 local items = { 'word', 'choice', 'text', 'thing' } local max_len = 0 @@ -5498,31 +5980,115 @@ describe('builtin popupmenu', function() screen:try_resize(32, 8) command('set completeopt+=menuone,noselect') feed('i' .. string.rep(' ', 13)) - fn.complete(14, { '哦哦哦哦哦哦哦哦哦哦' }) + + fn.complete(14, { '一二三四五六七八九十' }) if multigrid then screen:expect({ grid = [[ - ## grid 1 - [2:--------------------------------]|*7 - [3:--------------------------------]| - ## grid 2 - ^ | - {1:~ }|*6 - ## grid 3 - {2:-- INSERT --} | - ## grid 4 - {n: 哦哦哦哦哦哦哦哦哦>}| + ## grid 1 + [2:--------------------------------]|*7 + [3:--------------------------------]| + ## grid 2 + ^ | + {1:~ }|*6 + ## grid 3 + {2:-- INSERT --} | + ## grid 4 + {n: 一二三四五六七八九>}| ]], float_pos = { [4] = { -1, 'NW', 2, 1, 12, false, 100 } }, }) else screen:expect([[ ^ | - {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}| + {1:~ }{n: 一二三四五六七八九>}| {1:~ }|*5 {2:-- INSERT --} | ]]) end + feed('<C-E>') + + fn.complete(14, { { word = '一二三', kind = '四五六', menu = '七八九十' } }) + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*7 + [3:--------------------------------]| + ## grid 2 + ^ | + {1:~ }|*6 + ## grid 3 + {2:-- INSERT --} | + ## grid 4 + {n: 一二三 四五六 七八>}| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 12, false, 100 } }, + }) + else + screen:expect([[ + ^ | + {1:~ }{n: 一二三 四五六 七八>}| + {1:~ }|*5 + {2:-- INSERT --} | + ]]) + end + feed('<C-E>') + + command('set rightleft') + fn.complete(14, { '一二三四五六七八九十' }) + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*7 + [3:--------------------------------]| + ## grid 2 + ^ | + {1: ~}|*6 + ## grid 3 + {2:-- INSERT --} | + ## grid 4 + {n:<九八七六五四三二一 }| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100 } }, + }) + else + screen:expect([[ + ^ | + {n:<九八七六五四三二一 }{1: ~}| + {1: ~}|*5 + {2:-- INSERT --} | + ]]) + end + feed('<C-E>') + + fn.complete(14, { { word = '一二三', kind = '四五六', menu = '七八九十' } }) + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*7 + [3:--------------------------------]| + ## grid 2 + ^ | + {1: ~}|*6 + ## grid 3 + {2:-- INSERT --} | + ## grid 4 + {n:<八七 六五四 三二一 }| + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100 } }, + }) + else + screen:expect([[ + ^ | + {n:<八七 六五四 三二一 }{1: ~}| + {1: ~}|*5 + {2:-- INSERT --} | + ]]) + end + feed('<C-E>') end) it('truncates double-width character correctly with scrollbar', function() @@ -5530,37 +6096,140 @@ describe('builtin popupmenu', function() command('set completeopt+=noselect') command('set pumheight=4') feed('i' .. string.rep(' ', 12)) - local items = {} + local items1 = {} + local items2 = {} for _ = 1, 8 do - table.insert(items, { word = '哦哦哦哦哦哦哦哦哦哦', equal = 1, dup = 1 }) + table.insert(items1, { word = '一二三四五六七八九十', equal = 1, dup = 1 }) end - fn.complete(13, items) + for _ = 1, 2 do + table.insert( + items2, + { word = 'abcdef', kind = 'ghijkl', menu = 'mnopqrst', equal = 1, dup = 1 } + ) + end + for _ = 3, 8 do + table.insert( + items2, + { word = '一二三', kind = '四五六', menu = '七八九十', equal = 1, dup = 1 } + ) + end + + fn.complete(13, items1) if multigrid then screen:expect({ grid = [[ - ## grid 1 - [2:--------------------------------]|*7 - [3:--------------------------------]| - ## grid 2 - ^ | - {1:~ }|*6 - ## grid 3 - {2:-- INSERT --} | - ## grid 4 - {n: 哦哦哦哦哦哦哦哦哦>}{c: }|*2 - {n: 哦哦哦哦哦哦哦哦哦>}{s: }|*2 + ## grid 1 + [2:--------------------------------]|*7 + [3:--------------------------------]| + ## grid 2 + ^ | + {1:~ }|*6 + ## grid 3 + {2:-- INSERT --} | + ## grid 4 + {n: 一二三四五六七八九>}{c: }|*2 + {n: 一二三四五六七八九>}{s: }|*2 + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 11, false, 100 } }, + }) + else + screen:expect([[ + ^ | + {1:~ }{n: 一二三四五六七八九>}{c: }|*2 + {1:~ }{n: 一二三四五六七八九>}{s: }|*2 + {1:~ }|*2 + {2:-- INSERT --} | + ]]) + end + feed('<C-E>') + + fn.complete(13, items2) + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*7 + [3:--------------------------------]| + ## grid 2 + ^ | + {1:~ }|*6 + ## grid 3 + {2:-- INSERT --} | + ## grid 4 + {n: abcdef ghijkl mnopq}{c: }|*2 + {n: 一二三 四五六 七八>}{s: }|*2 ]], float_pos = { [4] = { -1, 'NW', 2, 1, 11, false, 100 } }, }) else screen:expect([[ ^ | - {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{c: }|*2 - {1:~ }{n: 哦哦哦哦哦哦哦哦哦>}{s: }|*2 + {1:~ }{n: abcdef ghijkl mnopq}{c: }|*2 + {1:~ }{n: 一二三 四五六 七八>}{s: }|*2 {1:~ }|*2 {2:-- INSERT --} | ]]) end + feed('<C-E>') + + command('set rightleft') + fn.complete(13, items1) + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*7 + [3:--------------------------------]| + ## grid 2 + ^ | + {1: ~}|*6 + ## grid 3 + {2:-- INSERT --} | + ## grid 4 + {c: }{n:<九八七六五四三二一 }|*2 + {s: }{n:<九八七六五四三二一 }|*2 + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100 } }, + }) + else + screen:expect([[ + ^ | + {c: }{n:<九八七六五四三二一 }{1: ~}|*2 + {s: }{n:<九八七六五四三二一 }{1: ~}|*2 + {1: ~}|*2 + {2:-- INSERT --} | + ]]) + end + feed('<C-E>') + + fn.complete(13, items2) + if multigrid then + screen:expect({ + grid = [[ + ## grid 1 + [2:--------------------------------]|*7 + [3:--------------------------------]| + ## grid 2 + ^ | + {1: ~}|*6 + ## grid 3 + {2:-- INSERT --} | + ## grid 4 + {c: }{n:qponm lkjihg fedcba }|*2 + {s: }{n:<八七 六五四 三二一 }|*2 + ]], + float_pos = { [4] = { -1, 'NW', 2, 1, 0, false, 100 } }, + }) + else + screen:expect([[ + ^ | + {c: }{n:qponm lkjihg fedcba }{1: ~}|*2 + {s: }{n:<八七 六五四 三二一 }{1: ~}|*2 + {1: ~}|*2 + {2:-- INSERT --} | + ]]) + end + feed('<C-E>') end) it('supports mousemodel=popup', function() diff --git a/test/old/testdir/gen_opt_test.vim b/test/old/testdir/gen_opt_test.vim index 2127945624..fb0af3de0a 100644 --- a/test/old/testdir/gen_opt_test.vim +++ b/test/old/testdir/gen_opt_test.vim @@ -214,10 +214,12 @@ let test_values = { \ 'closeoff', 'hiddenoff', 'foldcolumn:0', 'foldcolumn:12', \ 'followwrap', 'internal', 'indent-heuristic', 'algorithm:myers', \ 'icase,iwhite', 'algorithm:minimal', 'algorithm:patience', - \ 'algorithm:histogram', 'linematch:5'], + \ 'algorithm:histogram', 'inline:none', 'inline:simple', + \ 'inline:char', 'inline:word', 'inline:char,inline:word', 'linematch:5'], \ ['xxx', 'foldcolumn:', 'foldcolumn:x', 'foldcolumn:xxx', \ 'linematch:', 'linematch:x', 'linematch:xxx', 'algorithm:', - \ 'algorithm:xxx', 'context:', 'context:x', 'context:xxx']], + \ 'algorithm:xxx', 'context:', 'context:x', 'context:xxx', + \ 'inline:xxx']], \ 'display': [['', 'lastline', 'truncate', 'uhex', 'lastline,uhex'], \ ['xxx']], \ 'eadirection': [['both', 'ver', 'hor'], ['xxx', 'ver,hor']], diff --git a/test/old/testdir/setup.vim b/test/old/testdir/setup.vim index 87287a57ff..c077eb021a 100644 --- a/test/old/testdir/setup.vim +++ b/test/old/testdir/setup.vim @@ -3,7 +3,7 @@ if exists('s:did_load') set commentstring=/*\ %s\ */ set complete=.,w,b,u,t,i set define=^\\s*#\\s*define - set diffopt=internal,filler,closeoff + set diffopt=internal,filler,closeoff,inline:simple set directory^=. set display= set fillchars=vert:\|,foldsep:\|,fold:- diff --git a/test/old/testdir/test_diffmode.vim b/test/old/testdir/test_diffmode.vim index 0d20085360..6a5054b37b 100644 --- a/test/old/testdir/test_diffmode.vim +++ b/test/old/testdir/test_diffmode.vim @@ -430,13 +430,13 @@ endfunc func Common_icase_test() edit one - call setline(1, ['One', 'Two', 'Three', 'Four', 'Fi#ve']) + call setline(1, ['One', 'Two', 'Three', 'Four', 'Fi#vϵ', 'Si⃗x', 'Se⃗ve⃗n']) redraw let normattr = screenattr(1, 1) diffthis botright vert new two - call setline(1, ['one', 'TWO', 'Three ', 'Four', 'fI=VE']) + call setline(1, ['one', 'TWO', 'Three ', 'Four', 'fI=VΕ', 'SI⃗x', 'SEvE⃗n']) diffthis redraw @@ -444,10 +444,13 @@ func Common_icase_test() call assert_equal(normattr, screenattr(2, 1)) call assert_notequal(normattr, screenattr(3, 1)) call assert_equal(normattr, screenattr(4, 1)) + call assert_equal(normattr, screenattr(6, 2)) + call assert_notequal(normattr, screenattr(7, 2)) let dtextattr = screenattr(5, 3) call assert_notequal(dtextattr, screenattr(5, 1)) call assert_notequal(dtextattr, screenattr(5, 5)) + call assert_notequal(dtextattr, screenattr(7, 4)) diffoff! %bwipe! @@ -779,10 +782,10 @@ endfunc func Test_diff_hlID() new - call setline(1, [1, 2, 3]) + call setline(1, [1, 2, 3, 'Yz', 'a dxxg',]) diffthis vnew - call setline(1, ['1x', 2, 'x', 3]) + call setline(1, ['1x', 2, 'x', 3, 'yx', 'abc defg']) diffthis redraw @@ -793,6 +796,26 @@ func Test_diff_hlID() call diff_hlID(2, 1)->synIDattr("name")->assert_equal("") call diff_hlID(3, 1)->synIDattr("name")->assert_equal("DiffAdd") eval 4->diff_hlID(1)->synIDattr("name")->assert_equal("") + call diff_hlID(5, 1)->synIDattr("name")->assert_equal("DiffText") + call diff_hlID(5, 2)->synIDattr("name")->assert_equal("DiffText") + + set diffopt+=icase " test that caching is invalidated by diffopt change + call diff_hlID(5, 1)->synIDattr("name")->assert_equal("DiffChange") + set diffopt-=icase + call diff_hlID(5, 1)->synIDattr("name")->assert_equal("DiffText") + + call diff_hlID(6, 1)->synIDattr("name")->assert_equal("DiffChange") + call diff_hlID(6, 2)->synIDattr("name")->assert_equal("DiffText") + call diff_hlID(6, 4)->synIDattr("name")->assert_equal("DiffText") + call diff_hlID(6, 7)->synIDattr("name")->assert_equal("DiffText") + call diff_hlID(6, 8)->synIDattr("name")->assert_equal("DiffChange") + set diffopt+=inline:char + call diff_hlID(6, 1)->synIDattr("name")->assert_equal("DiffChange") + call diff_hlID(6, 2)->synIDattr("name")->assert_equal("DiffTextAdd") + call diff_hlID(6, 4)->synIDattr("name")->assert_equal("DiffChange") + call diff_hlID(6, 7)->synIDattr("name")->assert_equal("DiffText") + call diff_hlID(6, 8)->synIDattr("name")->assert_equal("DiffChange") + set diffopt-=inline:char wincmd w call assert_equal(synIDattr(diff_hlID(1, 1), "name"), "DiffChange") @@ -2099,6 +2122,178 @@ func Test_diff_topline_noscroll() call StopVimInTerminal(buf) endfunc +" Test inline highlighting which shows what's different within each diff block +func Test_diff_inline() + CheckScreendump + + call WriteDiffFiles(0, [], []) + let buf = RunVimInTerminal('-d Xdifile1 Xdifile2', {}) + call term_sendkeys(buf, ":set autoread\<CR>\<c-w>w:set autoread\<CR>\<c-w>w") + + call WriteDiffFiles(buf, ["abcdef ghi jk n", "x", "y"], ["aBcef gHi lm n", "y", "z"]) + call VerifyInternal(buf, "Test_diff_inline_01", "") + call VerifyInternal(buf, "Test_diff_inline_02", " diffopt+=inline:none") + + " inline:simple is the same as default + call VerifyInternal(buf, "Test_diff_inline_01", " diffopt+=inline:simple") + + call VerifyInternal(buf, "Test_diff_inline_03", " diffopt+=inline:char") + call VerifyInternal(buf, "Test_diff_inline_04", " diffopt+=inline:word") + + " multiple inline values will the last one + call VerifyInternal(buf, "Test_diff_inline_01", " diffopt+=inline:none,inline:char,inline:simple") + call VerifyInternal(buf, "Test_diff_inline_02", " diffopt+=inline:simple,inline:word,inline:none") + call VerifyInternal(buf, "Test_diff_inline_03", " diffopt+=inline:simple,inline:word,inline:char") + + " DiffTextAdd highlight + call term_sendkeys(buf, ":hi DiffTextAdd ctermbg=blue\<CR>") + call VerifyInternal(buf, "Test_diff_inline_05", " diffopt+=inline:char") + + " Live update in insert mode + call term_sendkeys(buf, "\<Esc>isometext") + call VerifyScreenDump(buf, "Test_diff_inline_06", {}) + call term_sendkeys(buf, "\<Esc>u") + + " icase simple scenarios + call VerifyInternal(buf, "Test_diff_inline_07", " diffopt+=inline:simple,icase") + call VerifyInternal(buf, "Test_diff_inline_08", " diffopt+=inline:char,icase") + call VerifyInternal(buf, "Test_diff_inline_09", " diffopt+=inline:word,icase") + + " diff algorithms should affect highlight + call WriteDiffFiles(buf, ["apples and oranges"], ["oranges and apples"]) + call VerifyInternal(buf, "Test_diff_inline_10", " diffopt+=inline:char") + call VerifyInternal(buf, "Test_diff_inline_11", " diffopt+=inline:char,algorithm:patience") + + " icase: composing chars and Unicode fold case edge cases + call WriteDiffFiles(buf, + \ ["1 - sigma in 6σ and Ὀδυσσεύς", "1 - angstrom in åå", "1 - composing: ii⃗I⃗"], + \ ["2 - Sigma in 6Σ and ὈΔΥΣΣΕΎΣ", "2 - Angstrom in ÅÅ", "2 - Composing: i⃗I⃗I⃗"]) + call VerifyInternal(buf, "Test_diff_inline_12", " diffopt+=inline:char") + call VerifyInternal(buf, "Test_diff_inline_13", " diffopt+=inline:char,icase") + + " wide chars + call WriteDiffFiles(buf, ["abc😅xde一", "f🚀g"], ["abcy😢de", "二f🚀g"]) + call VerifyInternal(buf, "Test_diff_inline_14", " diffopt+=inline:char,icase") + + " NUL char (\n below is internally substituted as NUL) + call WriteDiffFiles(buf, ["1\n34\n5\n6"], ["1234\n5", "6"]) + call VerifyInternal(buf, "Test_diff_inline_15", " diffopt+=inline:char") + + " word diff: always use first buffer's iskeyword and ignore others' for consistency + call WriteDiffFiles(buf, ["foo+bar test"], ["foo+baz test"]) + call VerifyInternal(buf, "Test_diff_inline_word_01", " diffopt+=inline:word") + + call term_sendkeys(buf, ":set iskeyword+=+\<CR>:diffupdate\<CR>") + call VerifyInternal(buf, "Test_diff_inline_word_02", " diffopt+=inline:word") + + call term_sendkeys(buf, ":set iskeyword&\<CR>:wincmd w\<CR>") + call term_sendkeys(buf, ":set iskeyword+=+\<CR>:wincmd w\<CR>:diffupdate\<CR>") + " Use the previous screen dump as 2nd buffer's iskeyword does not matter + call VerifyInternal(buf, "Test_diff_inline_word_01", " diffopt+=inline:word") + + call term_sendkeys(buf, ":windo set iskeyword&\<CR>:1wincmd w\<CR>") + + " char diff: should slide highlight to whitespace boundary if possible for + " better readability (by using forced indent-heuristics). A wrong result + " would be if the highlight is "Bar, prefix". It should be "prefixBar, " + " instead. + call WriteDiffFiles(buf, ["prefixFoo, prefixEnd"], ["prefixFoo, prefixBar, prefixEnd"]) + call VerifyInternal(buf, "Test_diff_inline_char_01", " diffopt+=inline:char") + + " char diff: small gaps between inline diff blocks will be merged during refine step + " - first segment: test that we iteratively merge small gaps after we merged + " adjacent blocks, but only with limited number (set to 4) of iterations. + " - second and third segments: show that we need a large enough adjacent block to + " trigger a merge. + " - fourth segment: small gaps are not merged when adjacent large block is + " on a different line. + call WriteDiffFiles(buf, + \ ["abcdefghijklmno", "anchor1", + \ "abcdefghijklmno", "anchor2", + \ "abcdefghijklmno", "anchor3", + \ "test", "multiline"], + \ ["a?c?e?g?i?k???o", "anchor1", + \ "a??de?????klmno", "anchor2", + \ "a??de??????lmno", "anchor3", + \ "t?s?", "??????i?e"]) + call VerifyInternal(buf, "Test_diff_inline_char_02", " diffopt+=inline:char") + + " Test multi-line blocks and whitespace + call WriteDiffFiles(buf, + \ ["this is ", "sometest text foo", "baz abc def ", "one", "word another word", "additional line"], + \ ["this is some test", "texts", "foo bar abX Yef ", "oneword another word"]) + call VerifyInternal(buf, "Test_diff_inline_multiline_01", " diffopt+=inline:char,iwhite") + call VerifyInternal(buf, "Test_diff_inline_multiline_02", " diffopt+=inline:word,iwhite") + call VerifyInternal(buf, "Test_diff_inline_multiline_03", " diffopt+=inline:char,iwhiteeol") + call VerifyInternal(buf, "Test_diff_inline_multiline_04", " diffopt+=inline:word,iwhiteeol") + call VerifyInternal(buf, "Test_diff_inline_multiline_05", " diffopt+=inline:char,iwhiteall") + call VerifyInternal(buf, "Test_diff_inline_multiline_06", " diffopt+=inline:word,iwhiteall") + + " newline should be highlighted too when 'list' is set + call term_sendkeys(buf, ":windo set list\<CR>") + call VerifyInternal(buf, "Test_diff_inline_multiline_07", " diffopt+=inline:char") + call VerifyInternal(buf, "Test_diff_inline_multiline_08", " diffopt+=inline:char,iwhite") + call VerifyInternal(buf, "Test_diff_inline_multiline_09", " diffopt+=inline:char,iwhiteeol") + call VerifyInternal(buf, "Test_diff_inline_multiline_10", " diffopt+=inline:char,iwhiteall") + call term_sendkeys(buf, ":windo set nolist\<CR>") + + call StopVimInTerminal(buf) +endfunc + +func Test_diff_inline_multibuffer() + CheckScreendump + + call WriteDiffFiles3(0, [], [], []) + let buf = RunVimInTerminal('-d Xdifile1 Xdifile2 Xdifile3', {}) + call term_sendkeys(buf, ":windo set autoread\<CR>:1wincmd w\<CR>") + call term_sendkeys(buf, ":hi DiffTextAdd ctermbg=blue\<CR>") + + call WriteDiffFiles3(buf, + \ ["That is buffer1.", "anchor", "Some random text", "anchor"], + \ ["This is buffer2.", "anchor", "Some text", "anchor", "buffer2/3"], + \ ["This is buffer3. Last.", "anchor", "Some more", "text here.", "anchor", "only in buffer2/3", "not in buffer1"]) + call VerifyInternal(buf, "Test_diff_inline_multibuffer_01", " diffopt+=inline:char") + + " Close one of the buffers and make sure it updates correctly + call term_sendkeys(buf, ":diffoff\<CR>") + call VerifyInternal(buf, "Test_diff_inline_multibuffer_02", " diffopt+=inline:char") + + " Update text in the non-diff buffer and nothing should be changed + call term_sendkeys(buf, "\<Esc>isometext") + call VerifyScreenDump(buf, "Test_diff_inline_multibuffer_03", {}) + call term_sendkeys(buf, "\<Esc>u") + + call term_sendkeys(buf, ":diffthis\<CR>") + call VerifyInternal(buf, "Test_diff_inline_multibuffer_01", " diffopt+=inline:char") + + " Test that removing first buffer from diff will in turn use the next + " earliest buffer's iskeyword during word diff. + call WriteDiffFiles3(buf, + \ ["This+is=a-setence"], + \ ["This+is=another-setence"], + \ ["That+is=a-setence"]) + call term_sendkeys(buf, ":set iskeyword+=+\<CR>:2wincmd w\<CR>:set iskeyword+=-\<CR>:1wincmd w\<CR>") + call VerifyInternal(buf, "Test_diff_inline_multibuffer_04", " diffopt+=inline:word") + call term_sendkeys(buf, ":diffoff\<CR>") + call VerifyInternal(buf, "Test_diff_inline_multibuffer_05", " diffopt+=inline:word") + call term_sendkeys(buf, ":diffthis\<CR>") + call VerifyInternal(buf, "Test_diff_inline_multibuffer_04", " diffopt+=inline:word") + + " Test multi-buffer char diff refinement, and that removing a buffer from + " diff will update the others properly. + call WriteDiffFiles3(buf, + \ ["abcdefghijkYmYYY"], + \ ["aXXdXXghijklmnop"], + \ ["abcdefghijkYmYop"]) + call VerifyInternal(buf, "Test_diff_inline_multibuffer_06", " diffopt+=inline:char") + call term_sendkeys(buf, ":diffoff\<CR>") + call VerifyInternal(buf, "Test_diff_inline_multibuffer_07", " diffopt+=inline:char") + call term_sendkeys(buf, ":diffthis\<CR>") + call VerifyInternal(buf, "Test_diff_inline_multibuffer_06", " diffopt+=inline:char") + + call StopVimInTerminal(buf) +endfunc + func Test_diffget_diffput_linematch() CheckScreendump call delete('.Xdifile1.swp') diff --git a/test/old/testdir/test_let.vim b/test/old/testdir/test_let.vim index 22a3a35f87..ec83de880c 100644 --- a/test/old/testdir/test_let.vim +++ b/test/old/testdir/test_let.vim @@ -93,6 +93,26 @@ func Test_let() let [l[0], l[1]] = [10, 20] call assert_equal([10, 20, 3], l) + " Test for using curly brace name in the LHS of an assignment + let listvar = [1, 2] + let s = 'listvar' + let {s} = [3, 4] + call assert_equal([3, 4], listvar) + + " Test for using curly brace name as a list and as list index in the LHS of + " an assignment + let listvar = [1, 2] + let idx = 1 + let s = 'listvar' + let {s}[0] = 10 + let s = 'idx' + let listvar[{s}] = 20 + call assert_equal([10, 20], listvar) + let s1 = 'listvar' + let s2 = 'idx' + let {s1}[{s2}] = 30 + call assert_equal([10, 30], listvar) + " Test for errors in conditional expression call assert_fails('let val = [] ? 1 : 2', 'E745:') call assert_fails('let val = 1 ? 5+ : 6', 'E121:') diff --git a/test/old/testdir/test_normal.vim b/test/old/testdir/test_normal.vim index 1d9609cbe1..b8011a81e4 100644 --- a/test/old/testdir/test_normal.vim +++ b/test/old/testdir/test_normal.vim @@ -2705,6 +2705,22 @@ func Test_normal33_g_cmd2() call assert_equal(87, col('.')) call assert_equal('E', getreg(0)) + " Have an odd number of chars in the line + norm! A. + call assert_equal(145, col('.')) + norm! gMyl + call assert_equal(73, col('.')) + call assert_equal('0', getreg(0)) + + " 'listchars' "eol" should not affect gM behavior + setlocal list listchars=eol:$ + norm! $ + call assert_equal(145, col('.')) + norm! gMyl + call assert_equal(73, col('.')) + call assert_equal('0', getreg(0)) + setlocal nolist + " Test for gM with Tab characters call setline('.', "\ta\tb\tc\td\te\tf") norm! gMyl diff --git a/test/old/testdir/test_options.vim b/test/old/testdir/test_options.vim index 9104098baa..f3dcb3bbb7 100644 --- a/test/old/testdir/test_options.vim +++ b/test/old/testdir/test_options.vim @@ -313,11 +313,18 @@ func Test_set_completion() call feedkeys(":set suffixes:\<C-A>\<C-B>\"\<CR>", 'tx') call assert_equal('"set suffixes:.bak,~,.o,.h,.info,.swp,.obj', @:) - " Expand key codes. + " " Expand key codes. " call feedkeys(":set <H\<C-A>\<C-B>\"\<CR>", 'tx') " call assert_equal('"set <Help> <Home>', @:) - - " Expand terminal options. + " " <BackSpace> (alt name) and <BS> should both show up in auto-complete + " call feedkeys(":set <B\<C-A>\<C-B>\"\<CR>", 'tx') + " call assert_equal('"set <BackSpace> <Bar> <BS> <Bslash>', @:) + " " <ScrollWheelDown> has alt name <MouseUp> but it should not show up here + " " nor show up as duplicates + " call feedkeys(":set <ScrollWheel\<C-A>\<C-B>\"\<CR>", 'tx') + " call assert_equal('"set <ScrollWheelDown> <ScrollWheelLeft> <ScrollWheelRight> <ScrollWheelUp>', @:) + " + " " Expand terminal options. " call feedkeys(":set t_A\<C-A>\<C-B>\"\<CR>", 'tx') " call assert_equal('"set t_AB t_AF t_AU t_AL', @:) " call assert_fails('call feedkeys(":set <t_afoo>=\<C-A>\<CR>", "xt")', 'E474:') @@ -622,10 +629,11 @@ func Test_set_completion_string_values() " call assert_equal([], getcompletion('set completepopup=bogusname:', 'cmdline')) " set previewpopup& completepopup& - " diffopt: special handling of algorithm:<alg_list> + " diffopt: special handling of algorithm:<alg_list> and inline:<inline_type> call assert_equal('filler', getcompletion('set diffopt+=', 'cmdline')[0]) call assert_equal([], getcompletion('set diffopt+=iblank,foldcolumn:', 'cmdline')) call assert_equal('patience', getcompletion('set diffopt+=iblank,algorithm:pat*', 'cmdline')[0]) + call assert_equal('char', getcompletion('set diffopt+=iwhite,inline:ch*', 'cmdline')[0]) " highlight: special parsing, including auto-completing highlight groups " after ':' @@ -715,7 +723,7 @@ func Test_set_completion_string_values() call assert_equal([], getcompletion('set diffopt-=', 'cmdline')) " Test all possible values call assert_equal(['filler', 'context:', 'iblank', 'icase', 'iwhite', 'iwhiteall', 'iwhiteeol', 'horizontal', - \ 'vertical', 'closeoff', 'hiddenoff', 'foldcolumn:', 'followwrap', 'internal', 'indent-heuristic', 'algorithm:', 'linematch:'], + \ 'vertical', 'closeoff', 'hiddenoff', 'foldcolumn:', 'followwrap', 'internal', 'indent-heuristic', 'algorithm:', 'inline:', 'linematch:'], \ getcompletion('set diffopt=', 'cmdline')) set diffopt& diff --git a/test/old/testdir/test_popup.vim b/test/old/testdir/test_popup.vim index 8f81db6213..c5591fac05 100644 --- a/test/old/testdir/test_popup.vim +++ b/test/old/testdir/test_popup.vim @@ -1992,4 +1992,88 @@ func Test_pum_complete_with_special_characters() call StopVimInTerminal(buf) endfunc +func Test_pum_maxwidth() + CheckScreendump + + let lines =<< trim END + 123456789_123456789_123456789_a + 123456789_123456789_123456789_b + 123 + END + call writefile(lines, 'Xtest', 'D') + let buf = RunVimInTerminal('Xtest', {}) + + call term_sendkeys(buf, "G\"zyy") + call term_sendkeys(buf, "A\<C-N>") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_01', {'rows': 8}) + call term_sendkeys(buf, "\<Esc>3Gdd\"zp") + + call term_sendkeys(buf, ":set pummaxwidth=10\<CR>") + call term_sendkeys(buf, "GA\<C-N>") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_02', {'rows': 8}) + call term_sendkeys(buf, "\<Esc>3Gdd\"zp") + + call term_sendkeys(buf, ":set pummaxwidth=20\<CR>") + call term_sendkeys(buf, "GA\<C-N>") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_03', {'rows': 8}) + call term_sendkeys(buf, "\<Esc>3Gdd\"zp") + + call term_sendkeys(buf, ":set pumwidth=20 pummaxwidth=8\<CR>") + call term_sendkeys(buf, "GA\<C-N>") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_04', {'rows': 8}) + call term_sendkeys(buf, "\<Esc>3Gdd\"zp") + + call term_sendkeys(buf, ":set lines=10 columns=32\<CR>") + call term_sendkeys(buf, "GA\<C-N>") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_09', {'rows': 10, 'cols': 32}) + call term_sendkeys(buf, "\<Esc>3Gdd\"zp") + + call StopVimInTerminal(buf) +endfunc + +func Test_pum_maxwidth_multibyte() + CheckScreendump + + let lines =<< trim END + func Omni_test(findstart, base) + if a:findstart + return col(".") + endif + return [ + \ #{word: "123456789_123456789_123456789_"}, + \ #{word: "一二三四五六七八九十"}, + \ #{word: "abcdefghij"}, + \ #{word: "上下左右"}, + \ ] + endfunc + set omnifunc=Omni_test + END + call writefile(lines, 'Xtest', 'D') + let buf = RunVimInTerminal('-S Xtest', {}) + call TermWait(buf) + + call term_sendkeys(buf, "S\<C-X>\<C-O>") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_05', {'rows': 8}) + call term_sendkeys(buf, "\<ESC>") + + call term_sendkeys(buf, ":set pummaxwidth=10\<CR>") + call term_sendkeys(buf, "S\<C-X>\<C-O>") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_06', {'rows': 8}) + call term_sendkeys(buf, "\<ESC>") + + if has('rightleft') + call term_sendkeys(buf, ":set rightleft\<CR>") + call term_sendkeys(buf, "S\<C-X>\<C-O>") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_07', {'rows': 8}) + call term_sendkeys(buf, "\<Esc>:set norightleft\<CR>") + endif + + call term_sendkeys(buf, ":set pummaxwidth=2\<CR>") + call term_sendkeys(buf, "S\<C-X>\<C-O>") + call VerifyScreenDump(buf, 'Test_pum_maxwidth_08', {'rows': 8}) + call term_sendkeys(buf, "\<ESC>") + + call StopVimInTerminal(buf) +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/test/old/testdir/test_search.vim b/test/old/testdir/test_search.vim index cd36f56f17..4e5cb574bd 100644 --- a/test/old/testdir/test_search.vim +++ b/test/old/testdir/test_search.vim @@ -1499,17 +1499,46 @@ func Test_large_hex_chars2() try /[\Ufffffc1f] catch - call assert_match('E486:', v:exception) + call assert_match('E1541:', v:exception) endtry try set re=1 /[\Ufffffc1f] catch - call assert_match('E486:', v:exception) + call assert_match('E1541:', v:exception) endtry set re& endfunc +func Test_large_hex_chars3() + " Validate max number of Unicode char + try + /[\UFFFFFFFF] + catch + call assert_match('E1541:', v:exception) + endtry + try + /[\UFFFFFFF] + catch + call assert_match('E486:', v:exception) + endtry + try + /\%#=2[\d32-\UFFFFFFFF] + catch + call assert_match('E1541:', v:exception) + endtry + try + /\%#=1[\UFFFFFFFF] + catch + call assert_match('E1541:', v:exception) + endtry + try + /\%#=1[\d32-\UFFFFFFFF] + catch + call assert_match('E945:', v:exception) + endtry +endfunc + func Test_one_error_msg() " This was also giving an internal error call assert_fails('call search(" \\((\\v[[=P=]]){185}+ ")', 'E871:') diff --git a/test/old/testdir/test_shell.vim b/test/old/testdir/test_shell.vim index 9499462a70..e30e9c9ec8 100644 --- a/test/old/testdir/test_shell.vim +++ b/test/old/testdir/test_shell.vim @@ -281,4 +281,18 @@ func Test_shell_no_prevcmd() call delete('Xtestdone') endfunc +func Test_shell_filter_buffer_with_nul_bytes() + CheckUnix + new + set noshelltemp + " \n is a NUL byte + let lines = ["aaa\nbbb\nccc\nddd\neee", "fff\nggg\nhhh\niii\njjj"] + call setline(1, lines) + %!cat + call assert_equal(lines, getline(1, '$')) + + set shelltemp& + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab |