Emacs style highlighting for incremental search in vim - vim

In Vim, is there a way to enable on-the-fly highlighting for all matches when searching?
If I enable incsearch and type "/something" it will highlight the first match only. If I enable hlsearch and type "/something", nothing happens until I press enter (it only highlights the previous search).
In emacs the first match will be highlighted, and (after a slight delay) all other matches on the screen are highlighted in a different color, giving almost instant feedback when scanning for matches in a piece of code.

Doesn't answer your question, but maybe this Wikia post can help?
Quote from that post:
Put the following code in your vimrc, or create file
~/.vim/plugin/autohighlight.vim (Unix) or
$HOME/vimfiles/plugin/autohighlight.vim (Windows) containing the
script below. Then restart Vim.
To automatically highlight the current word, type z/. To turn off,
type z/ again.
" Highlight all instances of word under cursor, when idle.
" Useful when studying strange source code.
" Type z/ to toggle highlighting on/off.
nnoremap z/ :if AutoHighlightToggle()<Bar>set hls<Bar>endif<CR>
function! AutoHighlightToggle()
let #/ = ''
if exists('#auto_highlight')
au! auto_highlight
augroup! auto_highlight
setl updatetime=4000
echo 'Highlight current word: off'
return 0
else
augroup auto_highlight
au!
au CursorHold * let #/ = '\V\<'.escape(expand('<cword>'), '\').'\>'
augroup end
setl updatetime=500
echo 'Highlight current word: ON'
return 1
endif
endfunction

Add this to your .vimrc
hi Search guifg=black guibg=#C6C5FE gui=BOLD ctermfg=black ctermbg=cyan cterm=BOLD
Of course, you might want to change the colors to suit your needs.

Related

How do I change the background color of current buffer or pane in vim?

Imagine I'm coding, and I have different split panes open. What settings should I pass into vimrc to change the background color as I switch from one buffer/pane to another?
I have tried:
autocmd BufEnter * highlight Normal ctermbg=black
autocmd BufLeave * highlight Normal ctermbg=white
I would like to add that I am sure that I've got 256 colors enabled
Actually, there is a way to get this effect. See the answer by #blueyed to this related question: vim - dim inactive split panes. He provides the script below and when placed in my .vimrc it does dim the background of inactive windows. In effect, it makes their background the same colour specified for the colorcolumn (the vertical line indicating your desired text width).
" Dim inactive windows using 'colorcolumn' setting
" This tends to slow down redrawing, but is very useful.
" Based on https://groups.google.com/d/msg/vim_use/IJU-Vk-QLJE/xz4hjPjCRBUJ
" XXX: this will only work with lines containing text (i.e. not '~')
" from
if exists('+colorcolumn')
function! s:DimInactiveWindows()
for i in range(1, tabpagewinnr(tabpagenr(), '$'))
let l:range = ""
if i != winnr()
if &wrap
" HACK: when wrapping lines is enabled, we use the maximum number
" of columns getting highlighted. This might get calculated by
" looking for the longest visible line and using a multiple of
" winwidth().
let l:width=256 " max
else
let l:width=winwidth(i)
endif
let l:range = join(range(1, l:width), ',')
endif
call setwinvar(i, '&colorcolumn', l:range)
endfor
endfunction
augroup DimInactiveWindows
au!
au WinEnter * call s:DimInactiveWindows()
au WinEnter * set cursorline
au WinLeave * set nocursorline
augroup END
endif
You can't. The :highlight groups are global; i.e. when you have multiple window :splits, all window backgrounds will be colored by the same Normal highlight group.
The only differentiation between active and non-active windows is the (blinking) cursor and the differently highlighted status line (i.e. StatusLine vs. StatusLineNC). (You can add other differences, e.g. by only turning on 'cursorline' in the current buffer (see my CursorLineCurrentWindow plugin.))
One of the design goals of Vim is to work equally well in a primitive, low-color console as in the GUI GVIM. When you have only 16 colors available, a distinction by background color is likely to clash with the syntax highlighting. I guess that is the reason why Vim hasn't and will not have this functionality.
Basically what Kent said above will work -- surprisingly well at that. The only limitation is that you can only dim the foreground color. Copy this into vimrc, and evoke :call ToggleDimInactiveWin().
let opt_DimInactiveWin=0
hi Inactive ctermfg=235
fun! ToggleDimInactiveWin()
if g:opt_DimInactiveWin
autocmd! DimWindows
windo syntax clear Inactive
else
windo syntax region Inactive start='^' end='$'
syntax clear Inactive
augroup DimWindows
autocmd BufEnter * syntax clear Inactive
autocmd BufLeave * syntax region Inactive start='^' end='$'
augroup end
en
let g:opt_DimInactiveWin=!g:opt_DimInactiveWin
endfun
A few things I had to look up in writing this:
(1) windo conveniently executes a command across all windows
(2) augroup defines autocommand groups, which can be cleared with autocmd! group
For Neovim users, there is the winhighlight option. The help file provides the following example:
Example: show a different color for non-current windows:
set winhighlight=Normal:MyNormal,NormalNC:MyNormalNC
Personally, I use my statusline to let me know this. I use the WinEnter and WinLeave autocmds to switch to an inactive status line (grayed out) when leaving and an active statusline (bright colors) when entering. The split panes you mention are windows in vim. This also works because :help statusline tells us that its setting is global or local to a window, so you can use :setlocal statusline=... or let &l:statusline=... to only apply to the current window.
Your method won't work because a) BufEnter and BufLeave aren't necessarily the events that you want and b) highlight groups are global, so changing Normal's definition changes it for every window.

