tags:

views:

441

answers:

4

I want to be able to write \bit and have it expand to something in vim. How do I encode a backslash in the left-hand side of an abbreviation, though?

I tried all of these:

:iab \bit replacement_text
:iab <Bslash>bit replacement_text
:iab <bs>bit replacement_text

but got E474: Invalid argument for all of these.

The map_backslash help-topic suggests <Bslash>, but this doesn't seem to work.

+1  A: 

you could

   inoremap \bit replacementtext

Also if you dont like the lag an alternative leader like backtick ` (above the tab for me)

   :iab `f foobar

if you are not using them in your code often

michael
This would work, but not exactly the same way. There'd be an annoying pause after every \ waiting for the rest of it. I don't quite see a way around that though.
sykora
yeah, I tried this myself - and didn't like it.
Peter
I have this for a couple of imaps (using <cr>= for some function processing) you get over the pause (it forces you just type faster :)
michael
+5  A: 

You can define your abbreviation on "bit", and then test if it is preceded by "\", if so, return the new text, or "bit" otherwise.

function! s:Expr(default, repl)
  if getline('.')[col('.')-2]=='\'
    return "\<bs>".a:repl
  else
    return a:default
  endif
endfunction

:inoreab bit <c-r>=<sid>Expr('bit', 'foobar')<cr>

That's the kind of tricks I used in MapNoContext().

EDIT: see :h abbreviations for the reasons why what you asked can't be achieved directly.

EDIT2: It can be easily encapsulated this way:

function! s:DefIab(nore, ...)
  let opt = ''
  let i = 0
  while i != len(a:000)
    let arg = a:000[i]
    if arg !~? '<buffer>\|<silent>'
      break
    endif
    let opt .= ' '.arg
    let i += 1
  endwhile

  if i+2 != len(a:000)
    throw "Invalid number of arguments"
  endif
  let lhs = a:000[i]
  let rhs = a:000[i+1]

  exe 'i'.a:nore.'ab'.opt.' '.lhs.' <c-r>=<sid>Expr('.string(lhs).', '.string(rhs).')<cr>'
endfunction

command! -nargs=+ InoreabBSlash call s:DefIab('nore', <f-args>)

And used with a simple:

InoreabBSlash <buffer> locbit foobar

or

InoreabBSlash bit foobar
Luc Hermitte
A: 

You can only use a backslash as a prefix for an abbreviation if it's only got a single character following it, so :iab \b replacementtext will work.

Andrew Aylett
A: 

I suggest using backslash on both sides, vim is happy that way:

inoreabbr \bit\ replacement_text

Note that I am using the "nore" version of abbr, better to be clear if you don't intend a recursive expansion. I have been using the below abbreviations for a long time and they work great:

inoreabbr \time\ <C-R>=strftime("%d-%b-%Y @ %H:%M")<CR>
inoreabbr \date\ <C-R>=strftime("%d-%b-%Y")<CR>
haridsv