Automatic insertion of a colon after 'def', 'if' etc

Question:

I recently switched to Vim at the request of a friend after Sublime Text 2 decided it didn’t believe a module was installed even though it was…I digress.

I’ve managed to set up some stuff to make editing Python (currently me only language) easier. However, there’s one feature I’m missing from Sublime. It would automatically add a colon to the end of lines which require them (the beginning of function definitions, if statements etc.). This prevented countless annoying errors and I miss it 😛

I was wondering whether there was some sort of command I could put in .vimrc to do this.

An example:
If were to type def, I would like vim to automatically insert a colon to make it def : and place the cursor before the colon ready for me to type my function name.

Cheers and apologies if I’m being stupid in any way.

Asked By: Whonut

||

Answers:

Take a look at the old snipmate, the new snipmate and ultisnips. These plugins provide roughly similar “snippet-expansion” mechanisms modeled after TextMate’s system.

Answered By: romainl

This snippet doesn’t do exactly what you are asking, but it may still be useful to you.

Basically, it puts a semicolon at the end of a line (if the line starts with predefined words, and the colon is not there yet) when you press Enter.

inoremap <cr> <c-r>=ColonCheck()<cr><cr>

fun! ColonCheck()
  if getline(".") =~ '^s*(if|else|elif|while|for|try|except|finally|class|def)>.*[^:]s*$'
    return ":"
  else
    return ""
  endif
endfun
Answered By: Paolo Moretti

This is a rather hacky answer, but you can do a simple mapping like:

inoremap def def :<Esc>i

which would do exactly what you want. That is, when you type ‘def’, it interprets that as ‘def :’, then escapes back to normal mode (here you could move about a bit), then back to insert.

This works as well:

inoremap def def :<Left>

The problem, of course is that it will substitute defs whenever they appear, which is not ideal.

Answered By: CG Morton

Rather than use imaps like @CG Mortion’s answer suggests, I would strongly advise you to use iabbrs for these sorts of small fixes instead.

With an imap you would never be able to type “define” in insert mode unless you paused between pressing ‘d’, ‘e’, or ‘f’, or did one of a number of other hacky things to prevent the mapping from happening. With iabbr the abbreviation is only expanded once a non-keyword character is pressed. iabbr def def:<left> works exactly as you’d expect and it doesn’t have the drawbacks of imaps.


As mentioned in other answers, I would also suggest you move on to a snippet engine once you decide that you want something a little more complex. They are very powerful and can save you loads of time.

Answered By: Randy Morris

Simlar problem: https://stackoverflow.com/a/6950427/875064

augroup PythonProgramming
   au BufNewFile,BufRead,BufEnter   *.py   iabbr def def:<left>
augroup END
Answered By: John Kaul

I use LunarVim and add to the config this line:

lvim.keys.insert_mode[":<Enter>"] = "<Esc>$a:<Enter>"
Answered By: Sergey Nazarov
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.