Vim Tips for the Intermediate Vim User
After a decade of honing my skills as a mini-golfer, I’ve recently progressed onto playing a new version of golf: VimGolf. I’ve been using Vim for a few years now, and noticed that my Vim skillset had plateaued. The premise of VimGolf is simple: challenges consist of a start file and an end file. The goal is to get from the start file to the end file, using Vim, in as few keystrokes as possible. I’ve been playing VimGolf as a way to acquire new skills.
I’ve learned all kinds of new keystrokes and Vim tips through playing. Predictably, some of them are very niche and forgettable. But, I’ve found others which I didn’t know and now incorporate daily into my Vim usage. I’d imagine reading this, some will be familiar, and some new. This is not meant to be an introduction to Vim. Rather if (like me) you’ve been using Vim for a little bit but haven’t recently looked up Vim commands, I’m hoping some of these will be helpful.
My recommendation in reading through this post is to have a file open in Vim, and try out these commands as you read them. I hope at least a few are helpful for your workflow and make their way into your regular Vim usage!
Insertion
Ctrl-n
in insertion mode inserts based on context. It will prompt a word based on contents of the file. Keep hittingCtrl-n
to get the contextually next wordO
moves into insertion mode in a new line above the cursorci<char>
to delete within the<char>
and put you in insertion mode. For example,ci(
deletes everything within the(...)
and puts you in insertion mode. Also helpful,ci”
andci{
S
deletes the current line and puts you in insertion mode.
repeats the previous action (specifically helpful for insertion)Ctrl-o
in insertion mode escapes for one command in normal mode. This is very helpful for movement while insertingI
inserts at the beginning of the line
Movement
^
moves the cursor to the first non-whitespace character on the line+
moves to the beginning of the first word (non-whitespace character) on next lineCtrl-o
(backwards) andCtrl-i
(forwards) together jump the cursor around to where it was previously in any files. Keep usingCtrl-o
to go backwards, andCtrl-i
to go forwards. (:help jumplist
for more info here)B
(backwards) andE
(forwards) move the cursor using only whitespace as delimitersF<char>
(backwards) andf<char>
(forwards) find a character or word on the current line
Copy Paste
Y
highlights the line and copies it (I had been usingVy
for this)"+y
copies highlighted words to the clipboard so you can paste the value outside of Vim"+Y
copies the line the cursor is on to the clipboard so you can paste the value outside of VimCtrl-y
in insertion mode pastes the contents of the line directly above
Tip: If you highlight a word (or lines) and then replace it, the highlighted word moves into the register, and will be the next word you paste
Indenting Text
<<
(left) and>>
(right) shifts the current line<iB
(left) and>iB
(right) shifts the code in the current block=i{
fixes indentation of block excluding the braces=a{
fixes indentation of block including the bracesgg=G
to indent the full file
Tip: Use gg=G
and then Ctrl-o
to get the cursor back to where it was
Refocusing the page
zt
moves the line the cursor is on to the top of the pagezz
moves the line the cursor is on to the middle of the pagezb
moves the line the cursor is on to the bottom of the page
Specific Characters
~
switches the case of a characterCtrl-a
increments numbersCtrl-x
decrements numbers
Tip: The cursor doesn’t need to be on the number itself, it’ll increment or decrement any number after the cursor on the same line
Miscellaneous
ZZ
and:x
both only save the file if it has been modified, and then quit:!<command>
to run a bash command from Vim (for example:!ls
)gql
will split one line to the currently set width. To set the width of the split lines to be different from your current setting, you can use:set textwidth=<n>
. This can be helpful for 80 character linting, for exampledat
deletes everything inside an HTML tag including the tagdit
deletes everything inside an HTML tag excluding the tag