How to toggle Vim's search highlight visibility without disabling it

What I'd like is to map one key, e.g. F4, so that pressing F4 will toggle the visibility of search highlights, and so that starting a new search enables visibility no matter the current visibility.
What I've tried:
Mapping F4 to :nohlsearch temporarily disables highlight visibility without turning the hlsearch setting off, but it does not toggle visibility back again.
Mapping F4 to :set hlsearch! does toggle on/off, but I don't want to toggle the hlsearch setting off, just the visibility setting. If hlsearch is off then it doesn't come back automatically with a new search.
There doesn't seem to be an opposite form of :nohlsearch and the command itself has problems being called from a function.
I've found similiar questions, but they don't provide an answer.
Update:
The first comment provides exactly what I was asking for, reproduced below:
let hlstate=0
nnoremap <F4> :if (hlstate == 0) \| nohlsearch \| else \| set hlsearch \| endif \| let hlstate=1-hlstate<cr>
(N.B. for anyone using this --- cramming the map onto one line instead of using a function is necessary since you can't effect a change on highlighting from inside a function.)
Related question for slightly different functionality: https://stackoverflow.com/a/16750393/1176650
Note, recent Vims (7.4.79) have the v:hlsearch variable available. This means you can improve your mapping to:
:nnoremap <silent><expr> <Leader>h (&hls && v:hlsearch ? ':nohls' : ':set hls')."\n"
" ctrl+c to toggle highlight.
let hlstate=0
nnoremap <c-c> :if (hlstate%2 == 0) \| nohlsearch \| else \| set hlsearch \| endif \| let hlstate=hlstate+1<cr>
Now just press ctrl+c to toggle highlight. Only quirk is you gotta press it twice after a search to toggle off highlight because searching doesn't increment the counter.
What I'd like is to map one key, e.g. F4, so that pressing F4 will
toggle the visibility of search highlights, and so that starting a new
search enables visibility no matter the current visibility.
Just tried this and seems to do the trick:
" switch higlight no matter the previous state
nmap <F4> :set hls! <cr>
" hit '/' highlights then enter search mode
nnoremap / :set hlsearch<cr>/
You can toggle with :set invhlsearch
From Highlight all search pattern matches, we can map a key to toggle the highlighting states. Unlike trusktr's answer, here we do use a variable to store the state.
"If you want to be able to enable/disable highlighting quickly, you can map a key to toggle the hlsearch option":
" Press F4 to toggle highlighting on/off, and show current value.
:noremap <F4> :set hlsearch! hlsearch?<CR>
"Or, press return to temporarily get out of the highlighted search":
:nnoremap <CR> :nohlsearch<CR><CR>
Other answer need to toggle highlight search, this is not so good.
Actually you only need to
let #/ = ''
I write a little function to implement this feature, and highlight current word (just like * star key), but not jump to next matched word, and not touch jumplist.
function! HLtoggle()
if (#/ == '')
let #/ = expand("<cword>")
else
let #/ = ''
endif
endfunc
it's simple, but i'm not find it in google.
Have fun with vim! :)
Okay, try this:
:map <F12> :set nohls<CR>:let #/ = ""<CR>:set hls<CR>
Then if you hit F12, it turns of the higlighting, then sets the last search string to an empty one (that is: clears it), and turns back on the highlighting.
Or if you want to save the search string, then you can do something like:
:map <F12> :set nohls<CR>:let #s = #/<CR>:let #/ = ""<CR>:set hls<CR>
:map <SHIFT><F12> :let #/=#s<CR>
Now after pressing SHIFTF12 the original searchstring will be set back and highlighted.
If that still not satisfy you, you can still do it like:
:map <F12> :highlight Search term=None ctermfg=None ctermbg=None guifg=None guibg=None<CR>
:map <SHIFT><F12> :highlight Search term=OV1 ctermfg=OV2 ctermbg=OV3 guifg=OV4 guibg=OV5<CR>
Where OVx are the original values which you can write down when you issue a :highlight Search<CR>. This way it can be turned off then set back on, but with two keyboard shortcuts. If you want it with one, you should create a function for that which toggles it, then create a mapping for that function.
Hmm, isn't :set hlsearch the opposite of :nohlsearch?
The first one turns matches highlighting on, the second one turns matches highlighting off temporarilly.
I don't understand what you mean by "I don't want to toggle the 'hlsearch' setting itself, just the visibility setting.": :set hlsearch and its pendant only deal with the visibility ("highlighting") of search matches, nothing else.
If you want to have matches highlighted each time you do a search just add :set hlsearch to your ~/.vimrc.
If you want the ability to turn highlighting off after a search just map F4 to :nohlsearch, highlighting will be back at your next search.
I use this slightly improved version from trusktr. Note that ctrl+c as used in the example from trusktr is already mapped to Escape by default which is very handy.
" Toggle highlight search
let hlstate=0
nnomap <Leader>b :if (hlstate%2 == 0) \| nohlsearch \| else \| set hlsearch \| endif \| let hlstate=hlstate+1<CR>:echo "toggled visibility for hlsearch"<CR>
inomap <Leader>b <ESC>:if (hlstate%2 == 0) \| nohlsearch \| else \| set hlsearch \| endif \| let hlstate=hlstate+1<CR>:echo "toggled visibility for hlsearch"<CR>a
In order to accomplish this, I added this unsophisticated line in my .vimrc:
nmap <LEADER>h /xxxxx<CR>
I use the following:
augroup onsearch
autocmd!
autocmd VimEnter * set hlsearch
augroup END
nnoremap <leader>/ :set hlsearch!<CR>
The autogroup ensure's that highlighting is enabled when entering vim, but not switched on when re-sourcing your vimrc file(s). The mapping toggles it on and off.
If anyone is looking to do this in neovim (in lua) this is a simple command that I wrote:
HLSTATE = vim.opt.hlsearch
function TOGGLE_SEARCH_HIGHLIGTING()
if HLSTATE == true then
vim.opt.hlsearch = false
HLSTATE = false
else
vim.opt.hlsearch = true
HLSTATE = true
end
end
vim.api.nvim_create_user_command('HighlightToggle', 'lua TOGGLE_SEARCH_HIGHLIGTING()', {})
You can then run it with the command :HighlightToggle (and assign in a keymap if you want).

Vim: Different line-number color in the different modes

I've just started using Vim and I find myself being confused on which mode I'm currently in. I was wondering if it's possible to change the line number color (which I have displayed by default) in the different modes (command, visual, and insert) so that I can easily identify it.
Vim has an option called showmode that will put a message on the last line if you are not in normal mode. See :help 'showmode' for more info.
If you really want to change the background of the number column while in insert mode, you could do something like the following:
autocmd InsertEnter * highlight LineNr ctermbg=red guibg=red
autocmd InsertLeave * highlight LineNr ctermbg=black guibg=black
Note that this method will break if you are bad and use C-c to exit insert mode instead of <Esc> or <C-[.
Relevant :help tags: autocmd, autocmd-events, highlight, highlight-groups

How to highlight all occurrences of a selected word in VIM?

How can I highlight all occurrence of a selected word in GVim, like in Notepad++?
In Normal mode:
:set hlsearch
Then search for a pattern with the command / in Normal mode, or <Ctrl>o followed by / in Insert mode. * in Normal mode will search for the next occurrence of the word under the cursor. The hlsearch option will highlight all of them if set. # will search for the previous occurrence of the word.
To remove the highlight of the previous search:
:nohlsearch
You might wish to map :nohlsearch<CR> to some convenient key.
The * key will highlight all occurrences of the word that is under the cursor.
I know than it's a really old question, but if someone is interested in this feature, can check this code
http://vim.wikia.com/wiki/Auto_highlight_current_word_when_idle
" Highlight all instances of word under cursor, when idle.
" Useful when studying strange source code.
" Type z/ to toggle highlighting on/off.
nnoremap z/ :if AutoHighlightToggle()<Bar>set hls<Bar>endif<CR>
function! AutoHighlightToggle()
let #/ = ''
if exists('#auto_highlight')
au! auto_highlight
augroup! auto_highlight
setl updatetime=4000
echo 'Highlight current word: off'
return 0
else
augroup auto_highlight
au!
au CursorHold * let #/ = '\V\<'.escape(expand('<cword>'), '\').'\>'
augroup end
setl updatetime=500
echo 'Highlight current word: ON'
return 1
endif
endfunction
the simplest way, type in normal mode *
I also have these mappings to enable and disable
"highligh search enabled by default
set hlsearch
"now you can toggle it
nnoremap <S-F11> <ESC>:set hls! hls?<cr>
inoremap <S-F11> <C-o>:set hls! hls?<cr>
vnoremap <S-F11> <ESC>:set hls! hls?<cr> <bar> gv
Select word by clickin on it
set mouse=a "Enables mouse click
nnoremap <silent> <2-LeftMouse> :let #/='\V\<'.escape(expand('<cword>'), '\').'\>'<cr>:set hls<cr>
Bonus: CountWordFunction
fun! CountWordFunction()
try
let l:win_view = winsaveview()
let l:old_query = getreg('/')
let var = expand("<cword>")
exec "%s/" . var . "//gn"
finally
call winrestview(l:win_view)
call setreg('/', l:old_query)
endtry
endfun
" Bellow we set a command "CountWord" and a mapping to count word
" change as you like it
command! -nargs=0 CountWord :call CountWordFunction()
nnoremap <f3> :CountWord<CR>
Selecting word with mouse and counting occurrences at once:
OBS: Notice that in this version we have "CountWord" command at the end
nnoremap <silent> <2-LeftMouse> :let #/='\V\<'.escape(expand('<cword>'), '\').'\>'<cr>:set hls<cr>:CountWord<cr>
Search based solutions (*, /...) move cursor, which may be unfortunate.
An alternative is to use enhanced mark.vim plugin, then complete your .vimrc to let double-click trigger highlighting (I don't know how a keyboard selection may trigger a command) :
"Use Mark plugin to highlight selected word
map <2-leftmouse> \m
It allows multiple highlightings, persistence, etc.
To remove highlighting, either :
Double click again
:Mark (switch off until next selection)
:MarkClear
First (or in your .vimrc):
:set hlsearch
Then position your cursor over the word you want highlighted, and hit *.
hlsearch means highlight all occurrences of the current search, and * means search for the word under the cursor.
to highlight word without moving cursor, plop
" highlight reg. ex. in #/ register
set hlsearch
" remap `*`/`#` to search forwards/backwards (resp.)
" w/o moving cursor
nnoremap <silent> * :execute "normal! *N"<cr>
nnoremap <silent> # :execute "normal! #n"<cr>
into your vimrc.
What's nice about this is g* and g# will still work like "normal" * and #.
To set hlsearch off, you can use "short-form" (unless you have another function that starts with "noh" in command mode): :noh. Or you can use long version: :nohlsearch
For extreme convenience (I find myself toggling hlsearch maybe 20 times per day), you can map something to toggle hlsearch like so:
" search highlight toggle
nnoremap <silent> <leader>st :set hlsearch!<cr>
.:. if your <leader> is \ (it is by default), you can press \st (quickly) in normal mode to toggle hlsearch.
Or maybe you just want to have :noh mapped:
" search clear
nnoremap <silent> <leader>sc :nohlsearch<cr>
The above simply runs :nohlsearch so (unlike :set hlsearch!) it will still highlight word next time you press * or # in normal mode.
cheers
For example this plugIns:
https://github.com/rrethy/vim-illuminate
https://github.com/itchyny/vim-cursorword
Just search for under cursor in vimawesome.com
The key, as clagccs mentioned, is that the highlight does NOT conflict with your search: https://vim.fandom.com/wiki/Auto_highlight_current_word_when_idle
Screen-shot of how it does NOT conflict with search:
Notes:
vim-illuminate highlights by default, in my screen-shot I switched to underline
vim-illuminate highlights/underlines word under cursor by default, in my screen-shot I unset it
my colorschemes are very grey-ish. Check yours to customize it too.
First ensure that hlsearch is enabled by issuing the following command
:set hlsearch
You can also add this to your .vimrc file as set
set hlsearch
now when you use the quick search mechanism in command mode or a regular search command, all results will be highlighted. To move forward between results, press 'n' to move backwards press 'N'
In normal mode, to perform a quick search for the word under the cursor and to jump to the next occurrence in one command press '*', you can also search for the word under the cursor and move to the previous occurrence by pressing '#'
In normal mode, quick search can also be invoked with the
/searchterm<Enter>
to remove highlights on ocuurences use, I have bound this to a shortcut in my .vimrc
:nohl
set hlsearch
maybe ?
Enable search highlighting:
:set hlsearch
Then search for the word:
/word<Enter>
My favorite for doing this is the mark.vim plugin.
It allows to highlight several words in different colors simultaneously.
Example Screenshot
Use autocmd CursorMoved * exe printf('match IncSearch /\V\<%s\>/', escape(expand('<cword>'), '/\'))
Make sure you have IncSearch set to something. e.g call s:Attr('IncSearch', 'reverse'). Alternatively you can use another highlight group in its place.
This will highlight all occurrences of words under your cursor without a delay. I find that a delay slows me down when I'm wizzing through code. The highlight color will match the color of the word, so it stays consistent with your scheme.
Why not just:
z/
That will highlight the current word under cursor and any other occurrences. And you don't have to give a separate command for each item you're searching for. Perhaps that's not available in the unholy gvim? It's in vim by default.
* is only good if you want the cursor to move to the next occurrence. When comparing two things visually you often don't want the cursor to move, and it's annoying to hit the * key every time.
Add those lines in your ~/.vimrc file
" highlight the searched items
set hlsearch
" F8 search for word under the cursor recursively , :copen , to close -> :ccl
nnoremap <F8> :grep! "\<<cword>\>" . -r<CR>:copen 33<CR>
Reload the settings with :so%
In normal model go over the word.
Press * Press F8 to search recursively bellow your whole project over the word
--> if you want to highlight a text occurrences in gvim
Select the text & copy
then ?paste the selected text (Note: This will not work for insert mode)

Highlight variable under cursor in Vim like in NetBeans

I worked in NetBeans and liked this feature: when you place cursor in a variable name all occurences of the variable are highlighted. This is very useful for quick searching all occurences of the variable. Is it possible to add this behavior to Vim?
This autocommand will do what you want:
:autocmd CursorMoved * exe printf('match IncSearch /\V\<%s\>/', escape(expand('<cword>'), '/\'))
Edit: I have used the IncSearch highlight group in my example, but you can find other colours to use by running this command:
:so $VIMRUNTIME/syntax/hitest.vim
If you set
:set hlsearch
to highlight all occurrences of a search pattern, and then use * or # to find occurrences of the word under your cursor, that will get you some way to what you want. However I think a syntax-aware variable highlighting is beyond the scope of VIM.
This statement will allow a variable to enable/disable highlighting all occurences of the word under the cursor:
:autocmd CursorMoved * exe exists("HlUnderCursor")?HlUnderCursor?printf('match IncSearch /\V\<%s\>/', escape(expand('<cword>'), '/\')):'match none':""
One would activate highlighting with:
:let HlUnderCursor=1
And disable it with:
:let HlUnderCursor=0
One could easily define a shortcut key for enabling/disabling highlighting:
:nnoremap <silent> <F3> :exe "let HlUnderCursor=exists(\"HlUnderCursor\")?HlUnderCursor*-1+1:1"<CR>
Deleting the variable would prevent the match statement from executing, and not clear the current highlight:
:unlet HlUnderCursor
If you do not want to highlight language words (statements / preprocs such as if, #define) when your cursor is on these words, you can put this function in your .vimrc based on the #too_much_php answer :
let g:no_highlight_group_for_current_word=["Statement", "Comment", "Type", "PreProc"]
function s:HighlightWordUnderCursor()
let l:syntaxgroup = synIDattr(synIDtrans(synID(line("."), stridx(getline("."), expand('<cword>')) + 1, 1)), "name")
if (index(g:no_highlight_group_for_current_word, l:syntaxgroup) == -1)
exe printf('match IncSearch /\V\<%s\>/', escape(expand('<cword>'), '/\'))
else
exe 'match IncSearch /\V\<\>/'
endif
endfunction
autocmd CursorMoved * call s:HighlightWordUnderCursor()
i think that what you really want is the following plugin by Shuhei Kubota:
http://www.vim.org/scripts/script.php?script_id=4306
According to the description: 'This script highlights words under the cursor like many IDEs.'
Cheers.
vim_current_word works out of the box, is syntax aware, and allows customisable colours.
To map F2 to toggle highlighting:
map <F2> :set hlsearch!<CR> * #
It is certainly not perfect. '* #' jumps around a bit much...
This variant is optimized for speed (uses CursorHold instead of CursorMoved) and compatibility with hlsearch. The current search word highlighting will not be disrupted.
" autosave delay, cursorhold trigger, default: 4000ms
setl updatetime=300
" highlight the word under cursor (CursorMoved is inperformant)
highlight WordUnderCursor cterm=underline gui=underline
autocmd CursorHold * call HighlightCursorWord()
function! HighlightCursorWord()
" if hlsearch is active, don't overwrite it!
let search = getreg('/')
let cword = expand('<cword>')
if match(cword, search) == -1
exe printf('match WordUnderCursor /\V\<%s\>/', escape(cword, '/\'))
endif
endfunction
Similar to the accepted answer, but this way allows you to set a delay time after holding the cursor over a word before the highlighting will appear. The 1000 is in milliseconds and means that it will highlight after 1 second.
set updatetime=1000
autocmd CursorHold * exe
\ printf('match IncSearch /\V\<%s\>/', escape(expand('<cword>'), '/\'))
See :h CursorHold for more info.
vim-illuminate does the trick for me.
match-up does the trick for me.
vim match-up: even better % navigate and highlight matching words modern matchit and matchparen
Features
jump between matching words
jump to open & close words
jump inside (z%)
full set of text objects
highlight (), [], & {}
highlight all matching words
display matches off-screen
show where you are (breadcrumbs)
(neovim) tree-sitter integration

Resources