If you work with terminals a lot you probably also edit text in it. helix has become my default after years of vim, vi and neovim. Why? Because my config file got too big.

Why should you use a modal editor in the style of VI? You shouldn’t. Quite frankly I started using VI and inspired editors out of a practical need to work on many different machines. After a steep learning curve the most import benefit was that I could get to work quickly without having to install and configure another text editor. Additionally VI-like editors usually support split views which I find to be just as useful as being able to delete several lines without a mouse or cursor keys. That and any editor running in your terminal naturally integrates with the remote system.

Get me that smooth space curve now

You can install helix via your distro’s package manager or if you want to be ridiculously portable you can install it straight from GitHub:

ver="22.12"; sys="linux"; arch=$(uname -m); [ "$arch" == "arm64" ] && arch="aarch64"; curl -L https://github.com/helix-editor/helix/releases/download/$ver/helix-$ver-$arch-$sys.tar.xz | tar -C ~/.local/bin -xJ --strip-components=1

Note: You can also install helix via cargo install helix --locked if you have a Rust development setup 🦀️. Of course there’s always a chance your toolchain is out of sync or you run into bugs.

When using helix for the first time you may want to double-check that it’s installed correctly:

hx --health

Following that the “grammar” i.e. what’s needed to get syntax highlighting and diagnostics working need to be installed:

hx --grammar fetch && hx --grammar build

The matching of languages and file types can be configured in ~/.config/helix/languages.toml:

name = "perl"
file-types = [{ suffix = ".pl" }, { suffix = ".pm" }, { suffix = ".t" }]

This simple example shows how to get .t files recognized as Perl. This is because some projects use this for unit test. The syntax here is probably fairly obvious. The official helix docs will clarify this further, aided by the built-in language definitions which you can override as needed.

If you’re into smart code completion and language-specific diagnostics you may also want to get yourself some language servers. This is not mandatory, though and you can also look into this later.

Completion on words without LSP is still a WIP but hopefully supported real soon(TM).

How do I quit helix?

Old memes die slow. If you’re already familiar with VI-like editors you may expect to struggle to get started*. Actually that’s not how it is with helix because it will make an effort explaining how it can be used. Try to guess some commands. Say:


Of course the fastest way to get going if you have little to no prior experience is still via the tutor:


Conveniently there’s a full overview of key inputs online going beyond what the tutor explains and to help you lookup whatever I’m not explaining (yet).

But I did used to use VIM

Coming from Neo/Vi/m you’ll need to adjust to a slightly different, arguably more consistent core mechanic. Every action is based on a selection. The selection → action model means that any word, line or paragraph you want to manipulate is selected before you do something with it. Even the cursor position with “no” selection is conceptually a selection of a single character.

Perhaps most important to become productive is to remember the following keys:

  • v to enter select mode
  • x to select the line
  • * to search (and n to continue as you might expect)

If you like me and many others before you rely on ^C leaving inset mode here’s a little snippet to continue doing that with helix:

C-c = "normal_mode"

If you did not know about this, allow me to explain. The escape key is quite out of reach if you have regular human hands. This is to avoid straining your fingers too much.

The spiral staircase is hurting yy eyes

Easier done than said. Grab a theme from GitHub and drop it into the folder ~/.config/helix/themes.

Specify the theme by its name:

theme = "gruvbox"

There you go.

Take your diagnostics out of the gutter

This will be entirely personal, so here’s just some inspiration. I like myself diagnostics, diff indicators when working with git repos, tabs for open “buffers” aka open files in memory and automatically saving changes reduces my chances of data loss to a minimum. Ultimately you need to try these out and see what works for you.

gutters = ["diagnostics", "diff"]
auto-save = true
bufferline = "multiple"
color-modes = true

Cursor shapes are even more so a matter of style. And perhaps comfort. They have zero impact on usability:

insert = "bar"
normal = "block"
select = "underline"

It can be handy to also show where indentation is expected. Again this is a matter of arbitrary preference:

render = true
character = "╎"
skip-levels = 1

Hidden files can of course be quite important so you have the option of always showing them in the file picker. If you don’t that’s also okay since :open will have your back and not second-guess you:

hidden = false

More customary convenience tweaks

Chances are you have various key combinations that you’re used to, either because that’s what your editor of choice uses by default or because you configured it at some point after having switched from another editor. This is easy enough even for uppercase keys and key sequences, even though the syntax may not be entirely obvious:

"C-w" = { c = ":bc" }
"Q" = ":qa"

This translates to Ctrl+w followed by c to close a file/ buffer and Shift+q to quit respectively. As an exercise you can type the same commands by hand. :bc and :qa are short forms of the regular command names. b stands for buffer, c stands for close, q stands for quit and a stands for all (sorry, it unfortunately doesn’t rhyme).

Now enjoy your tangent lines at a constant angle

In case you didn’t realize it to no particular effect there’s a few hints to the visual description of a helix all over this blog post. You don’t actually need any knowledge about this to use the editor.