Vi and Vim Stack Exchange is a question and answer site for people using the vi and Vim families of text editors. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I like to define some abbreviations like:

cabbr csf cscope find

I thought cabbr would just be interpreted in the : command line. However, when I entered the search mode \, I found that \csf would still be expanded to \cscope find, which definitely was not what I want.
So how to deal with this situation? If I do want to search csf, what should I do? Or there is another kind of abbreviation other than cabbr intended to be valid just in the : command line? Thanks very much!

share|improve this question
up vote 5 down vote accepted

What you can do is use an expression abbreviation. This will allow you to use any Vim expression on the right-hand side, instead of just a static string. With getcmdtype() we can check if we're doing a normal Ex command or something else.

cabbr <expr> csf getcmdtype() == ':' ? 'cscope find' : 'csf'

See :help :map-<expr> for the documentation.

share|improve this answer

You could also define 2 custom commands :Cab and :Sab which would make the definition of such abbreviations easier.
:Cab would define an abbreviation which would only affect an Ex command, while :Sab would only modify a search.

The following code tries to define these commands:

command! -nargs=+ Cab call s:StrictAbbr(<q-args>, 1)
command! -nargs=+ Sab call s:StrictAbbr(<q-args>, 0)

function! s:StrictAbbr(args, cmd) abort
    let l:lhs = matchstr(a:args, '^\s*\zs\S*')
    let l:rhs = matchstr(a:args, '^\s*\S*\s\+\zs.*')
    if a:cmd
        execute printf("cnoreabbrev <expr> %s getcmdtype() ==# ':' ? '%s' : '%s'", l:lhs, l:rhs, l:lhs)
    else
        execute printf("cnoreabbrev <expr> %s getcmdtype() =~ '[/?]' ? '%s' : '%s'", l:lhs, l:rhs, l:lhs)
    endif
endfunction

Now to define the abbreviation mentioned in your post, you could write :

Cab csf cscope find

And to define the abbreviation which transforms fb in foo bar, but only in a search:

Sab fb foo bar

These abbreviations could be written anywhere in your vimrc, but only after the previous code, otherwise you'll have an error such as:

E492: Not an editor command: Sab fb foo bar

The code is heavily inspired from this post and from the accepted answer.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.