Installation

We provide pre-built binaries on the GitHub Releases page.

Packaging status

OSX

A Homebrew tap is available:

brew tap helix-editor/helix
brew install helix

Linux

NixOS

A flake containing the package is available in the project root. The flake can also be used to spin up a reproducible development shell for working on Helix.

Arch Linux

Binary packages are available on AUR:

Build from source

git clone --recurse-submodules --shallow-submodules -j8 https://github.com/helix-editor/helix
cd helix
cargo install --path helix-term

This will install the hx binary to $HOME/.cargo/bin.

Helix also needs it's runtime files so make sure to copy/symlink the runtime/ directory into the config directory (for example ~/.config/helix/runtime on Linux/macOS). This location can be overriden via the HELIX_RUNTIME environment variable.

Usage

(Currently not fully documented, see the keymappings list for more.)

Registers

Vim-like registers can be used to yank and store text to be pasted later. Usage is similar, with " being used to select a register:

  • "ay - Yank the current selection to register a.
  • "op - Paste the text in register o after the selection.

If there is a selected register before invoking a change or delete command, the selection will be stored in the register and the action will be carried out:

  • "hc - Store the selection in register h and then change it (delete and enter insert mode).
  • "md - Store the selection in register m and delete it.

Special Registers

Register characterContains
/Last search
:Last executed command
"Last yanked text

There is no special register for copying to system clipboard, instead special commands and keybindings are provided. See the keymap for the specifics.

Surround

Functionality similar to vim-surround is built into helix. The keymappings have been inspired from vim-sandwich:

surround demo

  • ms - Add surround characters
  • mr - Replace surround characters
  • md - Delete surround characters

ms acts on a selection, so select the text first and use ms<char>. mr and md work on the closest pairs found and selections are not required; use counts to act in outer pairs.

