Vim: Insert Mode is Like the Passing Lane

Insert mode is not the mode for editing text.

It is a mode for editing text, because both normal and insert modes are modes for editing text.

Insert mode, however, is the mode for inserting new/raw text directly from the keyboard (as opposed to, e.g., from a register or a file).

Thus, you will only be in insert mode when you are actually typing in inserting (raw) text directly. For almost every other editing operation, normal mode is where you will be. Once you grok this you will realize that, the bulk of most editing sessions is not insert mode, and you actually spend most of your time in normal mode, just dipping into insert mode to add text and then dipping out again.

Insert mode is thus like the passing lane on the highway. Just like you are should only be in the passing lane when you are actually passing other vehicles, you should only be in insert mode when you are inserting text.

Some snapshots from my own learning experiences here and here.

From Acolyte to Adept: The Next Step After NOP-ing Arrow Keys in Vim

René Descartes's illustration of dualism. Inputs are passed on by the sensory organs to the epiphysis in the brain and from there to the immaterial spirit. Public domain image. Sourced from: Wikimedia Commons

We all know about no-op’ing arrow keys in Vim to get us to break the habit of relying on them for inefficient movement.
But, as this post points out, it is not the location of the arrow keys that makes them inefficient, but the modality of the movement: single steps in insert mode is a horrible way to move around when normal mode provides so much better functionality.

But here is the thing: while normal mode provides for much better and more efficient ways to move around than insert mode, it also provides for ways to move that are just as inefficient as arrow keys. In fact, there is nothing that makes, e.g. “j” significantly better than “<DOWN>“, and so if we replace <DOWN><DOWN><DOWN><DOWN> with jjjj, we are just slapping on some fresh paint on a rusty bike and calling it “faster”. We have not even replaced one bad habit with another, we are indulging in the same bad habit, albeit with a different “it”. A bad habit that is not only inefficient, but, perhaps a much worse sin in the Vim-world, inelegant.

This customization will help break you of that habit by forcing you to enter a count for each of the basic moves (“h“, “j“, “k“, “l“, “gj“, “gk“).
This itself will make you more efficient for any move of three repeats or more: “3j” is more efficient than the uncounted “jjj” equivalent.
But, in addition, it will also have the side-effect of making you come up with more efficient moves yourself: as your eyes focus on the point where you want to go, instead of counting off the lines (or reading off the line count if you have “:set relativenumber“), you might find it more natural to, e.g. “/<pattern>” .

In fact, you might find that in many cases, you do not even need to actually move as such. For example, instead of moving to a line 8 lines down and deleting it, “8jdd“, you could just “:+8d“. Or instead of moving to a line four lines up, yanking it, moving back to where you were and pasting it, “4kyy4jp“, you can just “:-4y” and “p“. Once you get good enough at it, it will seem like magic the way you can manipulate lines far from your current position without moving! And what you will find is that, beyond the increased efficiency in number of keystrokes, there is an increase in mental efficiency: the microseconds of visually re-orienting yourself after each move is no longer a cost that you have to pay over and over and over again.

Naturally, you are going to find things less efficient and less elegant at first.
But that is just the pain that of stressing out mental muscles that have not been exercised enough, like that first leg day after the holidays (or maybe even the first leg day ever after signing up at the gym 4 years ago).

Eventually, your efficiency will increase.

But more than efficiency, the elegance of your moves will eventually increase as well. Dramatically. As far as editing text goes, at any rate.

So, stick the following into your “~/.vimrc“, and be prepared for some pain and frustration and swearing and clumsiness as you retrain your muscle memory and your mind, before gaining a new level of enlightened “acting-without-doing”.

NOTE: One of the greatest impediments to me naturally working with counted-movements was the fact that counting the number of lines to go in each direction is disruptive: it completely breaks my “flow”, jarringly derailing my train of thought. See below for the solution to this, the implementation of which I consider a mandatory pre-requisite to working this way.


Displaying Relative Numbers vs. Absolute Numbers

I find the need to count line offsets before every move or operation as conducive to my “flow” as having an air horn stuffed down my throat while frozen mayonnaise is blasted into my ears. This was why I resisted count-based ergonomics in Vim for so long.
Vim has a feature, “`:set relativenumber`” that shows relative numbers, and this makes things tremendously better, in that you can simply read of the line offset to your navigation target …. except that you must choose to show either relative numbers or absolute numbers. The fact is, the only time relative numbers are useful is for motions/operations in the current window or split, but when you have other splits open, relative numbers are worse than useless, as you need to have absolute numbers to make sense of what part of the buffer you are seeing in the non-focal splits. Showing both absolute and relative numbers at the same time would be ideal, but Vim does not support that natively (there is a plugin to help with that, but it exploits the “sign” feature, which can be a problem if you use signs to display something else, like marks, as I do). So the dilemma is that in most cases you want absolute numbers, but count-based motions/operations in the current window are annoying and mentally-disruptive if you do not have relative numbers showing to avoid you breaking your train of thought to count the lines to the target.

Luckily, a Vim plugin provides the answer: vim-numbers. This plugin automatically sets relative numbers on for the split/window in focus, and restores the previous numbering (absolute in my case) when focus moves to another split or window. It was this that made my move to strict count-required based motion possible.

EDIT: It was pointed out by /u/VanLaser that the following in your “~/.vimrc” is sufficient to achieve the relative-numbering-in-focal-window-and-absolute-everywhere-else dynamics without the need for a plugin:

set number
if has('autocmd')
augroup vimrc_linenumbering
    autocmd WinLeave *
                \ if &number |
                \   set norelativenumber |
                \ endif
    autocmd BufWinEnter *
                \ if &number |
                \   set relativenumber |
                \ endif
    autocmd VimEnter *
                \ if &number |
                \   set relativenumber |
                \ endif
augroup END

Taking it to a 11: Dramatically Speeding Up Keyboard/Typing Responsiveness in OSX

If you use a Mac/OSX, then enter the following commands in your shell and reboot:

    $ defaults write -g KeyRepeat -int 0
    $ defaults write -g InitialKeyRepeat -int 15

