mirror of
https://github.com/neovim/neovim.git
synced 2024-12-22 04:05:09 -07:00
43c49746d9
Problem: Checks for Dictionary argument often give a vague error message.
Solution: Give a useful error message. (Yegappan Lakshmanan, closes vim/vim#11009)
04c4c5746e
Cherry-pick removal of E922 from docs from patch 9.0.1403.
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
449 lines
13 KiB
VimL
449 lines
13 KiB
VimL
" Tests for search_stats, when "S" is not in 'shortmess'
|
|
|
|
source check.vim
|
|
source screendump.vim
|
|
|
|
func Test_search_stat()
|
|
new
|
|
set shortmess-=S
|
|
" Append 50 lines with text to search for, "foobar" appears 20 times
|
|
call append(0, repeat(['foobar', 'foo', 'fooooobar', 'foba', 'foobar'], 10))
|
|
|
|
call cursor(1, 1)
|
|
|
|
" searchcount() returns an empty dictionary when previous pattern was not set
|
|
call assert_equal({}, searchcount(#{pattern: ''}))
|
|
" but setting @/ should also work (even 'n' nor 'N' was executed)
|
|
" recompute the count when the last position is different.
|
|
call assert_equal(
|
|
\ #{current: 1, exact_match: 1, total: 40, incomplete: 0, maxcount: 99},
|
|
\ searchcount(#{pattern: 'foo'}))
|
|
call assert_equal(
|
|
\ #{current: 0, exact_match: 0, total: 10, incomplete: 0, maxcount: 99},
|
|
\ searchcount(#{pattern: 'fooooobar'}))
|
|
call assert_equal(
|
|
\ #{current: 0, exact_match: 0, total: 10, incomplete: 0, maxcount: 99},
|
|
\ searchcount(#{pattern: 'fooooobar', pos: [2, 1, 0]}))
|
|
call assert_equal(
|
|
\ #{current: 1, exact_match: 1, total: 10, incomplete: 0, maxcount: 99},
|
|
\ searchcount(#{pattern: 'fooooobar', pos: [3, 1, 0]}))
|
|
" on last char of match
|
|
call assert_equal(
|
|
\ #{current: 1, exact_match: 1, total: 10, incomplete: 0, maxcount: 99},
|
|
\ searchcount(#{pattern: 'fooooobar', pos: [3, 9, 0]}))
|
|
" on char after match
|
|
call assert_equal(
|
|
\ #{current: 1, exact_match: 0, total: 10, incomplete: 0, maxcount: 99},
|
|
\ searchcount(#{pattern: 'fooooobar', pos: [3, 10, 0]}))
|
|
call assert_equal(
|
|
\ #{current: 1, exact_match: 0, total: 10, incomplete: 0, maxcount: 99},
|
|
\ searchcount(#{pattern: 'fooooobar', pos: [4, 1, 0]}))
|
|
call assert_equal(
|
|
\ #{current: 1, exact_match: 0, total: 2, incomplete: 2, maxcount: 1},
|
|
\ searchcount(#{pattern: 'fooooobar', pos: [4, 1, 0], maxcount: 1}))
|
|
call assert_equal(
|
|
\ #{current: 0, exact_match: 0, total: 2, incomplete: 2, maxcount: 1},
|
|
\ searchcount(#{pattern: 'fooooobar', maxcount: 1}))
|
|
|
|
" match at second line
|
|
let messages_before = execute('messages')
|
|
let @/ = 'fo*\(bar\?\)\?'
|
|
let g:a = execute(':unsilent :norm! n')
|
|
let stat = '\[2/50\]'
|
|
let pat = escape(@/, '()*?'). '\s\+'
|
|
call assert_match(pat .. stat, g:a)
|
|
call assert_equal(
|
|
\ #{current: 2, exact_match: 1, total: 50, incomplete: 0, maxcount: 99},
|
|
\ searchcount(#{recompute: 0}))
|
|
" didn't get added to message history
|
|
call assert_equal(messages_before, execute('messages'))
|
|
|
|
" Match at last line
|
|
call cursor(line('$')-2, 1)
|
|
let g:a = execute(':unsilent :norm! n')
|
|
let stat = '\[50/50\]'
|
|
call assert_match(pat .. stat, g:a)
|
|
call assert_equal(
|
|
\ #{current: 50, exact_match: 1, total: 50, incomplete: 0, maxcount: 99},
|
|
\ searchcount(#{recompute: 0}))
|
|
|
|
" No search stat
|
|
set shortmess+=S
|
|
call cursor(1, 1)
|
|
let stat = '\[2/50\]'
|
|
let g:a = execute(':unsilent :norm! n')
|
|
call assert_notmatch(pat .. stat, g:a)
|
|
" n does not update search stat
|
|
call assert_equal(
|
|
\ #{current: 50, exact_match: 1, total: 50, incomplete: 0, maxcount: 99},
|
|
\ searchcount(#{recompute: 0}))
|
|
call assert_equal(
|
|
\ #{current: 2, exact_match: 1, total: 50, incomplete: 0, maxcount: 99},
|
|
\ searchcount(#{recompute: v:true}))
|
|
set shortmess-=S
|
|
|
|
" Many matches
|
|
call cursor(line('$')-2, 1)
|
|
let @/ = '.'
|
|
let pat = escape(@/, '()*?'). '\s\+'
|
|
let g:a = execute(':unsilent :norm! n')
|
|
let stat = '\[>99/>99\]'
|
|
call assert_match(pat .. stat, g:a)
|
|
call assert_equal(
|
|
\ #{current: 100, exact_match: 0, total: 100, incomplete: 2, maxcount: 99},
|
|
\ searchcount(#{recompute: 0}))
|
|
call assert_equal(
|
|
\ #{current: 272, exact_match: 1, total: 280, incomplete: 0, maxcount: 0},
|
|
\ searchcount(#{recompute: v:true, maxcount: 0, timeout: 200}))
|
|
call assert_equal(
|
|
\ #{current: 1, exact_match: 1, total: 280, incomplete: 0, maxcount: 0},
|
|
\ searchcount(#{recompute: 1, maxcount: 0, pos: [1, 1, 0], timeout: 200}))
|
|
call cursor(line('$'), 1)
|
|
let g:a = execute(':unsilent :norm! n')
|
|
let stat = 'W \[1/>99\]'
|
|
call assert_match(pat .. stat, g:a)
|
|
call assert_equal(
|
|
\ #{current: 1, exact_match: 1, total: 100, incomplete: 2, maxcount: 99},
|
|
\ searchcount(#{recompute: 0}))
|
|
call assert_equal(
|
|
\ #{current: 1, exact_match: 1, total: 280, incomplete: 0, maxcount: 0},
|
|
\ searchcount(#{recompute: 1, maxcount: 0, timeout: 200}))
|
|
call assert_equal(
|
|
\ #{current: 271, exact_match: 1, total: 280, incomplete: 0, maxcount: 0},
|
|
\ searchcount(#{recompute: 1, maxcount: 0, pos: [line('$')-2, 1, 0], timeout: 200}))
|
|
|
|
" Many matches
|
|
call cursor(1, 1)
|
|
let g:a = execute(':unsilent :norm! n')
|
|
let stat = '\[2/>99\]'
|
|
call assert_match(pat .. stat, g:a)
|
|
call cursor(1, 1)
|
|
let g:a = execute(':unsilent :norm! N')
|
|
let stat = 'W \[>99/>99\]'
|
|
call assert_match(pat .. stat, g:a)
|
|
|
|
" right-left
|
|
if exists("+rightleft")
|
|
set rl
|
|
call cursor(1,1)
|
|
let @/ = 'foobar'
|
|
let pat = 'raboof/\s\+'
|
|
let g:a = execute(':unsilent :norm! n')
|
|
let stat = '\[20/2\]'
|
|
call assert_match(pat .. stat, g:a)
|
|
set norl
|
|
endif
|
|
|
|
" right-left bottom
|
|
if exists("+rightleft")
|
|
set rl
|
|
call cursor('$',1)
|
|
let pat = 'raboof?\s\+'
|
|
let g:a = execute(':unsilent :norm! N')
|
|
let stat = '\[20/20\]'
|
|
call assert_match(pat .. stat, g:a)
|
|
set norl
|
|
endif
|
|
|
|
" right-left back at top
|
|
if exists("+rightleft")
|
|
set rl
|
|
call cursor('$',1)
|
|
let pat = 'raboof/\s\+'
|
|
let g:a = execute(':unsilent :norm! n')
|
|
let stat = 'W \[20/1\]'
|
|
call assert_match(pat .. stat, g:a)
|
|
call assert_match('search hit BOTTOM, continuing at TOP', g:a)
|
|
set norl
|
|
endif
|
|
|
|
" normal, back at bottom
|
|
call cursor(1,1)
|
|
let @/ = 'foobar'
|
|
let pat = '?foobar\s\+'
|
|
let g:a = execute(':unsilent :norm! N')
|
|
let stat = 'W \[20/20\]'
|
|
call assert_match(pat .. stat, g:a)
|
|
call assert_match('search hit TOP, continuing at BOTTOM', g:a)
|
|
call assert_match('W \[20/20\]', Screenline(&lines))
|
|
|
|
" normal, no match
|
|
call cursor(1,1)
|
|
let @/ = 'zzzzzz'
|
|
let g:a = ''
|
|
try
|
|
let g:a = execute(':unsilent :norm! n')
|
|
catch /^Vim\%((\a\+)\)\=:E486/
|
|
let stat = ''
|
|
" error message is not redir'ed to g:a, it is empty
|
|
call assert_true(empty(g:a))
|
|
catch
|
|
call assert_false(1)
|
|
endtry
|
|
|
|
" with count
|
|
call cursor(1, 1)
|
|
let @/ = 'fo*\(bar\?\)\?'
|
|
let g:a = execute(':unsilent :norm! 2n')
|
|
let stat = '\[3/50\]'
|
|
let pat = escape(@/, '()*?'). '\s\+'
|
|
call assert_match(pat .. stat, g:a)
|
|
let g:a = execute(':unsilent :norm! 2n')
|
|
let stat = '\[5/50\]'
|
|
call assert_match(pat .. stat, g:a)
|
|
|
|
" with offset
|
|
call cursor(1, 1)
|
|
call feedkeys("/fo*\\(bar\\?\\)\\?/+1\<cr>", 'tx')
|
|
let g:a = execute(':unsilent :norm! n')
|
|
let stat = '\[5/50\]'
|
|
let pat = escape(@/ .. '/+1', '()*?'). '\s\+'
|
|
call assert_match(pat .. stat, g:a)
|
|
|
|
" normal, n comes from a mapping
|
|
" Need to move over more than 64 lines to trigger char_avail(.
|
|
nnoremap n nzv
|
|
call cursor(1,1)
|
|
call append(50, repeat(['foobar', 'foo', 'fooooobar', 'foba', 'foobar'], 10))
|
|
call setline(2, 'find this')
|
|
call setline(70, 'find this')
|
|
let @/ = 'find this'
|
|
let pat = '/find this\s\+'
|
|
let g:a = execute(':unsilent :norm n')
|
|
" g:a will contain several lines
|
|
let g:b = split(g:a, "\n")[-1]
|
|
let stat = '\[1/2\]'
|
|
call assert_match(pat .. stat, g:b)
|
|
unmap n
|
|
|
|
" normal, but silent
|
|
call cursor(1,1)
|
|
let @/ = 'find this'
|
|
let pat = '/find this\s\+'
|
|
let g:a = execute(':norm! n')
|
|
let stat = '\[1/2\]'
|
|
call assert_notmatch(pat .. stat, g:a)
|
|
|
|
" normal, n comes from a silent mapping
|
|
" First test a normal mapping, then a silent mapping
|
|
call cursor(1,1)
|
|
nnoremap n n
|
|
let @/ = 'find this'
|
|
let pat = '/find this\s\+'
|
|
let g:a = execute(':unsilent :norm n')
|
|
let g:b = split(g:a, "\n")[-1]
|
|
let stat = '\[1/2\]'
|
|
call assert_match(pat .. stat, g:b)
|
|
nnoremap <silent> n n
|
|
call cursor(1,1)
|
|
let g:a = execute(':unsilent :norm n')
|
|
let g:b = split(g:a, "\n")[-1]
|
|
let stat = '\[1/2\]'
|
|
call assert_notmatch(pat .. stat, g:b)
|
|
call assert_match(stat, g:b)
|
|
" Test that the message is not truncated
|
|
" it would insert '...' into the output.
|
|
call assert_match('^\s\+' .. stat, g:b)
|
|
unmap n
|
|
|
|
" Time out
|
|
%delete _
|
|
call append(0, repeat(['foobar', 'foo', 'fooooobar', 'foba', 'foobar'], 100000))
|
|
call cursor(1, 1)
|
|
call assert_equal(1, searchcount(#{pattern: 'foo', maxcount: 0, timeout: 1}).incomplete)
|
|
|
|
" Clean up
|
|
set shortmess+=S
|
|
" close the window
|
|
bwipe!
|
|
endfunc
|
|
|
|
func Test_searchcount_fails()
|
|
call assert_fails('echo searchcount("boo!")', 'E1206:')
|
|
call assert_fails('echo searchcount({"timeout" : []})', 'E745:')
|
|
call assert_fails('echo searchcount({"maxcount" : []})', 'E745:')
|
|
call assert_fails('echo searchcount({"pattern" : []})', 'E730:')
|
|
call assert_fails('echo searchcount({"pos" : 1})', 'E475:')
|
|
call assert_fails('echo searchcount({"pos" : [1]})', 'E475:')
|
|
call assert_fails('echo searchcount({"pos" : [[], 2, 3]})', 'E745:')
|
|
call assert_fails('echo searchcount({"pos" : [1, [], 3]})', 'E745:')
|
|
call assert_fails('echo searchcount({"pos" : [1, 2, []]})', 'E745:')
|
|
endfunc
|
|
|
|
func Test_search_stat_narrow_screen()
|
|
" This used to crash Vim
|
|
let save_columns = &columns
|
|
try
|
|
let after =<< trim [CODE]
|
|
set laststatus=2
|
|
set columns=16
|
|
set shortmess-=S showcmd
|
|
call setline(1, 'abc')
|
|
call feedkeys("/abc\<CR>:quit!\<CR>")
|
|
autocmd VimLeavePre * call writefile(["done"], "Xdone")
|
|
[CODE]
|
|
|
|
if !RunVim([], after, '--clean')
|
|
return
|
|
endif
|
|
call assert_equal("done", readfile("Xdone")[0])
|
|
call delete('Xdone')
|
|
finally
|
|
let &columns = save_columns
|
|
endtry
|
|
endfunc
|
|
|
|
func Test_searchcount_in_statusline()
|
|
CheckScreendump
|
|
|
|
let lines =<< trim END
|
|
set shortmess-=S
|
|
call append(0, 'this is something')
|
|
function TestSearchCount() abort
|
|
let search_count = searchcount()
|
|
if !empty(search_count)
|
|
return '[' . search_count.current . '/' . search_count.total . ']'
|
|
else
|
|
return ''
|
|
endif
|
|
endfunction
|
|
set hlsearch
|
|
set laststatus=2 statusline+=%{TestSearchCount()}
|
|
END
|
|
call writefile(lines, 'Xsearchstatusline')
|
|
let buf = RunVimInTerminal('-S Xsearchstatusline', #{rows: 10})
|
|
call TermWait(buf)
|
|
call term_sendkeys(buf, "/something")
|
|
call VerifyScreenDump(buf, 'Test_searchstat_4', {})
|
|
|
|
call term_sendkeys(buf, "\<Esc>")
|
|
call StopVimInTerminal(buf)
|
|
call delete('Xsearchstatusline')
|
|
endfunc
|
|
|
|
func Test_search_stat_foldopen()
|
|
CheckScreendump
|
|
|
|
let lines =<< trim END
|
|
set shortmess-=S
|
|
setl foldenable foldmethod=indent foldopen-=search
|
|
call append(0, ['if', "\tfoo", "\tfoo", 'endif'])
|
|
let @/ = 'foo'
|
|
call cursor(1,1)
|
|
norm n
|
|
END
|
|
call writefile(lines, 'Xsearchstat1')
|
|
|
|
let buf = RunVimInTerminal('-S Xsearchstat1', #{rows: 10})
|
|
call TermWait(buf)
|
|
call VerifyScreenDump(buf, 'Test_searchstat_3', {})
|
|
|
|
call term_sendkeys(buf, "n")
|
|
call TermWait(buf)
|
|
call VerifyScreenDump(buf, 'Test_searchstat_3', {})
|
|
|
|
call term_sendkeys(buf, "n")
|
|
call TermWait(buf)
|
|
call VerifyScreenDump(buf, 'Test_searchstat_3', {})
|
|
|
|
call StopVimInTerminal(buf)
|
|
call delete('Xsearchstat1')
|
|
endfunc
|
|
|
|
func! Test_search_stat_screendump()
|
|
CheckScreendump
|
|
|
|
let lines =<< trim END
|
|
set shortmess-=S
|
|
" Append 50 lines with text to search for, "foobar" appears 20 times
|
|
call append(0, repeat(['foobar', 'foo', 'fooooobar', 'foba', 'foobar'], 20))
|
|
call setline(2, 'find this')
|
|
call setline(70, 'find this')
|
|
nnoremap n n
|
|
let @/ = 'find this'
|
|
call cursor(1,1)
|
|
norm n
|
|
END
|
|
call writefile(lines, 'Xsearchstat')
|
|
let buf = RunVimInTerminal('-S Xsearchstat', #{rows: 10})
|
|
call term_wait(buf)
|
|
call VerifyScreenDump(buf, 'Test_searchstat_1', {})
|
|
|
|
call term_sendkeys(buf, ":nnoremap <silent> n n\<cr>")
|
|
call term_sendkeys(buf, "gg0n")
|
|
call term_wait(buf)
|
|
call VerifyScreenDump(buf, 'Test_searchstat_2', {})
|
|
|
|
call StopVimInTerminal(buf)
|
|
call delete('Xsearchstat')
|
|
endfunc
|
|
|
|
func Test_search_stat_then_gd()
|
|
CheckScreendump
|
|
|
|
let lines =<< trim END
|
|
call setline(1, ['int cat;', 'int dog;', 'cat = dog;'])
|
|
set shortmess-=S
|
|
set hlsearch
|
|
END
|
|
call writefile(lines, 'Xsearchstatgd')
|
|
|
|
let buf = RunVimInTerminal('-S Xsearchstatgd', #{rows: 10})
|
|
call term_sendkeys(buf, "/dog\<CR>")
|
|
call TermWait(buf)
|
|
call VerifyScreenDump(buf, 'Test_searchstatgd_1', {})
|
|
|
|
call term_sendkeys(buf, "G0gD")
|
|
call TermWait(buf)
|
|
call VerifyScreenDump(buf, 'Test_searchstatgd_2', {})
|
|
|
|
call StopVimInTerminal(buf)
|
|
call delete('Xsearchstatgd')
|
|
endfunc
|
|
|
|
func Test_search_stat_and_incsearch()
|
|
CheckScreendump
|
|
|
|
let lines =<< trim END
|
|
call setline(1, ['abc--c', '--------abc', '--abc'])
|
|
set hlsearch
|
|
set incsearch
|
|
set bg=dark
|
|
set showtabline=2
|
|
|
|
function MyTabLine()
|
|
try
|
|
let a=searchcount(#{recompute: 1, maxcount: -1})
|
|
return a.current .. '/' .. a.total
|
|
catch
|
|
return ''
|
|
endtry
|
|
endfunction
|
|
|
|
set tabline=%!MyTabLine()
|
|
END
|
|
call writefile(lines, 'Xsearchstat_inc')
|
|
|
|
let buf = RunVimInTerminal('-S Xsearchstat_inc', #{rows: 10})
|
|
call term_sendkeys(buf, "/abc")
|
|
call TermWait(buf)
|
|
call VerifyScreenDump(buf, 'Test_searchstat_inc_1', {})
|
|
|
|
call term_sendkeys(buf, "\<c-g>")
|
|
call TermWait(buf)
|
|
call VerifyScreenDump(buf, 'Test_searchstat_inc_2', {})
|
|
|
|
call term_sendkeys(buf, "\<c-g>")
|
|
call TermWait(buf)
|
|
call VerifyScreenDump(buf, 'Test_searchstat_inc_3', {})
|
|
|
|
call term_sendkeys(buf, "\<esc>:qa\<cr>")
|
|
call TermWait(buf)
|
|
|
|
call StopVimInTerminal(buf)
|
|
call delete('Xsearchstat_inc')
|
|
endfunc
|
|
|
|
|
|
" vim: shiftwidth=2 sts=2 expandtab
|