Vim: search and highlight but do not jump

SearchVim

Search Problem Overview


The super star (*) key in Vim will search for the word under the cursor and jump forward to the next match. The user can jump to the next matches with the n key. If hlsearch is enabled, it will also highlight the matches.

I want to be able to press * and get the highlighted matches and be able to navigate the matches using the n key. However, I do not want Vim to jump to the next match when * is pressed, it should remain on the current word. Is there a way to do this?

Search Solutions


Solution 1 - Search

I would map:

nnoremap * *``

Works exactly like you want, except that it adds a jump in the jump list. To prevent that you need:

nnoremap * :keepjumps normal! mi*`i<CR>

Solution 2 - Search

I found this works pretty well, there's no blink and it doesn't need an intermediate register.

nnoremap <silent> * :let @/= '\<' . expand('<cword>') . '\>' <bar> set hls <cr>

Or if you want the g* behavior:

nnoremap <silent> g* :let @/=expand('<cword>') <bar> set hls <cr>

Solution 3 - Search

The best solution:

  1. don't add a jump to the jump list
  2. the behavior of the star key is not be changed

so, try the plugin: http://www.vim.org/scripts/script.php?script_id=4335

Much better than:

" a jump adds to the jump list
nnoremap * *``
" I got a dead loop on macvim
nnoremap * :keepjumps normal *``<cr>
" the behavior is changed
nnoremap <silent> <Leader>* :let @/='\<<C-R>=expand("<cword>")<CR>\>'<CR>:set hls<CR>

Solution 4 - Search

I haven't seen this one yet:

nmap <silent> * "syiw<Esc>: let @/ = @s<CR>

It's very short and does not involve jumping around which can result in blinking.

Explanation: copy the word under cursor to s register and then set the search register (/) to the content of s register. The search register is not writeable directly, that's why the let is necessary and hence the silent to keep vim's command line clean.

Solution 5 - Search

I have the following in my .vimrc, which I think works better than the other alternatives:

" Put word under cursor into search register and highlight
nnoremap <silent> <Leader>* :let @/='\<<C-R>=expand("<cword>")<CR>\>'<CR>:set hls<CR>
vnoremap <silent> <Leader>* :<C-U>
  \let old_reg=getreg('"')<Bar>let old_regtype=getregtype('"')<CR>
  \gvy:let @/=substitute(
  \escape(@", '/\.*$^~['), '\_s\+', '\\_s\\+', 'g')<CR>
  \gV:call setreg('"', old_reg, old_regtype)<CR>:set hls<CR>

Solution 6 - Search

If you want to keep the current view and add the search to the history, try this [not so efficient] solution:

noremap * msHmt`s*`tzt`s

It is using the marks s (save) and t (top).

Solution 7 - Search

A simple solution came to my mind: put map * *# in .vimrc file (it will blink though).

Solution 8 - Search

Many answers here outline rather simple mappings that work well for common cases, but may have side effects (like flickering by jumping back and forth) or lack robustness (may break if some regexp characters are defined as keyword characters).

If you're looking for a robust implementation and don't mind installing a plugin, you can choose from a plethora of alternatives, many of which also offer additional search-related improvements:

  • My SearchHighlighting plugin changes the * command, extends it to visual selections, and offers optional auto-searching of the word under the cursor.
  • star search changes the behavior of * to not jump to the next match, and includes the visual search from the next plugin
  • vim-visual-star-search provides searching of the visual selection
  • visualstar.vim provides searching of the visual selection
  • select & search can use either n/N or * in the visual selection, and can avoid jumping.
  • vim-asterisk provides a z* mapping that also doesn't jump, visual *, more intuitive smartcase handling, and can keep the cursor position when jumping (like ,*)
  • searchant.vim hooks into the built-in search commands and provides a separate highlighting for the match last jumped to.

Solution 9 - Search

The other answers here are good, particularly @rodrigo's, but I wanted to write a solution that preserves scroll position and does so without affecting any of the marks.

This works for me:

function! StarPositionSave()
  let g:star_position_cursor = getpos('.')
  normal! H
  let g:star_position_top = getpos('.')
  call setpos('.', g:star_position_cursor)
endfunction
function! StarPositionRestore()
  call setpos('.', g:star_position_top)
  normal! zt
  call setpos('.', g:star_position_cursor)
endfunction
nnoremap <silent> * :call StarPositionSave()<CR>*:call StarPositionRestore()<CR>

