1" Tests for search_stats, when "S" is not in 'shortmess' 2 3source check.vim 4source screendump.vim 5 6func Test_search_stat() 7 new 8 set shortmess-=S 9 " Append 50 lines with text to search for, "foobar" appears 20 times 10 call append(0, repeat(['foobar', 'foo', 'fooooobar', 'foba', 'foobar'], 10)) 11 12 call cursor(1, 1) 13 14 " searchcount() returns an empty dictionary when previous pattern was not set 15 call assert_equal({}, searchcount(#{pattern: ''})) 16 " but setting @/ should also work (even 'n' nor 'N' was executed) 17 " recompute the count when the last position is different. 18 call assert_equal( 19 \ #{current: 1, exact_match: 1, total: 40, incomplete: 0, maxcount: 99}, 20 \ searchcount(#{pattern: 'foo'})) 21 call assert_equal( 22 \ #{current: 0, exact_match: 0, total: 10, incomplete: 0, maxcount: 99}, 23 \ searchcount(#{pattern: 'fooooobar'})) 24 call assert_equal( 25 \ #{current: 0, exact_match: 0, total: 10, incomplete: 0, maxcount: 99}, 26 \ searchcount(#{pattern: 'fooooobar', pos: [2, 1, 0]})) 27 call assert_equal( 28 \ #{current: 1, exact_match: 1, total: 10, incomplete: 0, maxcount: 99}, 29 \ searchcount(#{pattern: 'fooooobar', pos: [3, 1, 0]})) 30 " on last char of match 31 call assert_equal( 32 \ #{current: 1, exact_match: 1, total: 10, incomplete: 0, maxcount: 99}, 33 \ searchcount(#{pattern: 'fooooobar', pos: [3, 9, 0]})) 34 " on char after match 35 call assert_equal( 36 \ #{current: 1, exact_match: 0, total: 10, incomplete: 0, maxcount: 99}, 37 \ searchcount(#{pattern: 'fooooobar', pos: [3, 10, 0]})) 38 call assert_equal( 39 \ #{current: 1, exact_match: 0, total: 10, incomplete: 0, maxcount: 99}, 40 \ searchcount(#{pattern: 'fooooobar', pos: [4, 1, 0]})) 41 call assert_equal( 42 \ #{current: 1, exact_match: 0, total: 2, incomplete: 2, maxcount: 1}, 43 \ searchcount(#{pattern: 'fooooobar', pos: [4, 1, 0], maxcount: 1})) 44 call assert_equal( 45 \ #{current: 0, exact_match: 0, total: 2, incomplete: 2, maxcount: 1}, 46 \ searchcount(#{pattern: 'fooooobar', maxcount: 1})) 47 48 " match at second line 49 let messages_before = execute('messages') 50 let @/ = 'fo*\(bar\?\)\?' 51 let g:a = execute(':unsilent :norm! n') 52 let stat = '\[2/50\]' 53 let pat = escape(@/, '()*?'). '\s\+' 54 call assert_match(pat .. stat, g:a) 55 call assert_equal( 56 \ #{current: 2, exact_match: 1, total: 50, incomplete: 0, maxcount: 99}, 57 \ searchcount(#{recompute: 0})) 58 " didn't get added to message history 59 call assert_equal(messages_before, execute('messages')) 60 61 " Match at last line 62 call cursor(line('$')-2, 1) 63 let g:a = execute(':unsilent :norm! n') 64 let stat = '\[50/50\]' 65 call assert_match(pat .. stat, g:a) 66 call assert_equal( 67 \ #{current: 50, exact_match: 1, total: 50, incomplete: 0, maxcount: 99}, 68 \ searchcount(#{recompute: 0})) 69 70 " No search stat 71 set shortmess+=S 72 call cursor(1, 1) 73 let stat = '\[2/50\]' 74 let g:a = execute(':unsilent :norm! n') 75 call assert_notmatch(pat .. stat, g:a) 76 " n does not update search stat 77 call assert_equal( 78 \ #{current: 50, exact_match: 1, total: 50, incomplete: 0, maxcount: 99}, 79 \ searchcount(#{recompute: 0})) 80 call assert_equal( 81 \ #{current: 2, exact_match: 1, total: 50, incomplete: 0, maxcount: 99}, 82 \ searchcount(#{recompute: v:true})) 83 set shortmess-=S 84 85 " Many matches 86 call cursor(line('$')-2, 1) 87 let @/ = '.' 88 let pat = escape(@/, '()*?'). '\s\+' 89 let g:a = execute(':unsilent :norm! n') 90 let stat = '\[>99/>99\]' 91 call assert_match(pat .. stat, g:a) 92 call assert_equal( 93 \ #{current: 100, exact_match: 0, total: 100, incomplete: 2, maxcount: 99}, 94 \ searchcount(#{recompute: 0})) 95 call assert_equal( 96 \ #{current: 272, exact_match: 1, total: 280, incomplete: 0, maxcount: 0}, 97 \ searchcount(#{recompute: v:true, maxcount: 0, timeout: 200})) 98 call assert_equal( 99 \ #{current: 1, exact_match: 1, total: 280, incomplete: 0, maxcount: 0}, 100 \ searchcount(#{recompute: 1, maxcount: 0, pos: [1, 1, 0], timeout: 200})) 101 call cursor(line('$'), 1) 102 let g:a = execute(':unsilent :norm! n') 103 let stat = 'W \[1/>99\]' 104 call assert_match(pat .. stat, g:a) 105 call assert_equal( 106 \ #{current: 1, exact_match: 1, total: 100, incomplete: 2, maxcount: 99}, 107 \ searchcount(#{recompute: 0})) 108 call assert_equal( 109 \ #{current: 1, exact_match: 1, total: 280, incomplete: 0, maxcount: 0}, 110 \ searchcount(#{recompute: 1, maxcount: 0, timeout: 200})) 111 call assert_equal( 112 \ #{current: 271, exact_match: 1, total: 280, incomplete: 0, maxcount: 0}, 113 \ searchcount(#{recompute: 1, maxcount: 0, pos: [line('$')-2, 1, 0], timeout: 200})) 114 115 " Many matches 116 call cursor(1, 1) 117 let g:a = execute(':unsilent :norm! n') 118 let stat = '\[2/>99\]' 119 call assert_match(pat .. stat, g:a) 120 call cursor(1, 1) 121 let g:a = execute(':unsilent :norm! N') 122 let stat = 'W \[>99/>99\]' 123 call assert_match(pat .. stat, g:a) 124 125 " right-left 126 if exists("+rightleft") 127 set rl 128 call cursor(1,1) 129 let @/ = 'foobar' 130 let pat = 'raboof/\s\+' 131 let g:a = execute(':unsilent :norm! n') 132 let stat = '\[20/2\]' 133 call assert_match(pat .. stat, g:a) 134 set norl 135 endif 136 137 " right-left bottom 138 if exists("+rightleft") 139 set rl 140 call cursor('$',1) 141 let pat = 'raboof?\s\+' 142 let g:a = execute(':unsilent :norm! N') 143 let stat = '\[20/20\]' 144 call assert_match(pat .. stat, g:a) 145 set norl 146 endif 147 148 " right-left back at top 149 if exists("+rightleft") 150 set rl 151 call cursor('$',1) 152 let pat = 'raboof/\s\+' 153 let g:a = execute(':unsilent :norm! n') 154 let stat = 'W \[20/1\]' 155 call assert_match(pat .. stat, g:a) 156 call assert_match('search hit BOTTOM, continuing at TOP', g:a) 157 set norl 158 endif 159 160 " normal, back at bottom 161 call cursor(1,1) 162 let @/ = 'foobar' 163 let pat = '?foobar\s\+' 164 let g:a = execute(':unsilent :norm! N') 165 let stat = 'W \[20/20\]' 166 call assert_match(pat .. stat, g:a) 167 call assert_match('search hit TOP, continuing at BOTTOM', g:a) 168 call assert_match('W \[20/20\]', Screenline(&lines)) 169 170 " normal, no match 171 call cursor(1,1) 172 let @/ = 'zzzzzz' 173 let g:a = '' 174 try 175 let g:a = execute(':unsilent :norm! n') 176 catch /^Vim\%((\a\+)\)\=:E486/ 177 let stat = '' 178 " error message is not redir'ed to g:a, it is empty 179 call assert_true(empty(g:a)) 180 catch 181 call assert_false(1) 182 endtry 183 184 " with count 185 call cursor(1, 1) 186 let @/ = 'fo*\(bar\?\)\?' 187 let g:a = execute(':unsilent :norm! 2n') 188 let stat = '\[3/50\]' 189 let pat = escape(@/, '()*?'). '\s\+' 190 call assert_match(pat .. stat, g:a) 191 let g:a = execute(':unsilent :norm! 2n') 192 let stat = '\[5/50\]' 193 call assert_match(pat .. stat, g:a) 194 195 " with offset 196 call cursor(1, 1) 197 call feedkeys("/fo*\\(bar\\?\\)\\?/+1\<cr>", 'tx') 198 let g:a = execute(':unsilent :norm! n') 199 let stat = '\[5/50\]' 200 let pat = escape(@/ .. '/+1', '()*?'). '\s\+' 201 call assert_match(pat .. stat, g:a) 202 203 " normal, n comes from a mapping 204 " Need to move over more than 64 lines to trigger char_avail(. 205 nnoremap n nzv 206 call cursor(1,1) 207 call append(50, repeat(['foobar', 'foo', 'fooooobar', 'foba', 'foobar'], 10)) 208 call setline(2, 'find this') 209 call setline(70, 'find this') 210 let @/ = 'find this' 211 let pat = '/find this\s\+' 212 let g:a = execute(':unsilent :norm n') 213 " g:a will contain several lines 214 let g:b = split(g:a, "\n")[-1] 215 let stat = '\[1/2\]' 216 call assert_match(pat .. stat, g:b) 217 unmap n 218 219 " normal, but silent 220 call cursor(1,1) 221 let @/ = 'find this' 222 let pat = '/find this\s\+' 223 let g:a = execute(':norm! n') 224 let stat = '\[1/2\]' 225 call assert_notmatch(pat .. stat, g:a) 226 227 " normal, n comes from a silent mapping 228 " First test a normal mapping, then a silent mapping 229 call cursor(1,1) 230 nnoremap n n 231 let @/ = 'find this' 232 let pat = '/find this\s\+' 233 let g:a = execute(':unsilent :norm n') 234 let g:b = split(g:a, "\n")[-1] 235 let stat = '\[1/2\]' 236 call assert_match(pat .. stat, g:b) 237 nnoremap <silent> n n 238 call cursor(1,1) 239 let g:a = execute(':unsilent :norm n') 240 let g:b = split(g:a, "\n")[-1] 241 let stat = '\[1/2\]' 242 call assert_notmatch(pat .. stat, g:b) 243 call assert_match(stat, g:b) 244 " Test that the message is not truncated 245 " it would insert '...' into the output. 246 call assert_match('^\s\+' .. stat, g:b) 247 unmap n 248 249 " Time out 250 %delete _ 251 call append(0, repeat(['foobar', 'foo', 'fooooobar', 'foba', 'foobar'], 100000)) 252 call cursor(1, 1) 253 call assert_equal(1, searchcount(#{pattern: 'foo', maxcount: 0, timeout: 1}).incomplete) 254 255 " Clean up 256 set shortmess+=S 257 " close the window 258 bwipe! 259endfunc 260 261func Test_searchcount_fails() 262 call assert_fails('echo searchcount("boo!")', 'E715:') 263 call assert_fails('echo searchcount({"timeout" : []})', 'E745:') 264 call assert_fails('echo searchcount({"maxcount" : []})', 'E745:') 265 call assert_fails('echo searchcount({"pattern" : []})', 'E730:') 266 call assert_fails('echo searchcount({"pos" : 1})', 'E475:') 267 call assert_fails('echo searchcount({"pos" : [1]})', 'E475:') 268 call assert_fails('echo searchcount({"pos" : [[], 2, 3]})', 'E745:') 269 call assert_fails('echo searchcount({"pos" : [1, [], 3]})', 'E745:') 270 call assert_fails('echo searchcount({"pos" : [1, 2, []]})', 'E745:') 271endfunc 272 273func Test_searchcount_in_statusline() 274 CheckScreendump 275 276 let lines =<< trim END 277 set shortmess-=S 278 call append(0, 'this is something') 279 function TestSearchCount() abort 280 let search_count = searchcount() 281 if !empty(search_count) 282 return '[' . search_count.current . '/' . search_count.total . ']' 283 else 284 return '' 285 endif 286 endfunction 287 set hlsearch 288 set laststatus=2 statusline+=%{TestSearchCount()} 289 END 290 call writefile(lines, 'Xsearchstatusline') 291 let buf = RunVimInTerminal('-S Xsearchstatusline', #{rows: 10}) 292 call TermWait(buf) 293 call term_sendkeys(buf, "/something") 294 call VerifyScreenDump(buf, 'Test_searchstat_4', {}) 295 296 call term_sendkeys(buf, "\<Esc>") 297 call StopVimInTerminal(buf) 298 call delete('Xsearchstatusline') 299endfunc 300 301func Test_search_stat_foldopen() 302 CheckScreendump 303 304 let lines =<< trim END 305 set shortmess-=S 306 setl foldenable foldmethod=indent foldopen-=search 307 call append(0, ['if', "\tfoo", "\tfoo", 'endif']) 308 let @/ = 'foo' 309 call cursor(1,1) 310 norm n 311 END 312 call writefile(lines, 'Xsearchstat1') 313 314 let buf = RunVimInTerminal('-S Xsearchstat1', #{rows: 10}) 315 call TermWait(buf) 316 call VerifyScreenDump(buf, 'Test_searchstat_3', {}) 317 318 call term_sendkeys(buf, "n") 319 call TermWait(buf) 320 call VerifyScreenDump(buf, 'Test_searchstat_3', {}) 321 322 call term_sendkeys(buf, "n") 323 call TermWait(buf) 324 call VerifyScreenDump(buf, 'Test_searchstat_3', {}) 325 326 call StopVimInTerminal(buf) 327 call delete('Xsearchstat1') 328endfunc 329 330func! Test_search_stat_screendump() 331 CheckScreendump 332 333 let lines =<< trim END 334 set shortmess-=S 335 " Append 50 lines with text to search for, "foobar" appears 20 times 336 call append(0, repeat(['foobar', 'foo', 'fooooobar', 'foba', 'foobar'], 20)) 337 call setline(2, 'find this') 338 call setline(70, 'find this') 339 nnoremap n n 340 let @/ = 'find this' 341 call cursor(1,1) 342 norm n 343 END 344 call writefile(lines, 'Xsearchstat') 345 let buf = RunVimInTerminal('-S Xsearchstat', #{rows: 10}) 346 call TermWait(buf) 347 call VerifyScreenDump(buf, 'Test_searchstat_1', {}) 348 349 call term_sendkeys(buf, ":nnoremap <silent> n n\<cr>") 350 call term_sendkeys(buf, "gg0n") 351 call TermWait(buf) 352 call VerifyScreenDump(buf, 'Test_searchstat_2', {}) 353 354 call StopVimInTerminal(buf) 355 call delete('Xsearchstat') 356endfunc 357 358func Test_search_stat_then_gd() 359 CheckScreendump 360 361 let lines =<< trim END 362 call setline(1, ['int cat;', 'int dog;', 'cat = dog;']) 363 set shortmess-=S 364 set hlsearch 365 END 366 call writefile(lines, 'Xsearchstatgd') 367 368 let buf = RunVimInTerminal('-S Xsearchstatgd', #{rows: 10}) 369 call term_sendkeys(buf, "/dog\<CR>") 370 call TermWait(buf) 371 call VerifyScreenDump(buf, 'Test_searchstatgd_1', {}) 372 373 call term_sendkeys(buf, "G0gD") 374 call TermWait(buf) 375 call VerifyScreenDump(buf, 'Test_searchstatgd_2', {}) 376 377 call StopVimInTerminal(buf) 378 call delete('Xsearchstatgd') 379endfunc 380 381 382 383" vim: shiftwidth=2 sts=2 expandtab 384