Introduction to Vim abbreviations
Intro
One of the less known Vim features is “abbreviations”. It’s something similar to mapping, but it has a different purpose.
Abbreviations are a very flexible and really powerful tool.
For simplicity, this post will cover only the Insert mode abbreviations. This is Part 1 of the post. Part 2 will be published soon.
Basic use of abbreviations
The command
The command for Insert mode abbreviations looks like this:
:iabbrev [<expr>] [<buffer>] {abbreviation} {expansion}
<expr>
- stands for Vimscript expression to create the expansion.<buffer>
- means that it only applies to the current buffer.{abbreviation}
- is the thing you type, or your “trigger”{expansion}
- is your final outcome
Anything that’s inside a [] is optional.
Correcting typos
Let’s start with the simple commands first.
Run this command in your Vim: :iabbrev teh the
. Now enter the Insert mode and type teh end
.
As soon as you hit Space after typing the teh
, Vim will replace it with the
.
You probably have a few or more words which you misspell quite often. This is a good way to solve that problem.
Expanding commonly used phrases
Of course, you can store all of your abbreviations in your .vimrc
file. For example:
iabbrev @@ hi@jovica.org
iabbrev ccc Copyright 2020 Jovica Ilic, all rights reserved.
You’re coding in C? How about:
iabbrev #i #include
iabbrev #d #define
Now, let’s create one abbreviation with a Vimscript expression. We can use strftime()
function.
If you run this command in Vim: :put =strftime('%c')
, you’ll insert the current date and time in your current buffer.
So, we can do something like this with an abbreviation:
iabbrev <expr> ddd strftime('%c')
Save your .vimrc
, open Vim and try them out. Cool, ha? :)
Basic text expanding and correcting spelling mistakes are just the tip of the iceberg. You can use abbreviations to generate entire code snippets.
Advanced use of abbreviations
Let’s create an abbreviation for generating a C style comment:
iabbrev cc /*<CR><CR>/<Up>
Basically, after you type cc
in Insert mode and hit Space, a code snippet like this is generated:
/*
*
*/
In the expression above, we basically told Vim to type /*
then hit Enter twice(<CR>
), type /
and hit the ↑ key.
If you have to write Java code for a living, you could add something like this to your .vimrc
:
iabbrev psvm public static void main(String[] args){<CR>}<CR><Up><CR><Up>
So every time you type psvm
and hit Space, you get a snippet like:
public static void main(String[] args){
}
File-type specific abbreviations
What if you want to use the same abbreviation for multiple programming languages? This is possible, as you can use abbreviations in auto commands. This way, you can create file-type specific abbreviations.
Let’s say we want to make one abbreviation for printing a string in Python and Java.
"python
autocmd Filetype python :iabbrev ppp print("");<left><left><left>
"java
autocmd FileType java :iabbrev ppp System.out.println("");<left><left><left>
With these lines in your .vimrc
, you can now hit ppp
and Space, and depending on the file type, you’ll insert an appropriate snippet for printing a string!
Let’s have a look at another, more complex example:
autocmd FileType c iabbrev start #include <stdio.h>
\<CR>
\#include <stdlib.h>
\<CR>
\#include <stdbool.h>
\<CR>
\<CR>
\int main() {
\<CR>
\ printf("hello\n");
\<CR>
\ return 0;
\<CR>
\}
So if you open a .c
file, type start
and hit Space, you’ll get the following snippet:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main() {
printf("hello\n");
return 0;
}
This is pretty cool. But all these “Enters” and other keys we need to simulate make these expressions a bit overwhelming. There’s a better way!
Vim commands in abbreviations
Let’s get back to the previous abbreviation we defined for Java:
iabbrev psvm public static void main(String[] args){<CR>}<CR><Up><CR><Up>
We can achieve the same result with the following snippet:
iabbrev psvm public static void main(String[] args){<CR>}<esc>O
What happens here? Let’s see:
psvm
- our “trigger” expressionpublic static void main(String[] args){
- first part of the string to insert<CR>
- hitting Enter once}
- second part of the string to insert<esc>
- hitting Esc once and entering the Normal modeO
- Normal mode command, which puts you in Insert mode, one line above your current line
Instead of simulating every single keystroke, we can “hit” Esc to go to Normal mode. From there, we can run any command we want :)
How about creating a for loop, and placing our cursor in Insert mode, exactly where the cursor should be?
Here’s a simple C-style loop sample:
for (i=1; i<=NUM; i++) {
}
We could create an abbreviation like this:
iabbrev forl for (i=1; i<=NUM; i++) {<CR><CR>}<Esc>?NUM<CR>cw
What happens here:
- At first, we insert the first part of the string
- Then we hit Enter twice, and insert the second part of the string (
}
) - After that, we hit Esc
- Then we perform a search backwards for string
NUM
, by “hitting”?NUM
and Enter - Lastly, we run the
cw
command which stands for “change word”. This way we delete the stringNUM
and stay in the Insert mode, ready to type a desired value.
There’s more
There’s much more to be said about abbreviations.
Here are just a few interesting bits:
- Just like mappings, abbreviations can be local to a buffer.
- Abbreviations are never recursive.
- Abbreviations can be mapped.
- To avoid the abbreviation in Insert mode, you can hit Ctrl-v before the character that would trigger the abbreviation.
I’ll cover things like these in the upcoming, Part 2, of this post.
Also, abbreviations are something I’ll definitely cover in the new edition of Mastering Vim Quickly: From WTF to OMG in no time.
You're welcome to join my private email list or follow me on Twitter.