Reputation: 1815
When writing mappings in nvim
, I'm sometimes using a search/replace, for instance in this mapping to creating headings that are the same length as the current line (for markdown etc):
nnoremap <leader>= 0Vyp0v$:s/./=/g<cr>:nohls<cr>
While this clears the search highlighting with :nohls
, it still creates the "flash" of the search/replace.
Upvotes: 2
Views: 243
Reputation: 172658
I would make use of :help function-search-undo
and extract the commands into a :function
. This won't clobber the current search pattern, and therefore also doesn't affect search highlighting. To be fully neutral, you just have to remove the used substitution pattern from the search history (via histdel()
):
function! MakeHeading()
normal! Vyp
s/./=/g
call histdel('search', -1)
endfunction
nnoremap <leader>= :call MakeHeading()<CR>
Note that I've also simplified the visual selection handling: As V
always selects the entire line, you don't need to go to the first column (^
), neither is the reselection necessary; we can just let :substitute
work on the current (pasted) line.
That reminds me that the canonical implementation of this functionality uses the :help v_r
command, and this indeed requires a re-selection:
nnoremap <leader>= Vyp0v$r=
As there's no pattern involved here, search highlighting is totally unaffected by it :-)
Upvotes: 3
Reputation: 1813
Based on your own answer, I would propose the following:
nnoremap <leader>= :set nohlsearch<cr>0Vyp0v$:s/./=/g<cr>:let @/=''<cr>:set hlsearch<cr>
This just sets the search register to an empty string. So no highlighting. You could even reset it to the previous search string:
nnoremap <leader>= :let olds=@/<cr>0Vyp0v$:s/./=/g<cr>:let @/=olds<cr>
And BTW: Wouldn't yyp:s/./=/g
be easier.
I personally have hlsearch
off by default and only switch it on, when I need it. To toggle it I have the following mapping in my vimrc
:
" Switch on/off higlighting of search string
noremap <F8> :set invhlsearch hlsearch?<CR>
Upvotes: 1
Reputation: 1815
While researching :h :s
and :h s_flags`, and doing more looking around here, part of @Ein's answer stuck out to me:
whenever you run the command
:set hlsearch
there are two effects: It sets the option AND it makes vim forget if you've ever typed:nohlsearch
. In other words, changing'hlsearch'
(either on or off) will force the current"highlight visibility"
to logically match.
With a combination of using :set nohls
and the e
flag (:h s_e
), I ended up with:
nnoremap <leader>= :set nohlsearch<cr>0Vyp0v$:s/./=/g<cr>:s/thanks@Ein//e<cr>:set hlsearch<cr>
" Broken out
" Turn off highlighting
:set nohlsearch
" Yank the whole line, duplicate it, and replace `.` with `=`
0Vyp0v$:s/./=/g
" Do a replace with something I'll never find in a document (probably), with `/e` to suppress errors.
:s/thanks@Ein//e
" Finally, reenable highlighting
:set hlsearch
Any more elegant solutions are welcome. I think I'll be refactoring some of this into a function soon at least, to allow for using other characters like -
for subheadings.
Upvotes: 0