Show Count of Matches in Vim

There is a nice feature in Google Chrome when you do a search. It tells you the number of matches there is for the keyword you are searching for. However, in Vim I don't see such a feature. Some people suggested using %s/pattern//gn or similar:

http://vim.wikia.com/wiki/Count_number_of_matches_of_a_pattern
Unable to count the number of matches in Vim

But that is quite long really!! I am looking for the count when a press the '*', '%', or do any search using '/' and '?'.

Any idea?


Solution 1:

Modern Vim

Starting with Vim 8.1.1270, there's a new feature in core to show the current match position. NeoVim enables this functionality by default, but standard Vim does not.

To enable it in standard Vim, run:

:set shortmess-=S

Originally mentioned below in Ben's answer, and added here for visibility.

Older Versions

In Vim 7.4+, the IndexedSearch plugin can be used.

Check henrik/vim-indexed-search on GitHub to ensure you get the latest version.

Solution 2:

I don't know of a direct way of doing it, but you could make use of the way :%s/// uses the last search as the default pattern:

:nmap ,c :%s///gn

You should then be able to do a search and then hit ,c to report the number of matches.

The only issue will be that * and # ignore 'smartcase', so the results might be off by a few after using *. You can get round this by doing * followed by /UpENTER and then ,c.

Solution 3:

One addition to @Al's answer: if you want to make vim show it automatically in the statusline, try adding the following to the vimrc:

let s:prevcountcache=[[], 0]
function! ShowCount()
    let key=[@/, b:changedtick]
    if s:prevcountcache[0]==#key
        return s:prevcountcache[1]
    endif
    let s:prevcountcache[0]=key
    let s:prevcountcache[1]=0
    let pos=getpos('.')
    try
        redir => subscount
        silent %s///gne
        redir END
        let result=matchstr(subscount, '\d\+')
        let s:prevcountcache[1]=result
        return result
    finally
        call setpos('.', pos)
    endtry
endfunction
set ruler
let &statusline='%{ShowCount()} %<%f %h%m%r%=%-14.(%l,%c%V%) %P'

Solution 4:

Here's a cheap solution ... I used Find and Replace All in Vim. No fancy scripting. I did a Find X and Replace All with X. At the end, Vim reports "2134 substitutions on 9892 lines". X appeared 2134 times. Use :q! to quit the file without saving it. No harm done.