" Tests for various eval things. source util/shared.vim import './util/vim9.vim' as v9 function s:foo() abort try return [] == 0 catch return 1 endtry endfunction func Test_catch_return_with_error() call assert_equal(1, s:foo()) endfunc func Test_nocatch_restore_silent_emsg() silent! try throw 1 catch endtry echoerr 'wrong again' call assert_equal('wrong again', ScreenLine(&lines)) endfunc func Test_mkdir_p() call mkdir('Xmkdir/nested', 'pR') call assert_true(isdirectory('Xmkdir/nested')) try " Trying to make existing directories doesn't error call mkdir('Xmkdir', 'p') call mkdir('Xmkdir/nested', 'p') catch /E739:/ call assert_report('mkdir(..., "p") failed for an existing directory') endtry " 'p' doesn't suppress real errors call writefile([], 'Xmkdirfile', 'D') call assert_fails('call mkdir("Xmkdirfile", "p")', 'E739:') call assert_equal(0, mkdir(test_null_string())) call assert_fails('call mkdir([])', 'E730:') call assert_fails('call mkdir("abc", [], [])', 'E745:') endfunc func DoMkdirDel(name) call mkdir(a:name, 'pD') call assert_true(isdirectory(a:name)) endfunc func DoMkdirDelAddFile(name) call mkdir(a:name, 'pD') call assert_true(isdirectory(a:name)) call writefile(['text'], a:name .. '/file') endfunc func DoMkdirDelRec(name) call mkdir(a:name, 'pR') call assert_true(isdirectory(a:name)) endfunc func DoMkdirDelRecAddFile(name) call mkdir(a:name, 'pR') call assert_true(isdirectory(a:name)) call writefile(['text'], a:name .. '/file') endfunc func Test_mkdir_defer_del() " Xtopdir/tmp is created thus deleted, not Xtopdir itself call mkdir('Xtopdir', 'R') call DoMkdirDel('Xtopdir/tmp') call assert_true(isdirectory('Xtopdir')) call assert_false(isdirectory('Xtopdir/tmp')) " Deletion fails because "tmp" contains "sub" call DoMkdirDel('Xtopdir/tmp/sub') call assert_true(isdirectory('Xtopdir')) call assert_true(isdirectory('Xtopdir/tmp')) call delete('Xtopdir/tmp', 'rf') " Deletion fails because "tmp" contains "file" call DoMkdirDelAddFile('Xtopdir/tmp') call assert_true(isdirectory('Xtopdir')) call assert_true(isdirectory('Xtopdir/tmp')) call assert_true(filereadable('Xtopdir/tmp/file')) call delete('Xtopdir/tmp', 'rf') " Xtopdir/tmp is created thus deleted, not Xtopdir itself call DoMkdirDelRec('Xtopdir/tmp') call assert_true(isdirectory('Xtopdir')) call assert_false(isdirectory('Xtopdir/tmp')) " Deletion works even though "tmp" contains "sub" call DoMkdirDelRec('Xtopdir/tmp/sub') call assert_true(isdirectory('Xtopdir')) call assert_false(isdirectory('Xtopdir/tmp')) " Deletion works even though "tmp" contains "file" call DoMkdirDelRecAddFile('Xtopdir/tmp') call assert_true(isdirectory('Xtopdir')) call assert_false(isdirectory('Xtopdir/tmp')) endfunc func Test_line_continuation() let array = [5, "\ ignore this \ 6, "\ more to ignore "\ more moreto ignore \ ] "\ and some more call assert_equal([5, 6], array) endfunc func Test_E963() " These commands used to cause an internal error prior to vim 8.1.0563 let v_e = v:errors let v_o = v:oldfiles call assert_fails("let v:errors=''", 'E963:') call assert_equal(v_e, v:errors) call assert_fails("let v:oldfiles=''", 'E963:') call assert_equal(v_o, v:oldfiles) endfunc func Test_for_invalid() call assert_fails("for x in 99", 'E1523:') call assert_fails("for x in function('winnr')", 'E1523:') call assert_fails("for x in {'a': 9}", 'E1523:') let lines =<< trim END for v:maxcol in range(5) endfor END let save_v_maxcol = v:maxcol call v9.CheckLegacyAndVim9Failure(lines, 'E46:') call assert_equal(save_v_maxcol, v:maxcol) let lines =<< trim END for g:constvar in range(5) endfor END const g:constvar = 10 call v9.CheckLegacyAndVim9Failure(lines, 'E741:') call assert_equal(10, g:constvar) unlet g:constvar let g:constvar = 10 lockvar 0 g:constvar call v9.CheckLegacyAndVim9Failure(lines, 'E1122:') call assert_equal(10, g:constvar) unlet g:constvar if 0 /1/5/2/s/\n endif redraw endfunc func Test_for_over_null_string() let save_enc = &enc set enc=iso8859 let cnt = 0 for c in test_null_string() let cnt += 1 endfor call assert_equal(0, cnt) let &enc = save_enc endfunc func Test_for_with_modifier() " this checks has_loop_cmd() works with a modifier let result = [] vim9cmd for i in range(3) call extend(result, [i]) endfor call assert_equal([0, 1, 2], result) endfunc func Test_for_invalid_line_count() let lines =<< trim END 111111111111111111111111 for line in ['one'] endfor END call writefile(lines, 'XinvalidFor', 'D') " only test that this doesn't crash call RunVim([], [], '-u NONE -e -s -S XinvalidFor -c qa') endfunc func Test_readfile_binary() new call setline(1, ['one', 'two', 'three']) setlocal ff=dos silent write XReadfile_bin let lines = 'XReadfile_bin'->readfile() call assert_equal(['one', 'two', 'three'], lines) let lines = readfile('XReadfile_bin', '', 2) call assert_equal(['one', 'two'], lines) let lines = readfile('XReadfile_bin', 'b') call assert_equal(["one\r", "two\r", "three\r", ""], lines) let lines = readfile('XReadfile_bin', 'b', 2) call assert_equal(["one\r", "two\r"], lines) bwipe! call delete('XReadfile_bin') endfunc func Test_readfile_binary_empty() call writefile([], 'Xempty-file', 'D') " This used to compare uninitialized memory in Vim <= 8.2.4065 call assert_equal([''], readfile('Xempty-file', 'b')) endfunc func Test_readfile_bom() call writefile(["\ufeffFOO", "FOO\ufeffBAR"], 'XReadfile_bom') call assert_equal(['FOO', 'FOOBAR'], readfile('XReadfile_bom')) call delete('XReadfile_bom') endfunc func Test_readfile_max() call writefile(range(1, 4), 'XReadfile_max', 'D') call assert_equal(['1', '2'], readfile('XReadfile_max', '', 2)) call assert_equal(['3', '4'], readfile('XReadfile_max', '', -2)) endfunc func Test_let_errmsg() call assert_fails('let v:errmsg = []', 'E730:') let v:errmsg = '' call assert_fails('let v:errmsg = []', 'E730:') let v:errmsg = '' endfunc func Test_string_concatenation() call assert_equal('ab', 'a'.'b') call assert_equal('ab', 'a' .'b') call assert_equal('ab', 'a'. 'b') call assert_equal('ab', 'a' . 'b') call assert_equal('ab', 'a'..'b') call assert_equal('ab', 'a' ..'b') call assert_equal('ab', 'a'.. 'b') call assert_equal('ab', 'a' .. 'b') let a = 'a' let b = 'b' let a .= b call assert_equal('ab', a) let a = 'a' let a.=b call assert_equal('ab', a) let a = 'a' let a ..= b call assert_equal('ab', a) let a = 'a' let a..=b call assert_equal('ab', a) let a = 'A' let b = 1.234 call assert_equal('A1.234', a .. b) endfunc " Test fix for issue #4507 func Test_skip_after_throw() try throw 'something' let x = wincol() || &ts catch /something/ endtry endfunc scriptversion 2 func Test_string_concat_scriptversion2() call assert_true(has('vimscript-2')) let a = 'a' let b = 'b' call assert_fails('echo a . b', 'E15:') call assert_fails('let a .= b', 'E985:') call assert_fails('let vers = 1.2.3', 'E488:') let f = .5 call assert_equal(0.5, f) endfunc scriptversion 1 func Test_string_concat_scriptversion1() call assert_true(has('vimscript-1')) let a = 'a' let b = 'b' echo a . b let a .= b let vers = 1.2.3 call assert_equal('123', vers) call assert_fails('let f = .5', 'E15:') endfunc scriptversion 3 func Test_vvar_scriptversion3() call assert_true(has('vimscript-3')) call assert_fails('echo version', 'E121:') call assert_false(exists('version')) let version = 1 call assert_equal(1, version) endfunc scriptversion 2 func Test_vvar_scriptversion2() call assert_true(exists('version')) echo version call assert_fails('let version = 1', 'E46:') call assert_equal(v:version, version) call assert_equal(v:version, v:versionlong / 10000) call assert_true(v:versionlong > 8011525) endfunc func Test_dict_access_scriptversion2() let l:x = {'foo': 1} call assert_false(0 && l:x.foo) call assert_true(1 && l:x.foo) endfunc scriptversion 4 func Test_vvar_scriptversion4() call assert_true(has('vimscript-4')) call assert_equal(17, 017) call assert_equal(15, 0o17) call assert_equal(15, 0O17) call assert_equal(18, 018) call assert_equal(511, 0o777) call assert_equal(64, 0b1'00'00'00) call assert_equal(1048576, 0x10'00'00) call assert_equal(32768, 0o10'00'00) call assert_equal(1000000, 1'000'000) call assert_equal("1234", execute("echo 1'234")->trim()) call assert_equal('1 234', execute("echo 1''234")->trim()) call assert_fails("echo 1'''234", 'E115:') endfunc scriptversion 1 func Test_vvar_scriptversion1() call assert_equal(15, 017) call assert_equal(15, 0o17) call assert_equal(15, 0O17) call assert_equal(18, 018) call assert_equal(511, 0o777) endfunc func Test_scriptversion_fail() call writefile(['scriptversion 9'], 'Xversionscript', 'D') call assert_fails('source Xversionscript', 'E999:') endfunc func Test_execute_cmd_with_null() call assert_fails('execute test_null_list()', 'E730:') call assert_fails('execute test_null_dict()', 'E731:') call assert_fails('execute test_null_blob()', 'E976:') execute test_null_string() call assert_fails('execute test_null_partial()', 'E729:') call assert_fails('execute test_unknown()', 'E908:') if has('job') call assert_fails('execute test_null_job()', 'E908:') call assert_fails('execute test_null_channel()', 'E908:') endif endfunc func Test_number_max_min_size() " This will fail on systems without 64 bit number support or when not " configured correctly. call assert_equal(64, v:numbersize) call assert_true(v:numbermin < -9999999) call assert_true(v:numbermax > 9999999) endfunc func Assert_reg(name, type, value, valuestr, expr, exprstr) call assert_equal(a:type, getregtype(a:name)) call assert_equal(a:value, getreg(a:name)) call assert_equal(a:valuestr, string(getreg(a:name, 0, 1))) call assert_equal(a:expr, getreg(a:name, 1)) call assert_equal(a:exprstr, string(getreg(a:name, 1, 1))) endfunc func Test_let_register() let @" = 'abc' call Assert_reg('"', 'v', "abc", "['abc']", "abc", "['abc']") let @" = "abc\n" call Assert_reg('"', 'V', "abc\n", "['abc']", "abc\n", "['abc']") let @" = "abc\" call Assert_reg('"', 'V', "abc\r\n", "['abc\r']", "abc\r\n", "['abc\r']") let @= = '"abc"' call Assert_reg('=', 'v', "abc", "['abc']", '"abc"', "['\"abc\"']") endfunc func Assert_regput(name, result) new execute "silent normal! o==\n==\e\"" . a:name . "P" call assert_equal(a:result, getline(2, line('$'))) bwipe! endfunc func Test_setreg_basic() call setreg('a', 'abcA', 'c') call Assert_reg('a', 'v', "abcA", "['abcA']", "abcA", "['abcA']") call Assert_regput('a', ['==', '=abcA=']) call setreg('A', 'abcAc', 'c') call Assert_reg('A', 'v', "abcAabcAc", "['abcAabcAc']", "abcAabcAc", "['abcAabcAc']") call Assert_regput('a', ['==', '=abcAabcAc=']) call setreg('A', 'abcAl', 'l') call Assert_reg('A', 'V', "abcAabcAcabcAl\n", "['abcAabcAcabcAl']", "abcAabcAcabcAl\n", "['abcAabcAcabcAl']") call Assert_regput('a', ['==', 'abcAabcAcabcAl', '==']) call setreg('A', 'abcAc2','c') call Assert_reg('A', 'v', "abcAabcAcabcAl\nabcAc2", "['abcAabcAcabcAl', 'abcAc2']", "abcAabcAcabcAl\nabcAc2", "['abcAabcAcabcAl', 'abcAc2']") call Assert_regput('a', ['==', '=abcAabcAcabcAl', 'abcAc2=']) call setreg('b', 'abcB', 'v') call Assert_reg('b', 'v', "abcB", "['abcB']", "abcB", "['abcB']") call Assert_regput('b', ['==', '=abcB=']) call setreg('b', 'abcBc', 'ca') call Assert_reg('b', 'v', "abcBabcBc", "['abcBabcBc']", "abcBabcBc", "['abcBabcBc']") call Assert_regput('b', ['==', '=abcBabcBc=']) call setreg('b', 'abcBb', 'ba') call Assert_reg('b', "\5", "abcBabcBcabcBb", "['abcBabcBcabcBb']", "abcBabcBcabcBb", "['abcBabcBcabcBb']") call Assert_regput('b', ['==', '=abcBabcBcabcBb=']) call setreg('b', 'abcBc2','ca') call Assert_reg('b', "v", "abcBabcBcabcBb\nabcBc2", "['abcBabcBcabcBb', 'abcBc2']", "abcBabcBcabcBb\nabcBc2", "['abcBabcBcabcBb', 'abcBc2']") call Assert_regput('b', ['==', '=abcBabcBcabcBb', 'abcBc2=']) call setreg('b', 'abcBb2','b50a') call Assert_reg('b', "\50", "abcBabcBcabcBb\nabcBc2abcBb2", "['abcBabcBcabcBb', 'abcBc2abcBb2']", "abcBabcBcabcBb\nabcBc2abcBb2", "['abcBabcBcabcBb', 'abcBc2abcBb2']") call Assert_regput('b', ['==', '=abcBabcBcabcBb =', ' abcBc2abcBb2']) call setreg('c', 'abcC', 'l') call Assert_reg('c', 'V', "abcC\n", "['abcC']", "abcC\n", "['abcC']") call Assert_regput('c', ['==', 'abcC', '==']) call setreg('C', 'abcCl', 'l') call Assert_reg('C', 'V', "abcC\nabcCl\n", "['abcC', 'abcCl']", "abcC\nabcCl\n", "['abcC', 'abcCl']") call Assert_regput('c', ['==', 'abcC', 'abcCl', '==']) call setreg('C', 'abcCc', 'c') call Assert_reg('C', 'v', "abcC\nabcCl\nabcCc", "['abcC', 'abcCl', 'abcCc']", "abcC\nabcCl\nabcCc", "['abcC', 'abcCl', 'abcCc']") call Assert_regput('c', ['==', '=abcC', 'abcCl', 'abcCc=']) call setreg('d', 'abcD', 'V') call Assert_reg('d', 'V', "abcD\n", "['abcD']", "abcD\n", "['abcD']") call Assert_regput('d', ['==', 'abcD', '==']) call setreg('D', 'abcDb', 'b') call Assert_reg('d', "\5", "abcD\nabcDb", "['abcD', 'abcDb']", "abcD\nabcDb", "['abcD', 'abcDb']") call Assert_regput('d', ['==', '=abcD =', ' abcDb']) call setreg('e', 'abcE', 'b') call Assert_reg('e', "\4", "abcE", "['abcE']", "abcE", "['abcE']") call Assert_regput('e', ['==', '=abcE=']) call setreg('E', 'abcEb', 'b') call Assert_reg('E', "\5", "abcE\nabcEb", "['abcE', 'abcEb']", "abcE\nabcEb", "['abcE', 'abcEb']") call Assert_regput('e', ['==', '=abcE =', ' abcEb']) call setreg('E', 'abcEl', 'l') call Assert_reg('E', "V", "abcE\nabcEb\nabcEl\n", "['abcE', 'abcEb', 'abcEl']", "abcE\nabcEb\nabcEl\n", "['abcE', 'abcEb', 'abcEl']") call Assert_regput('e', ['==', 'abcE', 'abcEb', 'abcEl', '==']) call setreg('f', 'abcF', "\") call Assert_reg('f', "\4", "abcF", "['abcF']", "abcF", "['abcF']") call Assert_regput('f', ['==', '=abcF=']) call setreg('F', 'abcFc', 'c') call Assert_reg('F', "v", "abcF\nabcFc", "['abcF', 'abcFc']", "abcF\nabcFc", "['abcF', 'abcFc']") call Assert_regput('f', ['==', '=abcF', 'abcFc=']) call setreg('g', 'abcG', 'b10') call Assert_reg('g', "\10", "abcG", "['abcG']", "abcG", "['abcG']") call Assert_regput('g', ['==', '=abcG =']) call setreg('h', 'abcH', "\10") call Assert_reg('h', "\10", "abcH", "['abcH']", "abcH", "['abcH']") call Assert_regput('h', ['==', '=abcH =']) call setreg('I', 'abcI') call Assert_reg('I', "v", "abcI", "['abcI']", "abcI", "['abcI']") call Assert_regput('I', ['==', '=abcI=']) " Appending NL with setreg() call setreg('a', 'abcA2', 'c') call setreg('b', 'abcB2', 'v') call setreg('c', 'abcC2', 'l') call setreg('d', 'abcD2', 'V') call setreg('e', 'abcE2', 'b') call setreg('f', 'abcF2', "\") call setreg('g', 'abcG2', 'b10') call setreg('h', 'abcH2', "\10") call setreg('I', 'abcI2') call setreg('A', "\n") call Assert_reg('A', 'V', "abcA2\n", "['abcA2']", "abcA2\n", "['abcA2']") call Assert_regput('A', ['==', 'abcA2', '==']) call setreg('B', "\n", 'c') call Assert_reg('B', 'v', "abcB2\n", "['abcB2', '']", "abcB2\n", "['abcB2', '']") call Assert_regput('B', ['==', '=abcB2', '=']) call setreg('C', "\n") call Assert_reg('C', 'V', "abcC2\n\n", "['abcC2', '']", "abcC2\n\n", "['abcC2', '']") call Assert_regput('C', ['==', 'abcC2', '', '==']) call setreg('D', "\n", 'l') call Assert_reg('D', 'V', "abcD2\n\n", "['abcD2', '']", "abcD2\n\n", "['abcD2', '']") call Assert_regput('D', ['==', 'abcD2', '', '==']) call setreg('E', "\n") call Assert_reg('E', 'V', "abcE2\n\n", "['abcE2', '']", "abcE2\n\n", "['abcE2', '']") call Assert_regput('E', ['==', 'abcE2', '', '==']) call setreg('F', "\n", 'b') call Assert_reg('F', "\0", "abcF2\n", "['abcF2', '']", "abcF2\n", "['abcF2', '']") call Assert_regput('F', ['==', '=abcF2=', ' ']) " Setting lists with setreg() call setreg('a', ['abcA3'], 'c') call Assert_reg('a', 'v', "abcA3", "['abcA3']", "abcA3", "['abcA3']") call Assert_regput('a', ['==', '=abcA3=']) call setreg('b', ['abcB3'], 'l') call Assert_reg('b', 'V', "abcB3\n", "['abcB3']", "abcB3\n", "['abcB3']") call Assert_regput('b', ['==', 'abcB3', '==']) call setreg('c', ['abcC3'], 'b') call Assert_reg('c', "\5", "abcC3", "['abcC3']", "abcC3", "['abcC3']") call Assert_regput('c', ['==', '=abcC3=']) call setreg('d', ['abcD3']) call Assert_reg('d', 'V', "abcD3\n", "['abcD3']", "abcD3\n", "['abcD3']") call Assert_regput('d', ['==', 'abcD3', '==']) call setreg('e', [1, 2, 'abc', 3]) call Assert_reg('e', 'V', "1\n2\nabc\n3\n", "['1', '2', 'abc', '3']", "1\n2\nabc\n3\n", "['1', '2', 'abc', '3']") call Assert_regput('e', ['==', '1', '2', 'abc', '3', '==']) call setreg('f', [1, 2, 3]) call Assert_reg('f', 'V', "1\n2\n3\n", "['1', '2', '3']", "1\n2\n3\n", "['1', '2', '3']") call Assert_regput('f', ['==', '1', '2', '3', '==']) " Appending lists with setreg() call setreg('A', ['abcA3c'], 'c') call Assert_reg('A', 'v', "abcA3\nabcA3c", "['abcA3', 'abcA3c']", "abcA3\nabcA3c", "['abcA3', 'abcA3c']") call Assert_regput('A', ['==', '=abcA3', 'abcA3c=']) call setreg('b', ['abcB3l'], 'la') call Assert_reg('b', 'V', "abcB3\nabcB3l\n", "['abcB3', 'abcB3l']", "abcB3\nabcB3l\n", "['abcB3', 'abcB3l']") call Assert_regput('b', ['==', 'abcB3', 'abcB3l', '==']) call setreg('C', ['abcC3b'], 'lb') call Assert_reg('C', "\6", "abcC3\nabcC3b", "['abcC3', 'abcC3b']", "abcC3\nabcC3b", "['abcC3', 'abcC3b']") call Assert_regput('C', ['==', '=abcC3 =', ' abcC3b']) call setreg('D', ['abcD32']) call Assert_reg('D', 'V', "abcD3\nabcD32\n", "['abcD3', 'abcD32']", "abcD3\nabcD32\n", "['abcD3', 'abcD32']") call Assert_regput('D', ['==', 'abcD3', 'abcD32', '==']) call setreg('A', ['abcA32']) call Assert_reg('A', 'V', "abcA3\nabcA3c\nabcA32\n", "['abcA3', 'abcA3c', 'abcA32']", "abcA3\nabcA3c\nabcA32\n", "['abcA3', 'abcA3c', 'abcA32']") call Assert_regput('A', ['==', 'abcA3', 'abcA3c', 'abcA32', '==']) call setreg('B', ['abcB3c'], 'c') call Assert_reg('B', 'v', "abcB3\nabcB3l\nabcB3c", "['abcB3', 'abcB3l', 'abcB3c']", "abcB3\nabcB3l\nabcB3c", "['abcB3', 'abcB3l', 'abcB3c']") call Assert_regput('B', ['==', '=abcB3', 'abcB3l', 'abcB3c=']) call setreg('C', ['abcC3l'], 'l') call Assert_reg('C', 'V', "abcC3\nabcC3b\nabcC3l\n", "['abcC3', 'abcC3b', 'abcC3l']", "abcC3\nabcC3b\nabcC3l\n", "['abcC3', 'abcC3b', 'abcC3l']") call Assert_regput('C', ['==', 'abcC3', 'abcC3b', 'abcC3l', '==']) call setreg('D', ['abcD3b'], 'b') call Assert_reg('D', "\6", "abcD3\nabcD32\nabcD3b", "['abcD3', 'abcD32', 'abcD3b']", "abcD3\nabcD32\nabcD3b", "['abcD3', 'abcD32', 'abcD3b']") call Assert_regput('D', ['==', '=abcD3 =', ' abcD32', ' abcD3b']) " Appending lists with NL with setreg() call setreg('A', ["\n", 'abcA3l2'], 'l') call Assert_reg('A', "V", "abcA3\nabcA3c\nabcA32\n\n\nabcA3l2\n", "['abcA3', 'abcA3c', 'abcA32', '\n', 'abcA3l2']", "abcA3\nabcA3c\nabcA32\n\n\nabcA3l2\n", "['abcA3', 'abcA3c', 'abcA32', '\n', 'abcA3l2']") call Assert_regput('A', ['==', 'abcA3', 'abcA3c', 'abcA32', "\n", 'abcA3l2', '==']) call setreg('B', ["\n", 'abcB3c2'], 'c') call Assert_reg('B', "v", "abcB3\nabcB3l\nabcB3c\n\n\nabcB3c2", "['abcB3', 'abcB3l', 'abcB3c', '\n', 'abcB3c2']", "abcB3\nabcB3l\nabcB3c\n\n\nabcB3c2", "['abcB3', 'abcB3l', 'abcB3c', '\n', 'abcB3c2']") call Assert_regput('B', ['==', '=abcB3', 'abcB3l', 'abcB3c', "\n", 'abcB3c2=']) call setreg('C', ["\n", 'abcC3b2'], 'b') call Assert_reg('C', "7", "abcC3\nabcC3b\nabcC3l\n\n\nabcC3b2", "['abcC3', 'abcC3b', 'abcC3l', '\n', 'abcC3b2']", "abcC3\nabcC3b\nabcC3l\n\n\nabcC3b2", "['abcC3', 'abcC3b', 'abcC3l', '\n', 'abcC3b2']") call Assert_regput('C', ['==', '=abcC3 =', ' abcC3b', ' abcC3l', " \n", ' abcC3b2']) call setreg('D', ["\n", 'abcD3b50'],'b50') call Assert_reg('D', "50", "abcD3\nabcD32\nabcD3b\n\n\nabcD3b50", "['abcD3', 'abcD32', 'abcD3b', '\n', 'abcD3b50']", "abcD3\nabcD32\nabcD3b\n\n\nabcD3b50", "['abcD3', 'abcD32', 'abcD3b', '\n', 'abcD3b50']") call Assert_regput('D', ['==', '=abcD3 =', ' abcD32', ' abcD3b', " \n", ' abcD3b50']) " Setting lists with NLs with setreg() call setreg('a', ['abcA4-0', "\n", "abcA4-2\n", "\nabcA4-3", "abcA4-4\nabcA4-4-2"]) call Assert_reg('a', "V", "abcA4-0\n\n\nabcA4-2\n\n\nabcA4-3\nabcA4-4\nabcA4-4-2\n", "['abcA4-0', '\n', 'abcA4-2\n', '\nabcA4-3', 'abcA4-4\nabcA4-4-2']", "abcA4-0\n\n\nabcA4-2\n\n\nabcA4-3\nabcA4-4\nabcA4-4-2\n", "['abcA4-0', '\n', 'abcA4-2\n', '\nabcA4-3', 'abcA4-4\nabcA4-4-2']") call Assert_regput('a', ['==', 'abcA4-0', "\n", "abcA4-2\n", "\nabcA4-3", "abcA4-4\nabcA4-4-2", '==']) call setreg('b', ['abcB4c-0', "\n", "abcB4c-2\n", "\nabcB4c-3", "abcB4c-4\nabcB4c-4-2"], 'c') call Assert_reg('b', "v", "abcB4c-0\n\n\nabcB4c-2\n\n\nabcB4c-3\nabcB4c-4\nabcB4c-4-2", "['abcB4c-0', '\n', 'abcB4c-2\n', '\nabcB4c-3', 'abcB4c-4\nabcB4c-4-2']", "abcB4c-0\n\n\nabcB4c-2\n\n\nabcB4c-3\nabcB4c-4\nabcB4c-4-2", "['abcB4c-0', '\n', 'abcB4c-2\n', '\nabcB4c-3', 'abcB4c-4\nabcB4c-4-2']") call Assert_regput('b', ['==', '=abcB4c-0', "\n", "abcB4c-2\n", "\nabcB4c-3", "abcB4c-4\nabcB4c-4-2="]) call setreg('c', ['abcC4l-0', "\n", "abcC4l-2\n", "\nabcC4l-3", "abcC4l-4\nabcC4l-4-2"], 'l') call Assert_reg('c', "V", "abcC4l-0\n\n\nabcC4l-2\n\n\nabcC4l-3\nabcC4l-4\nabcC4l-4-2\n", "['abcC4l-0', '\n', 'abcC4l-2\n', '\nabcC4l-3', 'abcC4l-4\nabcC4l-4-2']", "abcC4l-0\n\n\nabcC4l-2\n\n\nabcC4l-3\nabcC4l-4\nabcC4l-4-2\n", "['abcC4l-0', '\n', 'abcC4l-2\n', '\nabcC4l-3', 'abcC4l-4\nabcC4l-4-2']") call Assert_regput('c', ['==', 'abcC4l-0', "\n", "abcC4l-2\n", "\nabcC4l-3", "abcC4l-4\nabcC4l-4-2", '==']) call setreg('d', ['abcD4b-0', "\n", "abcD4b-2\n", "\nabcD4b-3", "abcD4b-4\nabcD4b-4-2"], 'b') call Assert_reg('d', "19", "abcD4b-0\n\n\nabcD4b-2\n\n\nabcD4b-3\nabcD4b-4\nabcD4b-4-2", "['abcD4b-0', '\n', 'abcD4b-2\n', '\nabcD4b-3', 'abcD4b-4\nabcD4b-4-2']", "abcD4b-0\n\n\nabcD4b-2\n\n\nabcD4b-3\nabcD4b-4\nabcD4b-4-2", "['abcD4b-0', '\n', 'abcD4b-2\n', '\nabcD4b-3', 'abcD4b-4\nabcD4b-4-2']") call Assert_regput('d', ['==', '=abcD4b-0 =', " \n", " abcD4b-2\n", " \nabcD4b-3", " abcD4b-4\nabcD4b-4-2"]) call setreg('e', ['abcE4b10-0', "\n", "abcE4b10-2\n", "\nabcE4b10-3", "abcE4b10-4\nabcE4b10-4-2"], 'b10') call Assert_reg('e', "10", "abcE4b10-0\n\n\nabcE4b10-2\n\n\nabcE4b10-3\nabcE4b10-4\nabcE4b10-4-2", "['abcE4b10-0', '\n', 'abcE4b10-2\n', '\nabcE4b10-3', 'abcE4b10-4\nabcE4b10-4-2']", "abcE4b10-0\n\n\nabcE4b10-2\n\n\nabcE4b10-3\nabcE4b10-4\nabcE4b10-4-2", "['abcE4b10-0', '\n', 'abcE4b10-2\n', '\nabcE4b10-3', 'abcE4b10-4\nabcE4b10-4-2']") call Assert_regput('e', ['==', '=abcE4b10-0=', " \n", " abcE4b10-2\n", " \nabcE4b10-3", " abcE4b10-4\nabcE4b10-4-2"]) " Search and expressions call setreg('/', ['abc/']) call Assert_reg('/', 'v', "abc/", "['abc/']", "abc/", "['abc/']") call Assert_regput('/', ['==', '=abc/=']) call setreg('/', ["abc/\n"]) call Assert_reg('/', 'v', "abc/\n", "['abc/\n']", "abc/\n", "['abc/\n']") call Assert_regput('/', ['==', "=abc/\n="]) call setreg('=', ['"abc/"']) call Assert_reg('=', 'v', "abc/", "['abc/']", '"abc/"', "['\"abc/\"']") call setreg('=', ["\"abc/\n\""]) call Assert_reg('=', 'v', "abc/\n", "['abc/\n']", "\"abc/\n\"", "['\"abc/\n\"']") " System clipboard if has('clipboard') new | only! call setline(1, ['clipboard contents', 'something else']) " Save and restore system clipboard. " If no connection to X-Server is possible, test should succeed. let _clipreg = ['*', getreg('*'), getregtype('*')] let _clipopt = &cb let &cb='unnamed' 1y call Assert_reg('*', 'V', "clipboard contents\n", "['clipboard contents']", "clipboard contents\n", "['clipboard contents']") tabdo :windo :echo "hi" 2y call Assert_reg('*', 'V', "something else\n", "['something else']", "something else\n", "['something else']") let &cb=_clipopt call call('setreg', _clipreg) enew! endif " Error cases call assert_fails('call setreg()', 'E119:') call assert_fails('call setreg(1)', 'E119:') call assert_fails('call setreg(1, 2, 3, 4)', 'E118:') call assert_fails('call setreg([], 2)', 'E730:') call assert_fails('call setreg(1, 2, [])', 'E730:') call assert_fails('call setreg("/", ["1", "2"])', 'E883:') call assert_fails('call setreg("=", ["1", "2"])', 'E883:') call assert_fails('call setreg(1, ["", "", [], ""])', 'E730:') endfunc func Test_curly_assignment() let s:svar = 'svar' let g:gvar = 'gvar' let lname = 'gvar' let gname = 'gvar' let {'s:'.lname} = {'g:'.gname} call assert_equal('gvar', s:gvar) let s:gvar = '' let { 's:'.lname } = { 'g:'.gname } call assert_equal('gvar', s:gvar) let s:gvar = '' let { 's:' . lname } = { 'g:' . gname } call assert_equal('gvar', s:gvar) let s:gvar = '' let { 's:' .. lname } = { 'g:' .. gname } call assert_equal('gvar', s:gvar) unlet s:svar unlet s:gvar unlet g:gvar endfunc func Test_deep_recursion() " this was running out of stack call assert_fails("exe 'if ' .. repeat('(', 1002)", 'E1169: Expression too recursive: ((') endfunc " K_SPECIAL in the modified character used be escaped, which causes " double-escaping with feedkeys() or as the return value of an mapping, " and doesn't match what getchar() returns, func Test_modified_char_no_escape_special() nnoremap let g:got_m_ellipsis += 1 call feedkeys("\", 't') call assert_equal("\", getchar()) let g:got_m_ellipsis = 0 call feedkeys("\", 'xt') call assert_equal(1, g:got_m_ellipsis) func Func() return "\" endfunc nmap Func() call feedkeys("\", 'xt') call assert_equal(2, g:got_m_ellipsis) delfunc Func nunmap unlet g:got_m_ellipsis nunmap endfunc func Test_eval_string_in_special_key() " this was using the '{' inside <> as the start of an interpolated string silent! echo 0{1-$"\n|nö% endfunc func s:Available() return get(g:, "vim_cp_available", v:true) endfunc func s:Paste(reg) let l:t = g:vim_paste if l:t == "tuple" return ("c", ["a", "tuple", a:reg]) elseif l:t == "list" return ["c", ["a", "list", a:reg]] elseif l:t == "block" return ("b40", ["a", "block"]) elseif l:t == "empty" return ("c", []) elseif l:t == "invalid" return ("INVALID", []) elseif l:t == "invalid2" return ("c", ["test", [1, 2]]) elseif l:t == "count" let g:vim_paste_count[a:reg] += 1 let g:vim_test = "hello" return ("c", ["hello"]) elseif l:t == "store" let l:s = get(g:, "vim_reg_store", []) if (len(l:s) > 0) return (l:s[0], l:s[1]) else return ("c", []) endif endif endfunc func s:Copy(reg, type, lines) if exists("g:vim_copy_count") let g:vim_copy_count[a:reg] += 1 endif let g:vim_copy = { \ "reg": a:reg, \ "type": a:type, \ "lines": a:lines \ } let g:vim_reg_store = (a:type, a:lines) endfunc func Test_clipboard_provider_available() CheckFeature clipboard_provider let g:vim_cp_available = v:true let v:clipproviders["test"] = { \ "available": function("s:Available"), \ } set clipmethod=test call assert_equal("test", v:clipmethod) let g:vim_cp_available = v:false clipreset call assert_notequal("test", v:clipmethod) " Invalid return value let g:vim_cp_available = "invalid" call assert_fails('set clipmethod=test', "E474:") call assert_notequal("test", v:clipmethod) let v:clipproviders["test"] = {} clipreset " Should default to TRUE call assert_equal("test", v:clipmethod) set clipmethod& endfunc func Test_clipboard_provider_paste() CheckFeature clipboard_provider let v:clipproviders["test"] = { \ "paste": { \ '+': function("s:Paste"), \ '*': function("s:Paste") \ } \ } set clipmethod=test let g:vim_paste = "tuple" call assert_equal(["a", "tuple", "+"], getreg("+", 1, 1)) call assert_equal(["a", "tuple", "*"], getreg("*", 1, 1)) let g:vim_paste = "list" call assert_equal(["a", "list", "+"], getreg("+", 1, 1)) call assert_equal(["a", "list", "*"], getreg("*", 1, 1)) let g:vim_paste = "block" call assert_equal("40", getregtype("+")) call assert_equal("40", getregtype("*")) let g:vim_paste = "empty" call assert_equal([], getreg("+", 1, 1)) call assert_equal([], getreg("*", 1, 1)) let g:vim_paste = "invalid" call assert_fails('call getreg("+", 1, 1)', "E474:") call assert_fails('call getreg("*", 1, 1)', "E474:") let g:vim_paste = "invalid2" call assert_fails('call getreg("+", 1, 1)', "E730:") call assert_fails('call getreg("*", 1, 1)', "E730:") " Test put new let g:vim_paste = "tuple" put! * call assert_equal(["a", "tuple", "*"], getline(1, 3)) put + call assert_equal(["a", "tuple", "+"], getline(4, 6)) bw! set clipmethod& endfunc func Test_clipboard_provider_copy() CheckFeature clipboard_provider function s:copy_cb_to_test_partial(_, reg, type, str) call s:Copy(a:reg, a:type, a:str) endfunction let v:clipproviders["test"] = { \ "copy": { \ '+': function("s:Copy"), \ '*': function("s:copy_cb_to_test_partial", [""]) \ } \ } set clipmethod=test " Test charwise call setreg("+", ["hello", "world!"], "c") call assert_equal("+",g:vim_copy.reg) call assert_equal(["hello", "world!"], g:vim_copy.lines) call assert_equal("v", g:vim_copy.type) call setreg("*", ["hello", "world!"], "c") call assert_equal("*",g:vim_copy.reg) call assert_equal(["hello", "world!"], g:vim_copy.lines) call assert_equal("v", g:vim_copy.type) " Test linewise call setreg("+", ["hello", "world!"], "l") call assert_equal("+",g:vim_copy.reg) call assert_equal(["hello", "world!"], g:vim_copy.lines) call assert_equal("V", g:vim_copy.type) call setreg("*", ["hello", "world!"], "l") call assert_equal("*",g:vim_copy.reg) call assert_equal(["hello", "world!"], g:vim_copy.lines) call assert_equal("V", g:vim_copy.type) " Test blockwise call setreg("+", ["hello", "world!"], "b40") call assert_equal("+",g:vim_copy.reg) call assert_equal(["hello", "world!"], g:vim_copy.lines) call assert_equal("40", g:vim_copy.type) call setreg("*", ["hello", "world!"], "b40") call assert_equal("*",g:vim_copy.reg) call assert_equal(["hello", "world!"], g:vim_copy.lines) call assert_equal("40", g:vim_copy.type) " Test yanking new call setline(1, "TESTING") yank * call assert_equal("*",g:vim_copy.reg) call assert_equal(["TESTING"], g:vim_copy.lines) call assert_equal("V", g:vim_copy.type) call setline(1, "TESTING2") yank + call assert_equal("+",g:vim_copy.reg) call assert_equal(["TESTING2"], g:vim_copy.lines) call assert_equal("V", g:vim_copy.type) bw! set clipmethod& endfunc " Test on platforms where only the * register is available (+ points to *), " and that the clipboard provider feature exposes the + register only when " clipmethod is set to a provider. If not, then the plus register points to the " star register like normal. func Test_clipboard_provider_no_unamedplus() CheckFeature clipboard_provider CheckNotFeature unnamedplus CheckFeature clipboard_working let g:vim_paste = "store" let v:clipproviders["test"] = {} set clipmethod=test call assert_equal(1, has('unnamedplus')) call setreg("+", ["plus"], "c") call setreg("*", ["star"], "c") call assert_equal("plus", getreg("+")) call assert_equal("star", getreg("*")) set clipmethod= call assert_equal(0, has('unnamedplus')) call setreg("+", ["plus2"], "c") call setreg("*", ["star2"], "c") call assert_equal("star2", getreg("+")) call assert_equal("star2", getreg("*")) set clipmethod& endfunc " Same as Test_clipboard_provider_registers() but do it when +clipboard isn't " enabled. func Test_clipboard_provider_no_clipboard() CheckFeature clipboard_provider CheckNotFeature clipboard let v:clipproviders["test"] = { \ "paste": { \ '+': function("s:Paste"), \ '*': function("s:Paste") \ }, \ "copy": { \ '+': function("s:Copy"), \ '*': function("s:Copy") \ } \ } call assert_fails('call setreg("+", "")', 'E354:') call assert_fails('call setreg("*", "")', 'E354:') let g:vim_paste = "tuple" set clipmethod=test call assert_equal(["a", "tuple", "+"], getreg("+", 1, 1)) call assert_equal(["a", "tuple", "*"], getreg("*", 1, 1)) set clipmethod& endfunc " Test if clipboard provider feature doesn't break existing clipboard " functionality. func Test_clipboard_provider_sys_clipboard() CheckFeature clipboard_provider CheckFeature clipboard_working let v:clipproviders["test"] = { \ "paste": { \ '+': function("s:Paste"), \ '*': function("s:Paste") \ }, \ "copy": { \ '+': function("s:Copy"), \ '*': function("s:Copy") \ } \ } call setreg("*", "hello world from the * register!", "c") call assert_equal("hello world from the * register!", getreg("*")) call setreg("+", "hello world from the + register!", "c") call assert_equal("hello world from the + register!", getreg("+")) let g:vim_paste = "tuple" set clipmethod=test call assert_equal(1, has('clipboard_working')) call setreg("*", "hello world!", "c") call assert_equal(["a", "tuple", "*"], getreg("*", 1, 1)) call assert_equal(["a", "tuple", "+"], getreg("+", 1, 1)) new call setline(1, "TESTING") yank * call assert_equal("*",g:vim_copy.reg) call assert_equal(["TESTING"], g:vim_copy.lines) call assert_equal("V", g:vim_copy.type) put * call assert_equal(["TESTING", "a", "tuple", "*"], getline(1, 4)) bw! set clipmethod& call setreg("*", "testing 1 2 3", "c") call assert_equal("testing 1 2 3", getreg("*")) call setreg("+", "testing 1 2 3 4 5", "c") call assert_equal("testing 1 2 3 4 5", getreg("+")) set clipmethod& endfunc " Test if the provider callback are only called once per register on operations " that may try calling them multiple times. func Test_clipboard_provider_accessed_once() CheckFeature clipboard_provider let v:clipproviders["test"] = { \ "paste": { \ '+': function("s:Paste"), \ '*': function("s:Paste") \ }, \ "copy": { \ '+': function("s:Copy"), \ '*': function("s:Copy") \ } \ } set clipmethod=test let g:vim_paste = "count" let g:vim_paste_count = {'*': 0, '+': 0} let g:vim_copy_count = {'*': 0, '+': 0} " Test if the paste callback is only called once per register when the " :registers/:display cmd is run. for i in range(1, 10) registers call assert_equal(i, g:vim_paste_count['*']) call assert_equal(i, g:vim_paste_count['+']) endfor let g:vim_paste_count = {'*': 0, '+': 0} let g:vim_copy_count = {'*': 0, '+': 0} " Test same for :global new call setline(1, "The quick brown fox jumps over the lazy dog") call execute(':global/quick/:put +') call execute(':global/quick/:put *') call assert_equal(1, g:vim_paste_count['+']) call assert_equal(1, g:vim_paste_count['*']) call assert_equal(0, g:vim_copy_count['+']) call assert_equal(0, g:vim_copy_count['*']) let g:vim_paste_count = {'*': 0, '+': 0} call execute(':global/quick/:yank +') call execute(':global/quick/:yank *') call assert_equal(1, g:vim_copy_count['+']) call assert_equal(1, g:vim_copy_count['*']) call assert_equal(0, g:vim_paste_count['+']) call assert_equal(0, g:vim_paste_count['*']) bw! new " Test same for changing and deleting text when 'clipboard' is " unnamed/unnamedplus. let g:vim_paste_count = {'*': 0, '+': 0} let g:vim_copy_count = {'*': 0, '+': 0} set clipboard=unnamed call setline(1, "testing") normal cw call assert_equal(0, g:vim_paste_count['*']) call assert_equal(1, g:vim_copy_count['*']) set clipboard=unnamedplus call setline(1, "testing") normal dw call assert_equal(0, g:vim_paste_count['+']) call assert_equal(1, g:vim_copy_count['+']) bw! set clipmethod& set clipboard& endfunc " Test if the copying does not call the paste callback, and pasting does not all " the copy callback. func Test_clipboard_provider_copy_paste_independent() CheckFeature clipboard_provider let v:clipproviders["test"] = { \ "paste": { \ '+': function("s:Paste"), \ '*': function("s:Paste") \ }, \ "copy": { \ '+': function("s:Copy"), \ '*': function("s:Copy") \ } \ } set clipmethod=test let g:vim_paste = "count" let g:vim_paste_count = {'*': 0, '+': 0} let g:vim_copy_count = {'*': 0, '+': 0} new put + put * bw! call getreg("+") call getreg("*") call assert_equal(0, g:vim_copy_count['*']) call assert_equal(0, g:vim_copy_count['+']) let g:vim_paste_count = {'*': 0, '+': 0} " Emitting TextYankPost event may cause a clipboard access augroup Test autocmd! autocmd TextYankPost * let g:test = 2 augroup END new call setline(1, "The quick brown fox jumps over the lazy dog") yank + yank * bw! autocmd! Test call setreg("+", "hello") call setreg("*", "hello") call assert_equal(0, g:vim_paste_count['*']) call assert_equal(0, g:vim_paste_count['+']) set clipmethod& endfunc " Test if clipboard provider feature works under :redir and execute() func Test_clipboard_provider_redir_execute() CheckFeature clipboard_provider let v:clipproviders["test"] = { \ "copy": { \ '+': function("s:Copy"), \ '*': function("s:Copy") \ } \ } set clipmethod=test redir @+ echom "testing" redir END call assert_equal("+",g:vim_copy.reg) call assert_equal(["", "testing"], g:vim_copy.lines) call assert_equal("v", g:vim_copy.type) let @+ = execute("echom 'hello world'") call assert_equal("+",g:vim_copy.reg) call assert_equal(["", "hello world"], g:vim_copy.lines) call assert_equal("v", g:vim_copy.type) set clipmethod& endfunc " Test if clipboard provider feature respects the "unnamed" and "unnamedplus" " values in the 'clipboard' option, and ignores the "autoselect" value. func Test_clipboard_provider_clipboard_option() CheckFeature clipboard_provider let v:clipproviders["test"] = { \ "paste": { \ '+': function("s:Paste"), \ '*': function("s:Paste") \ }, \ "copy": { \ '+': function("s:Copy"), \ '*': function("s:Copy") \ } \ } set clipmethod=test let g:vim_paste = "tuple" new call setline(1, "hello world!") set clipboard=unnamed yank call assert_equal("*",g:vim_copy.reg) call assert_equal(["hello world!"], g:vim_copy.lines) call assert_equal("V", g:vim_copy.type) put call assert_equal(["a", "tuple", "*"], getline(2, 4)) set clipboard=unnamedplus call cursor(1, 0) yank call assert_equal("+",g:vim_copy.reg) call assert_equal(["hello world!"], g:vim_copy.lines) call assert_equal("V", g:vim_copy.type) put call assert_equal(["a", "tuple", "+"], getline(2, 4)) set clipboard=unnamed,unnamedplus call setline(1, "testing") call cursor(1, 0) yank call assert_equal(["testing"], g:vim_copy.lines) call assert_equal(["testing"], g:vim_copy.lines) if has('clipboard') " Test that autoselect option is ignored, this can happen when visual " selection ends and there is TextYankPost autocmd set clipboard=autoselect let g:autoselect_test = 1 au TextYankPost * let g:autoselect_test = 0 call setline(1, "Hello world!") call cursor(1, 0) call feedkeys("vww\", "x!") call assert_equal(1, g:autoselect_test) endif " Change and delete operations are tested in " Test_clipboard_provider_accessed_once() bw! " Check if only "unnamed" and "unnamedplus" values are allowed when no " +clipboard feature (including cmdline expansion). if !has('clipboard') call assert_fails("set clipboard=autoselect", "E474:") call assert_equal(["unnamed,unnamedplus", "unnamed", "unnamedplus"], \ getcompletion('set clipboard=', 'cmdline')) endif set clipmethod& set clipboard& endfunc " vim: shiftwidth=2 sts=2 expandtab