It can also act on multiple seletions (yay!). For example, to change every occurance of (use) to [use]:

  • % to select the whole file
  • s to split the selections on a search term
  • Input use and hit Enter
  • mr([ to replace the parens with square brackets

Multiple characters are currently not supported, but planned.

Textobjects

Currently supported: word, surround.

textobject-demo

  • ma - Select around the object (va in vim, <alt-a> in kakoune)
  • mi - Select inside the object (vi in vim, <alt-i> in kakoune)
Key after mi or maTextobject selected
wWord
(, [, ', etcSpecified surround pairs

Textobjects based on treesitter, like function, class, etc are planned.

Migrating from Vim

Helix's editing model is strongly inspired from vim and kakoune, and a notable difference from vim (and the most striking similarity to kakoune) is that Helix follows the selection → action model. This means that the whatever you are going to act on (a word, a paragraph, a line, etc) is selected first and the action itself (delete, change, yank, etc) comes second. A cursor is simply a single width selection.

TODO: Mention texobjects, surround, registers

Configuration

To override global configuration parameters, create a config.toml file located in your config directory:

  • Linux and Mac: ~/.config/helix/config.toml
  • Windows: %AppData%\helix\config.toml

LSP

To display all language server messages in the status line add the following to your config.toml:

[lsp]
display-messages = true

Themes

First you'll need to place selected themes in your themes directory (i.e ~/.config/helix/themes), the directory might have to be created beforehand.

To use a custom theme add theme = <name> to your config.toml or override it during runtime using :theme <name>.

The default theme.toml can be found here, and user submitted themes here.

Creating a theme

First create a file with the name of your theme as file name (i.e mytheme.toml) and place it in your themes directory (i.e ~/.config/helix/themes).

Each line in the theme file is specified as below:

key = { fg = "#ffffff", bg = "#000000", modifiers = ["bold", "italic"] }

where key represents what you want to style, fg specifies the foreground color, bg the background color, and modifiers is a list of style modifiers. bg and modifiers can be omitted to defer to the defaults.

To specify only the foreground color:

key = "#ffffff"

if the key contains a dot '.', it must be quoted to prevent it being parsed as a dotted key.

"key.key" = "#ffffff"

Possible modifiers:

Modifier
bold
dim
italic
underlined
slow\_blink
rapid\_blink
reversed
hidden
crossed\_out

Possible keys:

KeyNotes
attribute
keyword
keyword.directivePreprocessor directives (#if in C)
keyword.controlControl flow
namespace
punctuation
punctuation.delimiter
operator
special
property
variable
variable.parameter
type
type.builtin
type.enum.variantEnum variants
constructor
function
function.macro
function.builtin
comment
variable.builtin
constant
constant.builtin
string
number
escapeEscaped characters
labelFor lifetimes
module
ui.background
ui.cursor
ui.cursor.insert
ui.cursor.select
ui.cursor.matchMatching bracket etc.
ui.cursor.primaryCursor with primary selection
ui.linenr
ui.linenr.selected
ui.statusline
ui.statusline.inactive
ui.popup
ui.window
ui.help
ui.text
ui.text.focus
ui.menu.selected
ui.selectionFor selections in the editing area
ui.selection.primary
warningLSP warning
errorLSP error
infoLSP info
hintLSP hint

These keys match tree-sitter scopes. We half-follow the common scopes from macromates language grammars with some differences.

For a given highlight produced, styling will be determined based on the longest matching theme key. So it's enough to provide function to highlight function.macro and function.builtin as well, but you can use more specific scopes to highlight specific cases differently.

Color palettes

You can define a palette of named colors, and refer to them from the configuration values in your theme. To do this, add a table called palette to your theme file:

ui.background = "white"
ui.text = "black"

[palette]
white = "#ffffff"
black = "#000000"

Remember that the [palette] table includes all keys after its header, so you should define the palette after normal theme options.

Keymap

Normal mode

Movement

NOTE: f, F, t and T are not confined to the current line.

KeyDescription
h, LeftMove left
j, DownMove down
k, UpMove up
l, RightMove right
wMove next word start
bMove previous word start
eMove next word end
WMove next WORD start
BMove previous WORD start
EMove next WORD end
tFind 'till next char
fFind next char
TFind 'till previous char
FFind previous char
HomeMove to the start of the line
EndMove to the end of the line
PageUpMove page up
PageDownMove page down
Ctrl-uMove half page up
Ctrl-dMove half page down
Ctrl-iJump forward on the jumplist TODO: conflicts tab
Ctrl-oJump backward on the jumplist
vEnter select (extend) mode
gEnter goto mode
mEnter match mode
:Enter command mode
zEnter view mode
Ctrl-wEnter window mode (maybe will be remove for spc w w later)
SpaceEnter space mode
KShow documentation for the item under the cursor

Changes

KeyDescription
rReplace with a character
RReplace with yanked text
~Switch case of the selected text
`Set the selected text to lower case
Alt-`Set the selected text to upper case
iInsert before selection
aInsert after selection (append)
IInsert at the start of the line
AInsert at the end of the line
oOpen new line below selection
OOpen new line above selection
uUndo change
URedo change
yYank selection
pPaste after selection
PPaste before selection
" <reg>Select a register to yank to or paste from
>Indent selection
<Unindent selection
=Format selection
dDelete selection
cChange selection (delete and enter insert mode)

Selection manipulation

KeyDescription
sSelect all regex matches inside selections
SSplit selection into subselections on regex matches
Alt-sSplit selection on newlines
;Collapse selection onto a single cursor
Alt-;Flip selection cursor and anchor
CCopy selection onto the next line
Alt-CCopy selection onto the previous line
(Rotate main selection forward
)Rotate main selection backward
Alt-(Rotate selection contents forward
Alt-)Rotate selection contents backward
%Select entire file
xSelect current line, if already selected, extend to next line
XExtend selection to line bounds (line-wise selection)
Expand selection to parent syntax node TODO: pick a key
JJoin lines inside selection
KKeep selections matching the regex TODO: overlapped by hover help
SpaceKeep only the primary selection TODO: overlapped by space mode
Ctrl-cComment/uncomment the selections

Insert Mode

KeyDescription
EscapeSwitch to normal mode
Ctrl-xAutocomplete
Ctrl-wDelete previous word

TODO: The search implementation isn't ideal yet -- we don't support searching in reverse, or searching via smartcase.

KeyDescription
/Search for regex pattern
nSelect next search match
NAdd next search match to selection
*Use current selection as the search pattern

Diagnostics

NOTE: [ and ] will likely contain more pair mappings in the style of vim-unimpaired

KeyDescription
[dGo to previous diagnostic
]dGo to next diagnostic
[DGo to first diagnostic in document
]DGo to last diagnostic in document

Select / extend mode

I'm still pondering whether to keep this mode or not. It changes movement commands to extend the existing selection instead of replacing it.

NOTE: It's a bit confusing at the moment because extend hasn't been implemented for all movement commands yet.

View mode

View mode is intended for scrolling and manipulating the view without changing the selection.

KeyDescription
z , cVertically center the line
tAlign the line to the top of the screen
bAlign the line to the bottom of the screen
mAlign the line to the middle of the screen (horizontally)
jScroll the view downwards
kScroll the view upwards

Goto mode

Jumps to various locations.

NOTE: Some of these features are only available with the LSP present.

KeyDescription
gGo to the start of the file
eGo to the end of the file
hGo to the start of the line
lGo to the end of the line
sGo to first non-whitespace character of the line
tGo to the top of the screen
mGo to the middle of the screen
bGo to the bottom of the screen
dGo to definition
yGo to type definition
rGo to references
iGo to implementation
aGo to the last accessed/alternate file

Match mode

Enter this mode using m from normal mode. See the relavant section in Usage for an explanation about surround and textobject usage.

KeyDescription
mGoto matching bracket
s <char>Surround current selection with <char>
r <from><to>Replace surround character <from> with <to>
d <char>Delete surround character <char>
a <object>Select around textobject
i <object>Select inside textobject

Object mode

TODO: Mappings for selecting syntax nodes (a superset of [).

Window mode

This layer is similar to vim keybindings as kakoune does not support window.

KeyDescription
w, Ctrl-wSwitch to next window
v, Ctrl-vVertical right split
h, Ctrl-hHorizontal bottom split
q, Ctrl-qClose current window

Space mode

This layer is a kludge of mappings I had under leader key in neovim.

KeyDescription
fOpen file picker
bOpen buffer picker
sOpen symbol picker (current document)
aApply code action
'Open last fuzzy picker
wEnter window mode
spaceKeep primary selection TODO: it's here because space mode replaced it
pPaste system clipboard after selections
PPaste system clipboard before selections
yJoin and yank selections to clipboard
YYank main selection to clipboard
RReplace selections by clipboard contents

Picker

Keys to use within picker.

KeyDescription
Up, Ctrl-pPrevious entry
Down, Ctrl-nNext entry
Ctrl-spaceFilter options
EnterOpen selected
Ctrl-hOpen horizontally
Ctrl-vOpen vertically
Escape, Ctrl-cClose picker

Key Remapping

One-way key remapping is temporarily supported via a simple TOML configuration file. (More powerful solutions such as rebinding via commands will be available in the feature).

To remap keys, write a config.toml file in your helix configuration directory (default ~/.config/helix in Linux systems) with a structure like this:

# At most one section each of 'keys.normal', 'keys.insert' and 'keys.select'
[keys.normal]
a = "move_char_left" # Maps the 'a' key to the move_char_left command
w = "move_line_up" # Maps the 'w' key move_line_up
"C-S-esc" = "extend_line" # Maps Control-Shift-Escape to extend_line
g = { a = "code_action" } # Maps `ga` to show possible code actions

[keys.insert]
"A-x" = "normal_mode" # Maps Alt-X to enter normal mode
j = { k = "normal_mode" } # Maps `jk` to exit insert mode

Control, Shift and Alt modifiers are encoded respectively with the prefixes C-, S- and A-. Special keys are encoded as follows:

Key nameRepresentation
Backspace"backspace"
Space"space"
Return/Enter"ret"
<"lt"
>"gt"
+"plus"
-"minus"
;"semicolon"
%"percent"
Left"left"
Right"right"
Up"up"
Home"home"
End"end"
Page"pageup"
Page"pagedown"
Tab"tab"
Back"backtab"
Delete"del"
Insert"ins"
Null"null"
Escape"esc"

Commands can be found in the source code at helix-term/src/commands.rs

Hooks