Nifty Vim Tricks

Two weeks ago I explained to you why I use vim. Last week, I taught you how to configure it. This week I want to talk about something different: power user stuff.

Let’s talk useful vim tricks. Everyone amasses an arsenal of these over the years. Some are really, really useful – other ones merely convenient. I wanted to share some of mine, in hopes that you will show me yours. Below I’m concentrating on basic, core vim functionality. I could extend this list quite a bit by including plugins, but not everyone uses them. That can be a topic for whole other post.

Stroke those keys like a Pro!

First let’s look at some interesting key combos. I will give them to you along with easy to remember mnemonics. Remember, it really pays to think of vim commands as words that can be strung together into sentences.

Keystrokes Mnemonic Description
d a < Delete Around Angle Bracket Deletes the first encountered html tag enclosed in <>
c i " Change Inside Quotes Deletes content inside the first encountered quotation marks(also works with (, [, {, ‘, < and etc..)
c i t Change Inside Tag Deletes the contents of the current HTML tag (but not the tag itself) and puts you in insert mode. You can use this to delete the contents of a div, regardless on how many other HTML tags are inside of it.
c a t Change Inside Tag Like the above, but deletes the opening/closing tags as well as the contents.
v i t Visual Inside Tag Visually selects the contents of the current html block (eg. current div). You can add y at the end to yank it.
y a t Yank Around Tag Yank the entire HTML block (eg an entire div).
Y p V r = Yank line, Paste below, Select line, Replace with ‘=’ Yank the current line, paste it below, replace all characters with ‘=’. Or in other words make a Markdown heading. You can replace ‘=’ with any other character.

There are dozens more like that. These are just useful examples, and you can easily mix and match various commands and motions to make new actions based on the above. Foe example: d a t, y a < and etc…

Two very useful motions are g g (which takes you to the begging of the file) and G which skips to the end. Whatever command you stick between these two will affect the entire file. Here are some examples:

Keystrokes Description
g g = G Auto-indent the entire file. Nice and easy way of cleaning up the indentation.
g g y G Yank the entire file.
g g v G Visually select the entire file.
g v Re-use last visual selection.

One of the common problems when working with vim is that the yank commands do not actually use the system clipboard. When vim was created, clipboard was not a thing yet, so Billy Joy built vim around the idea of registers. When you yank, vim puts the contents into named registers. You can specify which one you want when you yank. The modern versions of vim use the + register to mean system clipboard. So you can easily copy and paste between applications, or different instances of vim like this:

Keystrokes Description
" + y y Yank current line to system clipboard.
" + p Paste from system clipboard.
: % y + Yank the entire file into system clipboard.

In the last command I used the % key. Whenever you use it in command mode, it essentially means “this entire file”. So the above command is basically a slightly more succinct equivalent of g g " + y. Note that this key becomes even more useful when combined with the ! key which escapes to the shell.

Keystrokes Description
: ! % If the current file is a shell script, or an interpreted program code this will escape to the shell and run it with the default interpreter. The output will be shown in a separate buffer.
: % ! % Like the above, but overwrites the current buffer with the result.

Note that you can use the ! command to run any external application as long as it is in your system path:

Keystrokes Description
: !   cmd   % Runs the external command cmd and passes in the current file as input. Output is shown in a temporary buffer.
: r !   cmd   % Runs the external command cmd and passes in the current file as input. Output is pasted below the current line in the current buffer.
: . !   cmd   % Runs the external command cmd and passes in the current file as input. Output replaces current line in the current buffer.
: % !   cmd   % Runs the external command cmd and passes in the current file as input. Output overwrites the current buffer.
: . !   figlet Foo Concrete example – makes a pretty heading spelling out “Foo” by running the unix app called figlet and replacing the current line with it’s output.
: % !   xxd Another concrete example – shows you the hex dump of the current file by filtering it through the xxd command.

Here are some other nifty tricks that deal with opening, saving and undoing changes in your files:

