1" Test editing line in Ex mode (see :help Q and :help gQ). 2 3source check.vim 4source shared.vim 5 6" Helper function to test editing line in Q Ex mode 7func Ex_Q(cmd) 8 " Is there a simpler way to test editing Ex line? 9 call feedkeys("Q" 10 \ .. "let s:test_ex =<< END\<CR>" 11 \ .. a:cmd .. "\<CR>" 12 \ .. "END\<CR>" 13 \ .. "visual\<CR>", 'tx') 14 return s:test_ex[0] 15endfunc 16 17" Helper function to test editing line in gQ Ex mode 18func Ex_gQ(cmd) 19 call feedkeys("gQ" .. a:cmd .. "\<C-b>\"\<CR>", 'tx') 20 let ret = @:[1:] " Remove leading quote. 21 call feedkeys("visual\<CR>", 'tx') 22 return ret 23endfunc 24 25" Helper function to test editing line with both Q and gQ Ex mode. 26func Ex(cmd) 27 return [Ex_Q(a:cmd), Ex_gQ(a:cmd)] 28endfunc 29 30" Test editing line in Ex mode (both Q and gQ) 31func Test_ex_mode() 32 let encoding_save = &encoding 33 set sw=2 34 35 for e in ['utf8', 'latin1'] 36 exe 'set encoding=' . e 37 38 call assert_equal(['bar', 'bar'], Ex("foo bar\<C-u>bar"), e) 39 call assert_equal(["1\<C-u>2", "1\<C-u>2"], Ex("1\<C-v>\<C-u>2"), e) 40 call assert_equal(["1\<C-b>2\<C-e>3", '213'], Ex("1\<C-b>2\<C-e>3"), e) 41 call assert_equal(['0123', '2013'], Ex("01\<Home>2\<End>3"), e) 42 call assert_equal(['0123', '0213'], Ex("01\<Left>2\<Right>3"), e) 43 call assert_equal(['01234', '0342'], Ex("012\<Left>\<Left>\<Insert>3\<Insert>4"), e) 44 call assert_equal(["foo bar\<C-w>", 'foo '], Ex("foo bar\<C-w>"), e) 45 call assert_equal(['foo', 'foo'], Ex("fooba\<Del>\<Del>"), e) 46 call assert_equal(["foo\tbar", 'foobar'], Ex("foo\<Tab>bar"), e) 47 call assert_equal(["abbrev\t", 'abbreviate'], Ex("abbrev\<Tab>"), e) 48 call assert_equal([' 1', "1\<C-t>\<C-t>"], Ex("1\<C-t>\<C-t>"), e) 49 call assert_equal([' 1', "1\<C-t>\<C-t>"], Ex("1\<C-t>\<C-t>\<C-d>"), e) 50 call assert_equal([' foo', ' foo'], Ex(" foo\<C-d>"), e) 51 call assert_equal(['foo', ' foo0'], Ex(" foo0\<C-d>"), e) 52 call assert_equal(['foo', ' foo^'], Ex(" foo^\<C-d>"), e) 53 call assert_equal(['foo', 'foo'], 54 \ Ex("\<BS>\<C-H>\<Del>\<kDel>foo"), e) 55 " default wildchar <Tab> interferes with this test 56 set wildchar=<c-e> 57 call assert_equal(["a\tb", "a\tb"], Ex("a\t\t\<C-H>b"), e) 58 call assert_equal(["\t mn", "\tm\<C-T>n"], Ex("\tm\<C-T>n"), e) 59 set wildchar& 60 endfor 61 62 set sw& 63 let &encoding = encoding_save 64endfunc 65 66" Test substitute confirmation prompt :%s/pat/str/c in Ex mode 67func Test_Ex_substitute() 68 CheckRunVimInTerminal 69 let buf = RunVimInTerminal('', {'rows': 6}) 70 71 call term_sendkeys(buf, ":call setline(1, ['foo foo', 'foo foo', 'foo foo'])\<CR>") 72 call term_sendkeys(buf, ":set number\<CR>") 73 call term_sendkeys(buf, "gQ") 74 call WaitForAssert({-> assert_match(':', term_getline(buf, 6))}, 1000) 75 76 call term_sendkeys(buf, "%s/foo/bar/gc\<CR>") 77 call WaitForAssert({-> assert_match(' 1 foo foo', term_getline(buf, 5))}, 78 \ 1000) 79 call WaitForAssert({-> assert_match(' ^^^', term_getline(buf, 6))}, 1000) 80 call term_sendkeys(buf, "n\<CR>") 81 call WaitForAssert({-> assert_match(' ^^^', term_getline(buf, 6))}, 82 \ 1000) 83 call term_sendkeys(buf, "y\<CR>") 84 85 call term_sendkeys(buf, "q\<CR>") 86 call WaitForAssert({-> assert_match(':', term_getline(buf, 6))}, 1000) 87 88 " Pressing enter in ex mode should print the current line 89 call term_sendkeys(buf, "\<CR>") 90 call WaitForAssert({-> assert_match(' 3 foo foo', 91 \ term_getline(buf, 5))}, 1000) 92 93 call term_sendkeys(buf, ":vi\<CR>") 94 call WaitForAssert({-> assert_match('foo bar', term_getline(buf, 1))}, 1000) 95 96 call StopVimInTerminal(buf) 97endfunc 98 99" Test for displaying lines from an empty buffer in Ex mode 100func Test_Ex_emptybuf() 101 new 102 call assert_fails('call feedkeys("Q\<CR>", "xt")', 'E749:') 103 call setline(1, "abc") 104 call assert_fails('call feedkeys("Q\<CR>", "xt")', 'E501:') 105 call assert_fails('call feedkeys("Q%d\<CR>", "xt")', 'E749:') 106 close! 107endfunc 108 109" Test for the :open command 110func Test_open_command() 111 new 112 call setline(1, ['foo foo', 'foo bar', 'foo baz']) 113 call feedkeys("Qopen\<CR>j", 'xt') 114 call assert_equal('foo bar', getline('.')) 115 call feedkeys("Qopen /bar/\<CR>", 'xt') 116 call assert_equal(5, col('.')) 117 call assert_fails('call feedkeys("Qopen /baz/\<CR>", "xt")', 'E479:') 118 close! 119endfunc 120 121" Test for :g/pat/visual to run vi commands in Ex mode 122" This used to hang Vim before 8.2.0274. 123func Test_Ex_global() 124 new 125 call setline(1, ['', 'foo', 'bar', 'foo', 'bar', 'foo']) 126 call feedkeys("Q\<bs>g/bar/visual\<CR>$rxQ$ryQvisual\<CR>j", "xt") 127 call assert_equal('bax', getline(3)) 128 call assert_equal('bay', getline(5)) 129 bwipe! 130endfunc 131 132" In Ex-mode, a backslash escapes a newline 133func Test_Ex_escape_enter() 134 call feedkeys("gQlet l = \"a\\\<kEnter>b\"\<cr>vi\<cr>", 'xt') 135 call assert_equal("a\rb", l) 136endfunc 137 138" Test for :append! command in Ex mode 139func Test_Ex_append() 140 new 141 call setline(1, "\t abc") 142 call feedkeys("Qappend!\npqr\nxyz\n.\nvisual\n", 'xt') 143 call assert_equal(["\t abc", "\t pqr", "\t xyz"], getline(1, '$')) 144 close! 145endfunc 146 147" In Ex-mode, backslashes at the end of a command should be halved. 148func Test_Ex_echo_backslash() 149 " This test works only when the language is English 150 CheckEnglish 151 let bsl = '\\\\' 152 let bsl2 = '\\\' 153 call assert_fails('call feedkeys("Qecho " .. bsl .. "\nvisual\n", "xt")', 154 \ "E15: Invalid expression: \\\\") 155 call assert_fails('call feedkeys("Qecho " .. bsl2 .. "\nm\nvisual\n", "xt")', 156 \ "E15: Invalid expression: \\\nm") 157endfunc 158 159func Test_ex_mode_errors() 160 " Not allowed to enter ex mode when text is locked 161 au InsertCharPre <buffer> normal! gQ<CR> 162 let caught_e565 = 0 163 try 164 call feedkeys("ix\<esc>", 'xt') 165 catch /^Vim\%((\a\+)\)\=:E565/ " catch E565 166 let caught_e565 = 1 167 endtry 168 call assert_equal(1, caught_e565) 169 au! InsertCharPre 170 171 new 172 au CmdLineEnter * call ExEnterFunc() 173 func ExEnterFunc() 174 175 endfunc 176 call feedkeys("gQvi\r", 'xt') 177 178 au! CmdLineEnter 179 delfunc ExEnterFunc 180 quit 181endfunc 182 183func Test_ex_mode_with_global() 184 CheckNotGui 185 CheckFeature timers 186 187 " This will get stuck in Normal mode after the failed "J", use a timer to 188 " get going again. 189 let lines =<< trim END 190 call ch_logfile('logfile', 'w') 191 pedit 192 func FeedQ(id) 193 call feedkeys('Q', 't') 194 endfunc 195 call timer_start(10, 'FeedQ') 196 g/^/vi|HJ 197 call writefile(['done'], 'Xdidexmode') 198 qall! 199 END 200 call writefile(lines, 'Xexmodescript') 201 call assert_equal(1, RunVim([], [], '-e -s -S Xexmodescript')) 202 call assert_equal(['done'], readfile('Xdidexmode')) 203 204 call delete('logfile') 205 call delete('Xdidexmode') 206 call delete('Xexmodescript') 207endfunc 208 209func Test_ex_mode_count_overflow() 210 " The multiplication causes an integer overflow 211 CheckNotAsan 212 213 " this used to cause a crash 214 let lines =<< trim END 215 call feedkeys("\<Esc>Q\<CR>") 216 v9|9silent! vi|333333233333y32333333%O 217 call writefile(['done'], 'Xdidexmode') 218 qall! 219 END 220 call writefile(lines, 'Xexmodescript') 221 call assert_equal(1, RunVim([], [], '-e -s -S Xexmodescript -c qa')) 222 call assert_equal(['done'], readfile('Xdidexmode')) 223 224 call delete('Xdidexmode') 225 call delete('Xexmodescript') 226endfunc 227 228" vim: shiftwidth=2 sts=2 expandtab 229