1

Let's get directly to it.

I was working with some python code and realized I had written a bunch of elif blocks as else if after working too much in Javascript.

My natural thought was "cool, I can make an abbreviation to fix those for me so I don't have to think much about it". Then I realized {lhs} of abbreviations can't contain spaces.

I could of course abbrev elif to else if and :iunab it for python, but I was wondering if there's a way to fix it if I ever do happen to write an else if in python. I dug through the :h ab files.

:inoreabbreviate <expr> if f where f steps back one word and checks if it's an else-if block could work, but I'm wondering if there's any other way that I just don't know of?

3

This might not be the perfect answer, but I kind of solved the problem by creating the following augroup:

augroup filetype_python
autocmd!
autocmd BufRead,BufWrite *.py :%s/else if/elif/g
augroup END

Basically, it will substitute "else if" with "elif" (:%s/else if/elif/g) whenever a *.py file is:

  • read (BufRead, e.g :split testfile.py) or
  • written (BufWrite, e.g :wq to close save and close the current file)

So, it means that if you suddenly find out that you have been writing "else if" you could either write the file with :w, or just let it be; whenever you save and close it will be substituted.

Again, this might not be the perfect solution for you. It does seems useful for me (I have <space> remapped to :w, in order to execute the substitution I just hit space).

Anyway thanks for the exercise! (:

Maybe, you could also check Tim Pope's Vim-abolish, a plugin that:

easily search for, substitute, and abbreviate multiple variants of a word

  • 1
    Good idea! Albeit BufNewFile will never find any text according to spec - it only fires when you open a brand-new file. Those are usually empty. – Wolfie Jan 8 '17 at 0:11
  • Ahaha, thanks for pointing that out. Question edited. Should another event be added? – lsrdg Jan 8 '17 at 14:37
  • Usually it's enough to pretty it up whenever you open or save the file. Technically saving it is enough if you never use other editors, but that's a bit outside scope. – Wolfie Jan 8 '17 at 14:43
2

You'll have to analyse the context of the text you've typed to know what you want to insert. For instance, you could have a if abbreviation that detects there is a else just before.

BTW: don't remove abbreviations/mappings for a specific filetype context. Instead define your abbreviations only in a given context with the <buffer> specification. And define your abbreviation in filetype plugins (you could play with autocommands, but this doesn't scale).

What you're looking for is something like this:

inoreab <buffer> <expr> if repeat("\<bs>", strlen(matchstr(getline('.'), 'else\zs\s*if'))).'if'

Note that it doesn't take the current context into account (comments, strings), nor characters other than a space to end the abbreviation. Beside, we can do more like automatically adding semi-colons and jumping to the next line as I do in lh-brackets.

  • Interesting points, @LucHemitter. But could you provide an example of how autocommand would't scale? Thanks in advance. (: – lsrdg Jan 7 '17 at 22:24
  • 1
    The more autocommands you have, the more cluttered your .vimrc file becomes. Beside, sharing your configuration would only become possible through copy-pasting. It works as long as you don't have many ft-specific definitions. For instance, for C alone, I have something like 1000 lines of code in my ftplugins -- many should be moved to autoload plugins eventually. I can't imagine doing the same thing only with autocommands. – Luc Hermitte Jan 7 '17 at 22:42
  • The idea of defining it globally is that I could then pick up new languages without having to generate a new ftplugin just to put the elif->else if abbrev in there – Wolfie Jan 8 '17 at 0:09
  • We usually know the few languages we are working with. Beside with each we'll want different snippets (code blocks, semantics indenting, ...). PS: I've edited my answer to add a solution to your problem. – Luc Hermitte Jan 8 '17 at 0:55
  • I'm looking it over and this makes a lot of sense, other than repeat not being an editor command; it just multiplies strings for me. Also tested with -u none. – Wolfie Jan 8 '17 at 1:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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