Keystrokes Description
: e ! Drop all unsaved changes. In essence it forces vim to re-open the file from disk, discarding current buffer.
: w   ++ff=unix Save the file with unix style line endings.
: w   ++ff=mac Save the file with mac style line endings.
: w   ++ff=dos Save the file with dos style line endings.
z z Scroll the screen so that the current line is vertically centered.
Z Z Save and quit. Equivalent of : w q.
Z Q Quit without saving. Equivalent of : q !.
: earlier 15m Restore the file to state from 15 minutes ago.
: later 15m Fast forward 15 minutes into the future. Only works if you used undo or earlier commands.
[ s z = Jump to last misspelled word and enter the replacement mode

Mappings for Mupets

Let’s talk about some mappings. Here are some of the things I always remap in my .vimrc and you should too:

I mentioned this mapping before, but I think it bears repeating. It lets’ you press ; to issue commands in normal mode. It overrides repetition of t and f commands but how often do you use that feature versus vim command mode? I personally think that the key strokes you save by not having to hold shift are worth it.

nnoremap ; :

This mapping allows you to use j and k to move by screen lines, not by real lines – great for when you have soft word wrap enabled.

nnoremap j gj
nnoremap k gk

" also in visual mode
vnoremap j gj
vnoremap k gk

This will run ctags on current directory recursively when you press F6. I mentioned ctags in my previous vim post, so you should be familiar with it already.

nnoremap  :!ctags -R

Another trick I already mentioned in the other post, included here for the sake of completeness: pressing \ space clears the search highlights

nmap   :nohlsearch

Use \ Enter to break a line at the cursor:

nmap   i

This is a new one – sometimes you may want to insert blank lines in your text without entering insert mode. Now you can do it with \ o and \ O.

nmap  o o
nmap  O O

Use jj to quickly escape to normal mode while typing:

inoremap jj 

Toggle paste mode to paste properly indented text. It gives you a visual cue in the status line:

nnoremap  :set invpaste paste?
set pastetoggle=
set showmode

If you happen to work with PHP a lot (I do obscene amounts of PHP at work) this is kinda useful:

" run current PHP file through php 
:autocmd FileType php noremap p :w!:!php %
" run current PHP file through php linter (syntax check) check
:autocmd FileType php noremap l :!php -l %

This one is quite useful: toggle between absolute line numbers and relative line numbers. The relative numbering is really useful. For example, lets say you want to jump to a specific line in the code – with relative numbers you can just glance at the line number and know you need to use 1 0 j to get there. With absolute line numbers you would have to either guess, do some quick arithmetic in your head or just start to repeatedly hit j till you get there. That said, absolute line numbers are useful for debugging. So this trick gives you best of both worlds:

function! g:ToggleNuMode()
	if(&rnu == 1)
		set nu
		set rnu

nnoremap  :call g:ToggleNuMode()

Now you can hit F5 to toggle between the two modes.

Here is something very useful when you don’t want to listen to my advice and remap ; to :. Very often you will be typing fast, and you will hold Shift a fraction of a second too long typing in : W instead of : w and fail to save. Here is a solution:

command W w
command WQ wq
command Wq wq
command Q q

You simply remap common typos to the correct, intended commands. Now even if you fuck up, you will probably trigger the command you wanted.

Finally, here is a trick that makes copying and pasting between windows and applications a little less of a pain in the ass:

noremap y "+y
noremap Y "+Y
noremap p "+p

Now when you want to copy current line to system clipboard you simply hit \ y y or \ Y. It saves you two extra keystrokes either way.

Other Stuff

Final really quick trick that most people don’t know about. Sometimes you want to open your vim in a “clean” state. By that I mean no plugins, no custom key bindings, no advanced settings. Factory default vim if you will. Here is how you do it:

vim -u NONE

How much is too much?

A lot of people like to brag about their minimalistic .vimrc and how they are supposedly using vim “the right way”. Those people are what we call “willfully inefficient”. The entire point of using an editor like Vim or Emacs is their customizability. If you are not using it, then you are likely spinning wheels and using extra keystrokes which you could have bound to a single key. Hack your vim with reckless abandon, I say. Put your .vim folder under source control and you will never have to go without it as long as you have internet access.

This is about it for me. I hope this was somewhat useful and or enlightening for you guys. What are your favorite tips and tricks? Please post them in the comments.

This entry was posted in sysadmin notes and tagged . Bookmark the permalink.

6 Responses to Nifty Vim Tricks

  1. copperfish Mozilla Firefox Windows Terminalist says:

    Nice Luke. I’m no developer so I seldom need the syntax related stuff, but Vim is still my text editor of choice on all platforms. Thanks to this I might even try some of the remapping stuff.

    Reply  |  Quote
  2. Thanks for the excellent reading. I haven’t read anything so useful to my vim prowess since Steve Losh’s article on the same subject.

    Incidentally did you mean to put

    nnoremap p "+p

    the pasting didn’t work until I added the paste keystroke. If it was errata, please feel free to just delete/edit the comment.

    Reply  |  Quote
  3. Luke Maciak UNITED STATES Google Chrome Linux Terminalist says:

    @ copperfish:

    Yep, try it! It’s fun. Basically the more you customize your Vim, the better you get at it… And at customizing it. It is a performance optimization feedback loop. :)

    @ Stephen McQuay:

    Thank you sir! Steve Losh is way better at vimming than me. :)

    And yes, “+p was exactly what I meant. Good catch.

    Reply  |  Quote
  4. rev UNITED STATES Google Chrome Linux says:

    i too have embraced vim. i prefer vim on the console, not that abomination gvim, mind you. one of the plugins i really love is NERDTree, and my favorite color scheme by *far* is solarized. here is a remap that i find really handy:

    ” buffer navigation (insert mode)
    imap  _
    imap  _
    imap  :vertical res
    imap  :vertical res 50

    ” buffer navigation (command mode)
    map  _
    map  _
    map  :vertical res
    map  :vertical res 50

    it lets you switch buffers by hitting ctrl and arrow keys. when going up or down, it will minimize all but the current buffer. when going left it will open the left buffer 50 columns – this works well with NERDTree, then when going right it minimizes the left buffer. the result is that you always have as full a screen view of your current buffer as possible.

    i’ll be adding a few of your tips to my vimrc, for sure.

    Reply  |  Quote
  5. Luke Maciak UNITED STATES Google Chrome Linux Terminalist says:

    @ rev:

    Nice! I’ve been using MiniBufExpl that essentially emulates a tab-bar but it has been a bit problematic as it conflicts with some plugins such as Fugitive.

    Reply  |  Quote
  6. Scott Hansen UNITED STATES Mozilla Firefox Linux says:

    Thanks for the tips…there’s ALWAYS something new to learn in Vim! Now just keeping all in my head until I need it…


    Reply  |  Quote

Leave a Reply

Your email address will not be published. Required fields are marked *