Is it possible to have Vim automatically update the number of matches as you type out the regex search query? As opposed to it only showing the number of matches when you hit enter?
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
I use the following function to add number of matches and the match the cursor is currently on to my statusline:
function statusline#searchcount() abort if !v:hlsearch return '' endif try const count = searchcount({'maxcount': 0, 'timeout': 50}) catch /^Vim\%((\a\+)\)\=:\%(E486\)\@!/ return '[?/??]' endtry return count.total \ ? count.incomplete \ ? printf('[%d/??]', count.current) \ : printf('[%d/%d]', count.current, count.total) \ : '[0/0]' endfunction
The function is called in statusline#main()
which I set to 'statusline'
in my vimrc
. So something like:
" File: autoload/statusline.vim function statusline#main() abort " Other parts of statusline ... let stl ..= '%{statusline#searchcount()}' return stl endfunction " In my vimrc set statusline=%!statusline#main()
There's also a plugin that displays the number of matches in a popup window: https://github.com/obcat/vim-hitspop
Closed #7817.
The problem for a generic solution is: Where to show the count? Either it requires a statusline or some kind of overlay on the window text. There may not be space on the command line itself. There are other complications, such as it has to be asynchronous to avoid a lag in typing the pattern.
Since there is a plugin for those users who really want it, I rather not implement this in code.
@bfrg Thank you for your response. I am not familiar with vim functions, do you know why I am getting this error when I run your function?
@Sebastian-Nielsen
You're getting an error because I gave you only a snippet of the function statusline#main()
. The above was only meant as an example. Try the following here:
set statusline=%<%f\ %h%m%r\ %{statusline#searchcount()}%=%-14.(%l,%c%V%)\ %P
This will add the number of matches to the default statusline.
@bfrg I assume that line is supposed to substitute the set statusline=%!statusline#main()
function in .vimrc
. Having done that, there is still no match count on the fly: (I did remember to save the .vimrc file)
You need to add set laststatus=2
to enable the statusline.
@bfrg Thank you, we're almost there! For some reason though, it always only displays question marks (no matter the search query), any idea why?
You need to add scriptversion 4
at the top of the script-file that contains the statusline#searchcount()
function.
Which Vim version do you have?
Which Vim version do you have?
searchcount()
was added in 8.2.0877.
I just ran sudo apt update
(still doesn't work); here is the version number:
sebastian@ubuntu:~/.vim/autoload$ vim --version
VIM - Vi IMproved 8.1 (2018 May 18, compiled Apr 15 2020 06:40:31)
Included patches: 1-2269
Modified by team...@tracker.debian.org
Compiled by team...@tracker.debian.org
Huge version without GUI. Features included (+) or not (-):
+acl -farsi -mouse_sysmouse -tag_any_white
+arabic +file_in_path +mouse_urxvt -tcl
+autocmd +find_in_path +mouse_xterm +termguicolors
+autochdir +float +multi_byte +terminal
-autoservername +folding +multi_lang +terminfo
-balloon_eval -footer -mzscheme +termresponse
+balloon_eval_term +fork() +netbeans_intg +textobjects
-browse +gettext +num64 +textprop
++builtin_terms -hangul_input +packages +timers
+byte_offset +iconv +path_extra +title
+channel +insert_expand -perl -toolbar
+cindent +job +persistent_undo +user_commands
-clientserver +jumplist +postscript +vartabs
-clipboard +keymap +printer +vertsplit
+cmdline_compl +lambda +profile +virtualedit
+cmdline_hist +langmap -python +visual
+cmdline_info +libcall +python3 +visualextra
+comments +linebreak +quickfix +viminfo
+conceal +lispindent +reltime +vreplace
+cryptv +listcmds +rightleft +wildignore
+cscope +localmap -ruby +wildmenu
+cursorbind -lua +scrollbind +windows
+cursorshape +menu +signs +writebackup
+dialog_con +mksession +smartindent -X11
+diff +modify_fname +sound -xfontset
+digraphs +mouse +spell -xim
-dnd -mouseshape +startuptime -xpm
-ebcdic +mouse_dec +statusline -xsmp
+emacs_tags +mouse_gpm -sun_workshop -xterm_clipboard
+eval -mouse_jsbterm +syntax -xterm_save
+ex_extra +mouse_netterm +tag_binary
+extra_search +mouse_sgr -tag_old_static
system vimrc file: "$VIM/vimrc"
user vimrc file: "$HOME/.vimrc"
2nd user vimrc file: "~/.vim/vimrc"
user exrc file: "$HOME/.exrc"
defaults file: "$VIMRUNTIME/defaults.vim"
fall-back for $VIM: "/usr/share/vim"
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -Wdate-time -g -O2 -fdebug-prefix-map=/build/vim-iU6mZD/vim-8.1.2269=. -fstack-protector-strong -Wformat -Werror=format-security -D_REENTRANT -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
Linking: gcc -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -o vim -lm -ltinfo -lnsl -lselinux -lcanberra -lacl -lattr -lgpm -ldl -L/usr/lib/python3.8/config-3.8-x86_64-linux-gnu -lpython3.8 -lcrypt -lpthread -ldl -lutil -lm -lm
You need to show us the included patches, for example:
$ vim --version | head -2
VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Feb 12 2021 04:05:19)
Included patches: 1-2501
Oh right, here you go:
sebastian@ubuntu:~$ vim --version
VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Feb 11 2021 23:59:16)
Included patches: 1-2501
Can you move the searchcount()
call outside of the try-catch block so that we can see what error is emitted?
Can you try it with this modification:
function statusline#searchcount() abort if !v:hlsearch return '' endif try const count = searchcount({'maxcount': 0, 'timeout': 50}) catch /^Vim\%((\a\+)\)\=:\%(E486\)\@!/ return '[?/??]' endtry
if empty(count) return '' endif
return count.total \ ? count.incomplete \ ? printf('[%d/??]', count.current) \ : printf('[%d/%d]', count.current, count.total) \ : '[0/0]' endfunction
—
After you saved the file, you need to either restart Vim or resource the file with :source %
.
After you saved the file, you need to either restart Vim or resource the file with
:source %
.
Yeah, sorry, that was what I meant I did.
I really don't know why it doesn't work on your computer. Maybe someone else can take a look at this.
The following works on my system:
$ vim --clean test.vim -S test.vim
with
" test.vim function Searchcount() abort
if !v:hlsearch return '' endif try
const cnt = searchcount({'maxcount': 0, 'timeout': 50})
catch /^Vim\%((\a\+)\)\=:\%(E486\)\@!/ return '[?/??]' endtry
if empty(cnt) return '' endif return cnt.total \ ? cnt.incomplete \ ? printf('[%d/??]', cnt.current) \ : printf('[%d/%d]', cnt.current, cnt.total) \ : '[0/0]' endfunction set laststatus=2 set hlsearch set incsearch set statusline=%<%f\ %h%m%r\ %{Searchcount()}%=%-14.(%l,%c%V%)\ %P
You can put this into your vimrc
and try it again.
Notice that I removed the scriptversion 4
. If we do so, we need to rename the variable count
because v:count
is a built-in variable. Prefixing Vim variables with v:
is optional in scriptversion < 3
(see :help scriptversion-3
for more details), therefore count
can't be used as a variable name, unless we prefix it with an l:
.