If you live in a text editor or the shell, or otherwise spend most of your typing hammering away at the keyboard like I do,
then this makes an absolutely wonderful difference in the responsiveness of any typing activity. It will make your previous typing feel like you were pecking away in slow motion at the bottom of a pit of cold tar!

Yes, I know you can set the keyboard repeat rate in `System Preferences`.

I, too, did that a long time ago.

But this trick takes the speed to a 11

Dynamic On-Demand LaTeX Compilation

Most of the existing approaches to integrating LaTeX compilation into a LaTeX writing workflow centered around a text editor (as opposed to a fancy-schmancy IDE) are horrendously bloated creatures, aggressively and voraciously hijacking so many key-mappings and normal functionality that it makes your Vim feel like it is diseased and is experiencing a pathological personality disorder of some kind. Yes, LaTeX-Suite, I am looking at mainly at you.

I did not want a platoon of obnoxiously cheery elves to insert two hundred environments into the document while a marching band parades around the room when I hit the `$` key. I just wanted a way to quickly and easily compile the current document, and optionally open it for viewing. Thus, I wrote a little plugin to do exactly that.

It has worked fine enough all this time. But today, thanks to a comment in a reddit discussion, I discovered something magical: latexmk

Not all that great if you use TexShop or another LaTeX IDE for latexing, but if you use a Plain Old Text Editor, then the following may change your life:

    $ latexmk -pdf -pvc nature-publication-2014.tex

Two neat things going on here.

First, “latexmk”. This is the smart-single-click-do-all latex compiler (and is almost always available with all TeX distributions). Takes care of all those multiple compilation passes with BibTeX and such. So, no matter how complex your document, a single command Gets It Done, from compilation to viewing:

    $ latexmk -pdf nature-publication-2014.tex

Then there are the ‘-pvc‘ flags shown above. This is where things get sexy. This invokes “`latexmk`” on the document which then compiles it as per usual. But then, instead of exiting, it waits there monitoring the file for any changes. Upon detecting changes (like `make`), it recompiles and refreshes the document in the viewer!

So, if you have a shell with this command running in the background (either in a separate window or through, e.g., tmux or screen), you can merrily edit away in your POTE, and have constant refreshes as you save.

Setting up the Text Editor in My Computing Ecosystem


Image from WikiMedia Commons

Basic Setup of Shell to Support My Text Editor Preferences

By “text editor”, I mean Vim, of course. There are pseudo-operating systems that include rudimentary text-editing capabilities (e.g. Emacs), and integrated development environments that allow for editing of text, but there really is only one text editor that deserves the title of “text editor“: Vim, that magical mind-reading mustang that carries out textual mogrifications with surgical precision and zen-like elegance.

