Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to map a key in command-line mode but not in search mode

Tags:

vim

I want to map a key in VIM in command-line mode but not in search mode(with a leading /), like below:

  • Map Q to q
  • Map W to w

Sometimes I typed the wrong command in VIM, like :Q and :W, and I want to make these wrong commands to be right.

If I can map Q to q and W to w, I can make the wrong commands to be right.

I tried cmap Q q and cmap W w, but this will also affect the search mode, i.e. /Query to be /query (actually you can't type the upper Q).

And I also tried cabbrev Q q, and this will also affect the search mode.

So, is there any other command that can meet my requirement?

Thanks.

like image 680
chenzhiwei Avatar asked Sep 27 '22 15:09

chenzhiwei


1 Answers

There are a number of ways to do it, and neither is really straightforward.

With command you need to take care of attributes:

command! -nargs=* -complete=file -range=% -bang -bar W w
command! -bang -bar Q q

With cabbrev the pitfalls are described in the wiki, so you need to do it like this:

cnoreabbrev W <C-r>=(getcmdtype()==':' && getcmdpos()==1 ? 'w' : 'W')<CR>

I have a function for this purpose:

function! s:CAbbrev(from, to)
    execute 'cnoreabbrev ' . a:from . ' <C-r>=(getcmdtype()==#'':'' && getcmdpos()==1 ? ' . string(a:to) . ' : ' . string(a:from) . ')<CR>'
endfunction

With cmap you need the <expr> qualifier, and you need more or less the same precautions as with cabbrev:

cnoremap <nowait> <expr> W getcmdtype() ==# ':' && getcmdpos() == 1 ? 'w' : 'W'

The safest is probably the cabbrev way.

like image 146
lcd047 Avatar answered Oct 06 '22 20:10

lcd047