Putting normal! * in the function directly doesn't seem to work, as (at least in neovim) it suppresses search highlighting from being triggered (as if :nohlsearch was run).

Solution 10 - Search

My solution:

nnoremap <silent><expr> * v:count ? '*'
      \ : ':silent execute "keepjumps normal! *" <Bar> call winrestview(' . string(winsaveview()) . ')<CR>'
nnoremap <silent><expr> g* v:count ? 'g*'
      \ : ':silent execute "keepjumps normal! g*" <Bar> call winrestview(' . string(winsaveview()) . ')<CR>'

Edit: Recent Vim has <Cmd> mapping, so you can use below to avoid CmdlineEnter/Leave to be fired.

nnoremap <expr> * v:count ? '*'
      \ : '<Cmd>silent keepjumps normal! *<CR><Cmd>call winrestview(' .. string(winsaveview()) .. ')<CR>'
nnoremap <expr> g* v:count ? 'g*'
      \ : '<Cmd>silent keepjumps normal! g*<CR><Cmd>call winrestview(' .. string(winsaveview()) .. ')<CR>'

Pros:

  • No flickering.
  • Jump list remains unchanged.
  • With a count, it invokes original *; you can use 1* if you miss the original *.
  • Marks and registers are untouched.
  • Using original *, its behavior is almost identical with * (except for jumping).
    This means 'smartcase' is ignored as * do.
  • No need to install plugins.

Solution 11 - Search

Similar to * we have

[I ..................... it shows where the word under the cursor appears

I also have some useful lines on my vimrc that can, maybe, help you

" When double click a word vim will hightlight all other ocurences
" see CountWordFunction()
" [I shows lines with word under the cursor
nnoremap <silent> <2-LeftMouse> :let @/='\V\<'.escape(expand('<cword>'), '\').'\>'<cr>:set hls<cr>:CountWord<cr>
nnoremap <Leader>* :let @/='\V\<'.escape(expand('<cword>'), '\').'\>'<cr>:set hls<cr>:CountWord<cr>

if !exists('*CountWordFunction')
    fun! CountWordFunction()
        try
            let l:win_view = winsaveview()
            exec "%s/" . expand("<cword>") . "//gn"
        finally
            call winrestview(l:win_view)
        endtry
    endfun
endif

command! -nargs=0 CountWord :call CountWordFunction()
cnoreabbrev cw CountWord
nnoremap <F3> :CountWord<CR>

Solution 12 - Search

I'm adding this answer because I found the other answers either, centered the line in the view (which I found distracting), or seemed overly complicated.

The following command works well for me:

noremap * :let @/ = "\\<<C-r><C-w>\\>"<cr>:set hlsearch<cr>

It simply sets the pattern to the whole word under the cursor and then turns on (or updates) the highlighting for the search pattern.

  • NOTE: It doesn't modify the search history (which I prefer but might not be quite what you want).

Solution 13 - Search

just do

nnoremap * *N
nnoremap # #n

works with this http://www.vim.org/scripts/script.php?script_id=4335 too like so:

vnoremap * :<C-u>call VisualStarSearchSet('/')<CR>/<C-R>=@/<CR><CR>N
vnoremap # :<C-u>call VisualStarSearchSet('?')<CR>?<C-R>=@/<CR><CR>n

Solution 14 - Search

:map cc :let @/ = '\<'.expand('<cword>').'\>'\|set hlsearch<C-M>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAshwin NanjappaView Question on Stackoverflow
Solution 1 - Searchmb14View Answer on Stackoverflow
Solution 2 - SearchUriView Answer on Stackoverflow
Solution 3 - Searchname5566View Answer on Stackoverflow
Solution 4 - SearchSebastian BlaskView Answer on Stackoverflow
Solution 5 - SearchJeetView Answer on Stackoverflow
Solution 6 - SearchRodrigo FariasView Answer on Stackoverflow
Solution 7 - SearchkhachikView Answer on Stackoverflow
Solution 8 - SearchIngo KarkatView Answer on Stackoverflow
Solution 9 - SearchSophie AlpertView Answer on Stackoverflow
Solution 10 - SearchBakudankunView Answer on Stackoverflow
Solution 11 - SearchSergioAraujoView Answer on Stackoverflow
Solution 12 - Searchpev.hallView Answer on Stackoverflow
Solution 13 - Searchuser18084014View Answer on Stackoverflow
Solution 14 - SearchZaid GharaybehView Answer on Stackoverflow