Vim Keybindings in All CLIs

(October 5, 2020)

This post already lives as part of my cheatsheets, but I think this is one of those things that's worth putting out there.

readline is a library that can be used to add keyboard shortcuts to various CLI programs. If you're a command line user on Linux or Mac, you're probably already using it even if you don't know it — bash keyboard shortcuts come from readline.

By default, readline uses Emacs-like bindings. If you were ever confused by the weird key combinations in bash, this is where they come from.

readline can be configured via an ~/.inputrc config file in your home directory.

There are several other libraries that provide similar functionality that are used by certain CLI programs. libedit is a popular alternative with a more permissive ("less free") license. Many Haskell projects use haskeline, created specifically for ghc.

Configuring readline

All of the above libraries can be configured with config files in your home directory. Here's what to put in your dotfiles to use vi keybindings by default:

# ~/.inputrc
set editing-mode vi

# ~/.editrc
bind -v

# ~/.haskeline
editMode: Vi

One other useful tip: if you want to just quickly switch bash to vi keys, perhaps on an account that's temporary and you won't be putting effort into customizing it, you can do so by running set -o vi.

Where this doesn't work

The above configs cover some of my most used CLI tools, like bash, REPLs for Ruby, Python, Haskell. My biggest pain is that I haven't found a satisfactory way of getting vi keybindings in a Node.js shell.

In some cases you can hack your way around a CLI not using any of the readline-like libraries using a tool called rlwrap. Unfortunately, it's not a silver bullet. I remember it working fine enough for the OCaml REPL, but it doesn't play well with Node.

If you have any questions or comments about this post or site in general, feel free to email me.