However, while Vim is the only true text editor, there is more than one flavor of Vim. There is the original, universal one, i.e., console Vim. And then there are various lines of graphical Vim’s specific to various operating systems. On my primary development box, a Mac, I prefer MacVim over straight-up console Vim, for many, many, many reasons, even though I practically live in the shell otherwise. For working with files on remote machines, I prefer using SSH to login and editing with console Vim, even though I can also edit these files through my own local MacVim instance. My computing ecosystem is shared between all my accounts, and this includes a collection of scripts as well as resources for various applications (e.g., not only my entire ‘~/.vimrc‘, but the entire accompanying ‘~/.vim' directory).

I have the following line in my ‘~/.bashrc‘:

    export EDITOR=' -f'
    export EDITOR=''
alias e=''

This invokes the following script, ‘‘ which is in the ‘$PATH‘ of all my accounts:

#! /bin/bash

if [[ -f /Applications/ ]]
    # bypass mvim for speed
    VIMPATH='/Applications/ -g'
elif [[ -f /usr/local/bin/mvim ]]
    # fall back to mvim
    # fall back to original vim


Easy Opening of Multiple Project Files

I have FuzzySnake installed on my system. My totally unbiased opinion as the author of FuzzySnake is that it is absolutely awesome, and that you should all be using it as well. In addition to the default behavior of opening the selected targets in my ‘$EDITOR‘ (which is, as shown above, ‘‘), I also use the nifty ‘--L/--list-and-exit‘ facility of FuzzySnake to discover files of particular types and pass them to Vim. I could define a set of aliases like ‘alias epy="e $(fz -L --python)“‘, but this approach makes it impossible to pass options to the editor. Instead, I have a set of convenience functions like:

# open all C/C++ and header files
function ecc() {
    e $(fz -L --cpp --exclude-file-patterns="config.h" "$@")
# open all C/C++ and header files, as well as autotools files
function ecca() {
    e $(fz -L --cpp --autotools --exclude-file-patterns="config.h" "$@")
function ecm() {
    e $(fz --cmake "$@")
function eccm() {
    e $(fz -L --cpp --cmake --exclude-file-patterns="config.h" "$@")
# open all Python files
function epy() {
    e $(fz -L --py "$@")

Of course, for on-the-fly use-cases, I usually just do something like:

$ e $(fz -L --rst)

Allowing for Opening of Files in an Existing MacVim Instance

In MacVim’s Preferences, I make sure that ‘Open files from applications‘ is set to ‘in the current window‘. Then I define the following alias in my ‘~/.bashrc‘:

    # alias ee="open \"mvim://open?url=file://$1\""
    alias ee="open -a MacVim"

With this, while typing

$ e foo bar

will open a new Vim session (either MacVim or console vim, depending on whether I am editing a file on my local machine or remotely through SSH), with files ‘foo’ and ‘bar’ loaded into buffers, typing

$ ee foo bar

will open ‘foo’ and ‘bar’ in an existing MacVim session.

Opening Remote Files in My Local (Mac)Vim Session, with Auto-Completion of Paths/Filenames

Sometimes I do prefer to edit remote files in my desktop MacVim (one might wonder why I do not always prefer this …). Lack of path completion when invoking the command has alway been an irritation for me, until I defined the following function:

function edit-remote() {
    if [[ -z $1 ]]
        echo "usage: remote-edit [[user@]host1:]file1 ... [[user@]host2:]file2"
    declare -a targs=()
    for iarg in $@
        targ="scp://$(echo $iarg | sed -e 's@:/@//@' | sed -e 's@:@/@')"
        targs=("${targs[@]}" $targ)
    $EDITOR ${targs[@]}
complete -F _scp -o nospace remote-edit

Smart (`infercase`) Dictionary Completions in Vim While Preserving Your Preferred `ignorecase` Settings

Dictionary completions in Vim can use a ‘infer case’ mode, where, e.g.,
“Probab” will correctly autocomplete to, e.g., “Probability”, even though the
entry in the dictionary might be in a different case. The problem is that this
mode only works if `ignorecase` is on. And sometimes, we want one (`infercase`)
but not the other (`ignorecase`).

The following function, if added to your “`~/.vimrc`”, sets it up so that `ignorecase` is
forced on when dictionary completions are invoked via the `` keys,
and then restored to its original state when exiting.

[gist id=10015995]

A better approach than binding all the exit keys would be an autocommand on leaving the pop-up completion menu, but I could only find a trigger for entering the popupmenu.

Some Vim Movement Tips

  • Within-line character-based movement:
    • `h` and `l` move you left and right one character, respectively.
    • `fc` or `Fc` will take you forward to the next or back to the previous, respectively, occurrence of character “c` on the current line (e.g., `fp` will jump you forward to the next occurrence of “p” on the line, while `Fp` will jump you back to the previous occurrence of “p” on the line).
    • `tc` or `Tc` will take you forward to just before the next or back to just after the previous, respectively, occurrence of character “c` on the current line.
    • `;` or `,` repeats, forward or backward, respectively, the last `f`/`F`/`t`/`T` command.
    • `0` jumps you back to the beginning of the line while `$` jumps you to the end of the line.
    • `^` jumps you to the beginning of the first non-whitespace character on the current line.
    • Typing in a number and then typing `|` takes you to a column of that number on the current line.
  • Word-based movements:
    • `w` jumps you forward to the next “beginning-of-word”, while `b` jumps you back to the previous “beginning-of-word” (`W` and `B` for the corresponding WORD forms).
    • `e` jumps you forward to the next “end-of-word”, while `ge` jumps you back to the previous “end-of-word” (`E` and `gE` for corresponding WORD forms).
  • Line-based movements:
    • `j` and `k` move you down and up one line, respectively.
    • `+` and `-` move you to the first non-whitespace character on the next or previous line, respectively.
    • `G` jumps you to the last line of the buffer.
    • Typing in a number and then typing `G` takes you to line of that number.
    • `gg` jumps you the the first line of the buffer.
    • `+` moves you to the first non-blank character on the previous line (same effect as `k^`), while `-` moves you the the first non-blank character on the next line (same effect as `j^`).
    • `H` jumps you to the top (mnemonic=”home”) line of the current window.
    • `M` jumps you to the middle line of the current window.
    • `L` jumps you to the last line of the current window.
  • Page-based movements:
    • `<C-U>` moves you up half a page, while `<C-D>` moves you down by a half a page.
    • `<C-F>` moves you forward a full page, while `<C-B>` moves you backward a full page.
    • Go to a brace, bracket, parenthesis, quote, etc. Type `%` to jump to the matching brace, bracket, parenthesis, quote. etc.
  • Search-based movements:
    • With `:set incsearch` on, type `/` and starting typing in a search expression. As you type characters of the expression, you will be taken to the first location forward of the cursor position where that matching term appears in the buffer (use `?` to search backwards instead of forwards). Hit `<ENTER>` to start working from this new position, or `<ESC>` to cancel and return to your original location. To find the next matching expression, hit `<ENTER>` and then `N` to iterate through all matches in the buffer. If `:set wrapscan` is on, then the search will wrap around the buffer. If search highlighting is turned on (`:set hlsearch`), all occurrences of the expression will be highlighted.
    • Position the cursor over any word in an open, and (in normal mode, of course), type `*`. This will jump you to the next occurrence of the word under the buffer. If search highlighting is turned on (`:set hlsearch`), all occurrences of the word will be highlighted.
    • Now type `#`. This time, you will be taken back to the previous occurrence of the word under the cursor.
    • Typing `n` or `N` will jump to the next position in the buffer that matches the last-entered search expression (i.e., either through `/`, `?`, `*`, or `#`).
  • History-based movements:
    • “.` or `’.` will take you back to the last position or line, respectively, where you modified the file.
    • “^` or `’^` will take you back to the last position or line, respectively, where you left insert mode.
    • You can use `<C-O>` and `<C-I>` to take you backward and forward through these and other “jump” positions.
  • If you are editing source code, then:
    • `]m` takes you forward to the next “start of a method” (i.e., the beginning of the next method).
    • `[m` takes you back to the previous “start of a method” (i.e., the beginning of the current method if you are in the middle of one, or the beginning of the previous method if you are “in between” methods).
  • Window adjustment:
    • This is not a movement tip per se, but it is relevant in the sense that it changes the spatial relationship of the cursor with respect to the window: `zb`, `zt`, and `zz` scroll the screen to make the current line at the top, bottom, or middle, respectively.

Vim Regular Expression Special Characters: To Escape or Not To Escape

Vim‘s regular expression dialect is distinct from many of the other more popular ones out there today (and actually predates them).
One of the dialect differences that always leaves me fumbling has to do with which special characters need to be escaped.
Vim does have a special “very magic” mode (that is activated by “\v” in the regular expression) that makes thing very clean and simple in this regard: only letters, numbers and underscores are treated as literals without escaping.
But I have never got used to the habit of preceding my expressions with “\v“, though maybe I should.

In the mean time however, I thought I would put up a quick reference that lists all the special regular expression characters in the default “magic” mode Vim dialect, divided into those that do not need to be escaped vs. those that do.

Regular Expression Special Characters Not Requiring Escaping

The following special characters are interpreted as regular expression operators without escaping (escaping will result in them being intepreted as literals):

\ Escape next character (use “\\” for literal backslash).
^ Start-of-line (at start of pattern).
$ End-of-line.
. Matches any character.
* Matches 0 or more occurrences of the previous atom.
~ Matches last given substitute string.
[] Matches any of the characters given within the brackets.
[^] Matches any character not given within the brackets.
& In replacement pattern: insert the whole matched search pattern.

Regular Expression Special Characters Requiring Escaping

The following special characters are interpreted as regular expression operators only when escaped (otherwise they will be interpreted as literals):

\< Matches beginning of a word (left word break/boundary).
\> Matches end of a word (right word break/boundary).
\(...\) Grouping into an atom.
\| Separating alternatives.
\_. Matches any single character or end-of-line.
\+ 1 or more of the previous atom (greedy).
\= 0 or one of the previous atom (greedy).
\? 0 or one of the previous atom (greedy).
\{ Multi-item count match specification (greedy).

\{n,m} n to m occurrences of the preceding atom (as many as possible).
\{n} Exactly n occurrences of the preceding atom.
\{n,} At least n occurrences of the preceding atom (as many as possible).
\{,m} 0 to n occurrences of the preceding atom (as many as possible).
\{} 0 or more occurrences of the preceding atom (as many as possible).
\{- Multi-item count match specification (non-greedy).

\{-n,m} n to m occurrences of the preceding atom (as few as possible).
\{-n} Exactly n occurrences of the preceding atom.
\{-n,} At least n occurrences of the preceding atom (as few as possible).
\{-,m} 0 to n occurrences of the preceding atom (as few as possible).
\{-} 0 or more occurrences of the preceding atom (as few as possible).

The Power and Precision of Vim’s Text Objects: Efficent, Elegant, Awesome.

Vim’s text objects are not only a powerful, flexible and precise way to specify a region of text, but also intuitive and efficient.
They can be used with any command that can be combined with a motion (e.g., “d“, “y“, “v“, “r“), but in this post I will be using the “c” command (“change”) to illustrate them.

Imagine you were on a line looked like this, with the cursor on the letter “r” of the word “dry”:

print “Enter run mode (‘test’, ‘dry’, or ‘full’)”

Then, after typing “c” to start the “change” command, you can type “i” or “a” followed by another character to define a text object to which to apply the “change”.

Using “i” gives you the “inner” text object (i.e., a less-inclusive or non-greedy version that excludes the wrapping characters or delimiters) while “a” gives the full object (i.e., a more-inclusive or greedy version, that includes the wrapping characters or delimiters).

The third and final character of the command sequence gives the criteria by which the text object is defined.

This is typically the initial letter of the name of the object (e.g., “w” for “word”, “s” for “sentence”) or a character that delimits/wraps a region of text (e.g. a parenthesis for text in parentheses, a quote for quoted text, a curly brace for text in curly-braces).

For example:

  • Typing “ci'” will delete the word [dry], not including the quotes, and enter insert mode:


    print “Enter run mode (‘test’, ‘dry’, or ‘full’)”


    print “Enter run mode (‘test’, ‘ ‘, or ‘full’)”
  • Typing “ca'” will delete the word [‘dry’], including the quotes, and enter insert mode:


    print “Enter run mode (‘test’, ‘dry’, or ‘full’)”


    print “Enter run mode (‘test’,  , or ‘full’)”
  • Typing “ci(” or “ci)” will delete everything inside the parentheses, but not the parentheses themselves, and enter insert mode:


    print “Enter run mode (‘test’, ‘dry’, or ‘full’)”


    print “Enter run mode ( )”
  • Typing “ca(” or “ca)” will delete the everything inside the parentheses as well as the parentheses themselves, and then enter insert mode:


    print “Enter run mode (‘test’, ‘dry’, or ‘full’)”


    print “Enter run mode  
  • Typing “ci"” will delete everything inside the double-quotes, but not the double-quotes themselves, and enter insert mode:


    print “Enter run mode (‘test’, ‘dry’, or ‘full’)”


  • Typing “ca"” will delete everything inside the double-quotes, as well as the double-quotes themselves, and enter insert mode:


    print “Enter run mode (‘test’, ‘dry’, or ‘full’)”


<p>The idiom is naturally extended to many types of different delimiting characters in the most intuitive way possible (i.e., simply by specifying the delimiting character or first character of the name of the text object):

    <li>"<code>i{</code>" or "<code>i}</code>" selects curly-brace surrounded text, with the greedier versions being "<code>a{</code>" and "<code>a}</code>", respectively.
    <li>"<code>i[</code>" or "<code>i]</code>" selects square-bracket surrounded text, with the greedier versions being "<code>a[</code>" and "<code>a]</code>" respectively.
    <li>"<code>i'</code>" selects single-quote surrounded text, with the greedier version being "<code>a'</code>".
    <li>"<code>it</code>"  selects the text within the surrounding HTML/XML tag or container, with the greedier version being "<code>at</code>".
    <li>"<code>iw</code>"  selects the surrounding word, with the greedier version being "<code>aw</code>".
    <li>"<code>is</code>"  selects the surrounding sentence, with the greedier version being "<code>as</code>".
    <li>"<code>ip</code>"  selects the surrounding paragraph, with the greedier version being "<code>ap</code>".
    <li> etc.

Once you start using Vim's <a href="">text objects</a>, there really is no going back.
The power and precision they provide to specify regions of text to pass onto other Vim commands makes for an extremely efficient and elegant <i>modus operandi</i>, for which there simply is no equivalent in any other text editor.

For more information, please refer to the Vim documentation, either online, or by typing “:help text-objects” inside Vim.

Neat Bash Trick: Open Last Command for Editing in the Default Editor and then Execute on Saving/Exiting

This is pretty slick: enter “fc” in the shell and your last command opens up for editing in your default editor (as given by “$EDITOR“). Works perfectly with vi. The”$EDITOR” variable approach does not seem to work with BBEdit though, and you have to:

$ fc -e '/usr/bin/bbedit --wait'

With vi, “:cq” aborts execution of the command.

Managing and Munging Line Endings in Vim

If you have opened a file, and see a bunch “^M” or “^J” characters in it, chances are that for some reason Vim is confused as to the line-ending type.
You can force it to interpret the file with a specific line-ending by using the “++ff” argument and asking Vim to re-read the file using the “:e” command:

:e ++ff=unix
:e ++ff=mac
:e ++ff=dos

This will not actually change any characters in the file, just the way the file is interpreted.
If you want to resave the file with the new line-ending format, you can give the “++ff” argument to the “:w” command:

:w ++ff=unix
:w ++ff=mac
:w ++ff=dos

Alternatively, you can just set the line-ending format, and the file will be written out with the new line ending format the next time it is saved:

:set ff=unix
:set ff=mac
:set ff=dos

Filesystem Management with the Full Power of Vim

Just discovered vidir, a way to manipulate filenames inside your favorite text editor (better known as Vim).

Previously, I would use complex and cumbersome BASH constructs using “for;do;done”, “sed”, “awk” etc., coupled with the operation itself:

 $ for f in *.txt;  do mv $f $(echo $f | sed -e 's/foo\(\d\+\)_\(.*\)\.txt/bar_\1_blah_\2.txt/'); done

Which almost always involved a “pre-flight” dummy run to make sure the reg-ex’s were correct:

 $ for f in *.txt;  do echo mv $f $(echo $f | sed -e 's/foo\(\d\+\)_\(.*\)\.txt/bar_\1_blah_\2.txt/'); done

This approach works well enough, but apart from being a little cumbersome (especially if there is any fiddling to get the reg-ex’s right), is a little error-prone.

Now, the whole directory gets loaded up into the editor’s buffer (the “editor” being whatever ‘$EDITOR‘ is set to), for you to edit as you wish. When done, saving and exiting results in all the changes being applied to the directory. This allows you to bring the full power of regular expressions, line- and column-based selections etc., to bulk renaming and other operations. Best of all, you get to see the final set of proposed changes in your text editor before committing to the actual operation.

All of this can be rephrased as: ‘fantastic!

To get a dose of this filesystem management awesomeness in your world:

  1. Either clone the vidir repo or download a snapshot release from here.
  2. From inside the vidir directory:
  3. $ perl Makefile.PL
    $ make
    $ sudo make install

Execute Selected Lines of (Optionally) Marked-Up Python Code in a Vim Buffer

There are a number of solutions for executing Python code in your active buffer in Vim.
All of these expect the buffer lines to be well-formatted Python code, with correct indentation.
Many times, however, I am working on program or other documentation (in, for example reStructuredTex or Markdown format), and the code fragments that I want to execute have extra indentation or line leaders.

For example, a reStructuredText buffer might look like:

        How to Wuzzle the Wookie

        The :func:`foo` function can be used to wuzzle the wookie by::

            >>> import bar
            >>> fuzzlewuzzle ="the wookie")
            >>> for fuzz in fuzzlewuzzle:
            ...     if fuzz is
            ...          bar.wuzzle(fuzz)

While a Markdown buffer might have:

        ## How to Wuzzle the Wookie

        The ``foo`` function can be used to to wuzzle the wookie by:

            import bar
            fuzzlewuzzle ="the wookie")
            for fuzz in fuzzlewuzzle:
                if fuzz is

Simply passing the code lines in the above text to be evaluated in Python will not do: the extra decorators and indents required for embedding the code in the main document need to be dealt with.

Furthermore, many of the solutions that I could find (a) require Vim to have been built with Python enabled, and (b) use Vim’s internal Python to evaluate the lines.
The first seems like an unnecessary constraint, considering that native VimScript can handle the pre-processing quite well, while the second is problematical if there are external packages in your default system Python that the internal Vim Python does not have or if you prefer using the default system Python for whatever other reason.
Here I describe a pure-VimScript solution that handles the execution of optionally-marked-up visually-selected line ranges in your default system Python, and either shows the results in the command window or inserts the results in the current buffer.

Installation and Usage

Include the following code in your “~/.vimrc” or otherwise source it into your current Vim session.
Then select some lines of Python code and type “:EvalPy” to evaluate the lines in the default Python session and show the results in the command window, or “:EvalPy!” to evaluate the lines in the default Python session and insert the results in the current buffer.

Editing Remote Files With Your Local Vim Using the SCP Protocol

I love Vim!
It is so easy enough to edit a remote file with my local Vim through the Secure Copy protocol:

    $ vi scp://

However, I often find myself wishing that bash completion was available to expand/complete paths on the remote system.
Furthermore, when editing files outside of my home directory hierarchy, I have to remember to add an extra slash after the host name, e.g.:

    $ vi scp://

A solution is to write a custom wrapper function that takes scp-style remote file paths, converts them into Vim-style remote file paths, and then invokes Vim on them.
Then we can make use of the existing scp
bash completion for our wrapper function, and we get the side-benefit of not needing to juggle two different remote file path syntaxes.

The following code implements this solution. The function “vscp” is the wrapper function, while the line “complete -F _scp $nospace vscp” applies the “scp” completion function to the wrapper function. The code below needs to be sourced into your shell or placed into “~/.bashrc“.The “scp” completion function, “_scp() should already be defined if you have bash completion installed and sourced (and you should!), but just in case, it is conditionally defined here.

#! /bin/bash

function vscp() {
    if [[ -z $1 ]]
        echo "usage: vscp [[user@]host1:]file1 ... [[user@]host2:]file2"
    declare -a targs=()
    for iarg in $@
        targ="scp://$(echo $iarg | sed -e 's@:/@//@' | sed -e 's@:@/@')"
        targs=("${targs[@]}" $targ)
    vi ${targs[@]}

## Following function is from ".bash_completion". If it
## is not already defined/sourced, we define it here.
if [[ !$(declare -F _scp) ]]
        local cur userhost path

        local IFS=$'\t\n'

        _expand || return 0

        if [[ "$cur" == *:* ]]; then
            # remove backslash escape from :
            # unescape spaces
            path=${path//\\\\\\\\ / }
            if [ -z "$path" ]; then
                # default to home dir of specified user on remote host
                path=$(ssh -o 'Batchmode yes' $userhost pwd 2>/dev/null)
            # escape spaces; remove executables, aliases, pipes and sockets;
            # add space at end of file names
            COMPREPLY=( $( ssh -o 'Batchmode yes' $userhost \
                    command ls -aF1d "$path*" 2>/dev/null | \
                    sed -e 's/[][(){}<>",:;^&!$&=?`|\ ]/\\\\\\&/g' \
                    -e 's/[*@|=]$//g' -e 's/[^\/]$/& /g' ) )
            return 0

        [[ "$cur" == */* ]] || _known_hosts -c -a
            COMPREPLY=( ${COMPREPLY[@]} $( command ls -aF1d $cur* \
                    2>/dev/null | sed \
                    -e 's/[][(){}<>",:;^&!$&=?`|\ ]/\\&/g' \
                    -e 's/[*@|=]$//g' -e 's/[^\/]$/& /g' ) )
        return 0
complete -F _scp -o nospace vscp

The code is obviously pretty basic, and can be elaborated further (e.g., by passing custom options/arguments to Vim).


p>Once you have a remote file open in Vim, the command “:E” or “:Explorer” will open up Vim’s native remote filesystem browser. Once you have set up the function presented above, you can also invoke Vim’s native remote filesystem browser by passing in a directory path as an argument, being sure to include the trailing backslash:

    $ vscp

Of course, the obvious alternative to all of this is to login to the remote system and just edit the files through the ssh connection. Vim is, after all, ubiquitious and installed by default on most (decent) operating systems (except for the one that shall not be named). And, to be honest, this is what I do most of the time when making minor edits or tweaks.
However, there still are some benefits to using my local Vim versus a remote one over an ssh connection on a terminal emulator, especially when I have a major editing/debugging session: speed/responsiveness, and much nicer syntax coloration (16 million colors vs. the 16 colors to which I am limited using OS X’s Terminal). These may seem like minor advantages, but both make a huge difference when trawling through hundreds of lines of code!

Buffersaurus – A Vim Plugin for Searching and Indexing Across Buffers


Buffersaurus is a Vim plugin for searching and indexing the contents of buffers
for regular expression patterns or collections of regular expression patterns.
Results are displayed in separate buffer, and can be (optionally) viewed with
user-specifiable lines of context (i.e., a number of lines before and/or after
the line matching the search pattern) or filtered for specific patterns.

Global commands provided include (among others):

:Bsgrep[!] {pattern}
Search all buffers (or just current buffer if “!” given) for regular
expression pattern, {pattern}.
Construct a “table-of-contents” consisting of filetype-dependent
“important” patterns (e.g. class and method/function definitions).

Other commands include those for filtering results, jumping to next/previous
matching line without opening the catalog, searching for special user-defined
terms (“:Bsterm”) etc.

The results list can be browsed/navigated using all the usual Vim movement
commands. Selected lines can be opened in the previous window, a new window
split (vertical or horizontal), or a new tab page. Context can be toggled (i.e.
show a user-specified number of lines before or after the matching line).
Results are grouped and sorted by filename, and then by line number, but can
also be ungrouped and sorted lexically.

Search and replace as well as running arbitrary commands on the matched lines (or surrounding context lines) are also supported.

The primary distribution page for Buffersaurus is here:

Detailed usage description is given in the help file, which can be viewed
on-line here:

Source code repository can be found here:


If Pathogen is installed, you can install Buffersaurus by unpacking the source
(or cloning the Git repository) in “$VIMRUNTIME/bundle“. Otherwise, unpack the source archive and copy
buffersaurus.vim” to “$VIMRUNTIME/plugin” and “buffersaurus.txt” to

Character/Word/Line Count of Selection in Vim (a non-Vimique Vim Command) Compared to Underlining Text (a Vimique Operation)

Every day I discover at least one new thing about Vim. Sometimes useful, sometimes not. Sometimes rather prosaic, sometimes sublime.

This one falls in the useful but prosaic category: to get a count of the number of characters, lines, words etc. in the current selection, type "g CTRL-G".

This is a useful command, and good to know, but its invocation is a rather obscure key-mapping. In other words, just like most of the commands of your garden-variety “dumb” modeless editor, it can only be memorized (or looked up) and reproduced, instead of being generated based on grammatic-/syntactic- princples, like a language-based construct.

For an example of the latter, try this …

Move the cursor to a line of text, and then, in normal mode, type “yypVr-“.

This transforms:

Hello, world!


Hello, world!

A nifty little operation, and one that does not require memorization of any obscure key strokes. We are just “speaking” Vim:

  • yy“: yank (or copy) the current line
  • p“: put (or paste) the yanked/copied line
  • V“: select the (newly pasted) line
  • r-“: replace the contents with “-“, character by character

Even though more key-strokes than “g CTRL-G“, since the entire “phrase” is composed of a vocabulary of simple everyday commands/terms and can be composed from first princples, it does not need to be memorized, and hence never can be forgotten or need to be looked up. It simply is there, easily within reach of anyone who can express him- or herself in Vim.

A Tale of Two Vim Commands: ‘s’ and ‘c’

Vim continues to surprise me with its wonders. Sometimes (many times, in fact) things do not make sense, and I am perplexed as to the reasoning behind them. Then, one day, I grokked it. And from that day on, I can never imagine any other way of doing it.

An example of this was my confusion over the apparent redundancy of two fundamental commands.
In normal mode Vim, “s” (mnemonic: “substitute”) and “c” (mnemonic: “change”) are both ways to remove some existing text and then go into insert mode.
This is the equivalent of selecting some text with a mouse and beginning to type in the world of modeless editors.
For a while I was a little bit confused about the differences between the “s” and “c“, mainly because in some contexts they both behave the same way.
It took a little bit of snooping around the documentation and experimentation for me to realize the difference: “s” is the approach to use in simple situations, for replacing a single character or visual selection with typed text, while “c” is a much more powerful approach for use in more complex situations, because it is combined with motion and text object commands.

So, in general, you would use “s” in essentially one of two basic situations:

  • When you want to delete the character under the cursor, and replace it with text that you want to type in (which may be more than one character).
  • When you have text highlighted in visual select mode, and you want to delete it and replace it with new text that you want to type in.

And that is about it. In fact, in the first of these situations, i.e., replacing a single character with new text to be typed in, “s” is the most efficient way to do things.

The “c” command, on the other hand, is usually combined with a motion or text object command to provide a much broader range of target possibilities.
It can actually be used identically to “s” in the second situation above, i.e., to delete a visually selected block and replace it with new text to be typed in, but it really distinguishes itself when carrying out more complex operations than simply replacing the current visual selection.
The use of “c” with motions is straightforward: type “c” followed by a Vim movement command (e.g., “c$” or “cw“) , to delete everything from the current cursor position to the destination and enter insert mode.
The same applies with “c” and text objects: type “c” followed by a text object selection command (e.g., “ca)“, or “cis“) to delete the text object, and then enter insert mode and start typing.

Now, I not only understand the distinction beween “s” and “c“, but I also understand why Vim provides these two ways to go about doing a similar operation.
Because you combine the “c” command with a motion or text object, you can operate text regions of a broad range of sizes and scopes.
However, this means that in the simpler and more limited cases, where you just want to replace a single character or the current visual selection, using the “c” is quite inefficient, as you will be using keystrokes to describe what is the most atomic region of text (i.e., a single character) or the most obvious region of text (i.e., the current visual selection).
The “s” command exists solely to solve this problem, reducing the command to single keystroke when the region of text is irreducibly simple or absolutely unambiguous.

Vim: Making Those Arrow Keys Work for You (Or Why the Anti-Arrow-Key Propoganda is Wrong)

The Great Controversy

A standard dictum amongst experienced Vim users is not to use the arrow keys to move around your document. This dictum is often repeated again and again, in tones that range from the taken-for-granted to hysterical-zeal. The most common reason given for this is that using the arrow keys takes your hands away from the home row of your keyboard, and thus is wasteful both in terms of time and energy, whereas the standard Vim movement keys —| h, j, k, and l —| keep your hands on the home row, and therefore is far more efficient. Here is what I have discovered: this anti-arrow key argument is wrong!

The Great Experiment

When I first started using Vim, I of course found the h, j, k, and l keys to be horribly unintuitive.
But what was worse was that I could not use these keys to move in insert mode.It was this latter issue that kept me resolutely married to my arrow keys.The centi-seconds of time it took for me to move my fingers to hit an arrow key seemed far more efficient than exiting into normal mode, using the h, j, k, and l to move to where I wanted, and then i again to get back into insert mode. And so, for the longest time, not only did I continue to use the arrow keys, but I had absolutely no desire to cease doing so, just to gain what would probably accumulate to be about an hour’s worth of saved time over the course of a year.

Recently, however, on a whim, just to see what the fuss was about and if I was correct in viewing the arrow-keys-Noooooooooo!-zealots as the computing equivalent of monodimensional cladist fundamentalists, I decided to indulge in what I initially viewed as a temporary experiment in masochism.

Yes, that’s right.

I disabled my arrow keys:

inoremap  <Up>     <NOP>
  inoremap  <Down>   <NOP>
  inoremap  <Left>   <NOP>
  inoremap  <Right>  <NOP>
  noremap   <Up>     <NOP>
  noremap   <Down>   <NOP>
  noremap   <Left>   <NOP>
  noremap   <Right>  <NOP>

It did not take long (less than an hour) for me to get used to the spatial directions mapped to the h, j, k, and l keys, and so within a day I was comfortable using these keys to move around in normal mode. But the inability to move around in insert mode was incredibly annoying. It got so frustrating that I considered switching back to using arrow keys permanently, but decided to stick with the pain of trying to work in this tedious and painful environment for a little longer before giving up.

The Great Results

After a couple of days, I came to the realization that I had started working with Vim in a different way. It happened gradually, and mostly unconsciously, so that I did not notice it as first. But I did begin to notice that I was no longer tripping up or stumbling quite as much when needing to move around my document. In fact, quite the opposite, I felt like I was zipping around to places much faster and much more efficiently than I ever did before when I was using the arrow keys.

This feeling was not due to the gains from those accumulated centi-seconds shaved off my editing time by not having to move off the home row so frequently.</ on p>

It was, instead, due to the consequence of being forced to exit insert mode when I was not actually typing text.

Being forced to return to normal mode right after I edited the text at a single point in the document (sometimes just a couple of characters, sometimes a word or two, sometimes short blocks or fragments), also resulted in me being forced to use the rich suite of powerful normal mode movement commands to get to exactly where I needed to be before resuming editing. This was like suddenly beginning to use the fifth and other gears while driving on an open highway, whereas before I had been grinding along for mile after laborious mile on first.

The most remarkable and unanticipated aspect of my new way of working with Vim was not so much my usage of the h, j, k, and l keys, and other relatively “dumb” movement keys (0, $, etc.). It was my much greater usage of “smart” movement keys and commands. Due to the shift in the dominant ecology (i.e., normal mode vs. insert mode dominant), my repertoire of idioms for movement within and across the buffer evolved, and simple up/down/left/right movements were replaced by far more efficient and powerful commands. For example, I would use f/F/t/T/; etc. to jump to the exact character on a line that I wanted to get to, instead of pecking away at the left/right keys to get there. I would use :150 or 150G to jump directly to line 150 instead of using the up/down arrow keys. I would use /def or ?def to jump directly to a function line instead of tapping away a directional key like a zombie trying to signal in pseudo-Morse. I would use marks (e.g., mm) to register an “anchor” into the document that I could jump back to directly (by using, for example, 'm), before moving off to temporarily work on some other part of the document.

It is true, of course, that none of these movements are in any way more efficient when, for example, to moving a couple of characters to the left or right or up or down of the current position while in insert mode. In fact, this “local neighborhood” (i.e., one or two characters/lines on either side of my current position) is exactly where the arrow keys do come into their own by allowing you to get to these places without leaving insert mode. It is only when we start dealing with positions more than a couple of offsets away from the current position that the normal mode movement keys and commands start to yield benefits.

But the fact is, while I had arrow keys enabled I simply found it difficult to consciously make it a point to limit my use of them only within the “local neighborhood” . When in insert mode, and I needed to get anywhere that I could see in the viewable buffer, without thinking about it I would start tapping away at the arrow keys, even if the destination was several to dozens of lines/characters away. So while I had learned and started using all those “smart” movement commands that I am using now within the first couple of months of using Vim, I was just not using them enough or in all the places that I should been using them.

Disabling the arrow keys, while making “local neighborhood” movement significantly more cumbersome than before, taught and continues to teach me to view the document as a landscape, across which I can visit any point that I want directly and precisely through Vim’s normal mode movement commands. I still have not completely internalized this perspective, and often find myself reaching for the arrow keys unconsciously while editing in insert mode. So, for the time being, until this regime has been exorcized from my muscle memory, I think I am going to keep my arrow keys disabled as motion keys.

Re-Educating the Arrow Keys to Work With You: Text Shifters Instead of Cursor Movers

However, that does mean that I have 4 decent keys on my keyboard not doing anything at all. That, to me, seems just as wasteful as any of the extra energy and time required to use them. And thus I decided to put those arrow keys to work as “text movers” rather than their default role as “cursor movers”.

Editing text is like doing surgery: when you start hacking away at a bit of code, you usually open up various gashes and slashes in the surrounding area. At least with modern medical practices, it is both customary and polite to sew up these gashes and slashes, and naturally we do the same when editing code: indentation has to restored (here is a tip: see what = and == can do for you in Vim), empty lines need to be closed up, etc. etc. We probably do this dozens of times during a particular edit session, and typically it involves a lot of moving around, deleting and inserting lines all over the place. Even with the power of Vim’s normal mode commands, it still takes a lot of keystrokes, tedium and hassle to achieve this.

And so I have remapped my arrow keys to do the following:

  • The Up arrow key deletes a blank line above the current line (a non-empty line will not be deleted), while the Down arrow key inserts a blank line above the current line. The result is hitting Up or Down moves the current line up or down, in both normal as well as insert mode.
  • Typing Ctrl-Up and Ctrl-Down, instead, deletes or inserts a blank line below the current line. The result is that the text below the current line moves up or down, respectively.
  • Typing Left de-dents the current line, while Right indents it. The result is that text shifts left and right, respectively.

The following code, included in your ~/.vimrc or otherwise sourced into your session, implements this (the actual functions that do the work are copied from here):

function! DelEmptyLineAbove()
    if line(".") == 1
    let l:line = getline(line(".") - 1)
    if l:line =~ '^s*$'
        let l:colsave = col(".")
        silent normal! <C-y>
        call cursor(line("."), l:colsave)

function! AddEmptyLineAbove()
    let l:scrolloffsave = &scrolloff
    " Avoid jerky scrolling with ^E at top of window
    set scrolloff=0
    call append(line(".") - 1, "")
    if winline() != winheight(0)
        silent normal! <C-e>
    let &scrolloff = l:scrolloffsave

function! DelEmptyLineBelow()
    if line(".") == line("$")
    let l:line = getline(line(".") + 1)
    if l:line =~ '^s*$'
        let l:colsave = col(".")
        call cursor(line("."), l:colsave)

function! AddEmptyLineBelow()
    call append(line("."), "")

" Arrow key remapping: Up/Dn = move line up/dn; Left/Right = indent/unindent
function! SetArrowKeysAsTextShifters()
    " normal mode
    nmap <silent> <Left> <<
    nmap <silent> <Right> >>
    nnoremap <silent> <Up> <Esc>:call DelEmptyLineAbove()<CR>
    nnoremap <silent> <Down>  <Esc>:call AddEmptyLineAbove()<CR>
    nnoremap <silent> <C-Up> <Esc>:call DelEmptyLineBelow()<CR>
    nnoremap <silent> <C-Down> <Esc>:call AddEmptyLineBelow()<CR>

    " visual mode
    vmap <silent> <Left> <
    vmap <silent> <Right> >
    vnoremap <silent> <Up> <Esc>:call DelEmptyLineAbove()<CR>gv
    vnoremap <silent> <Down>  <Esc>:call AddEmptyLineAbove()<CR>gv
    vnoremap <silent> <C-Up> <Esc>:call DelEmptyLineBelow()<CR>gv
    vnoremap <silent> <C-Down> <Esc>:call AddEmptyLineBelow()<CR>gv

    " insert mode
    imap <silent> <Left> <C-D>
    imap <silent> <Right> <C-T>
    inoremap <silent> <Up> <Esc>:call DelEmptyLineAbove()<CR>a
    inoremap <silent> <Down> <Esc>:call AddEmptyLineAbove()<CR>a
    inoremap <silent> <C-Up> <Esc>:call DelEmptyLineBelow()<CR>a
    inoremap <silent> <C-Down> <Esc>:call AddEmptyLineBelow()<CR>a

    " disable modified versions we are not using
    nnoremap  <S-Up>     <NOP>
    nnoremap  <S-Down>   <NOP>
    nnoremap  <S-Left>   <NOP>
    nnoremap  <S-Right>  <NOP>
    vnoremap  <S-Up>     <NOP>
    vnoremap  <S-Down>   <NOP>
    vnoremap  <S-Left>   <NOP>
    vnoremap  <S-Right>  <NOP>
    inoremap  <S-Up>     <NOP>
    inoremap  <S-Down>   <NOP>
    inoremap  <S-Left>   <NOP>
    inoremap  <S-Right>  <NOP>

call SetArrowKeysAsTextShifters()

Using the arrow keys for cursor movement cripples you in terms of time and efficiency, due to the far superior alternatives found in normal mode. Using the arrow keys for shifting text, on the other hand, empowers you by wrapping up an often-used series of repetitive and stereotypical actions into a single keystroke.

Revisiting the “Don’t Use the Arrow Keys!” Dictum

Modified slightly to say “Don’t Use the Arrow Keys for Movement”, this dictum basically holds. But I think it utterly fails to capture the real issue at hand, and the customary justification offered for it (the whole “taking your hands off the home row is wasteful”) fails to make for a convincing argument.

Instead, I think that Vim tutorials, guides, advocates and propaganda everywhere should emphasize:

Don’t move around the document in insert mode!

This is because normal mode offers so much more power and flexibility to get to any part of your document precisely and quickly. The “Don’t Use the Arrow Keys for Movement” should be offered as a corollary to this, rather than a primary statement in its own right, because using arrow keys for movements leads you —| for psychological reasons —| to remain trapped in insert mode when you should be cruising and jetting about in normal mode.