How I'm using Helix editor
I've been using Helix as my editor to develop on remote servers for quite some time now.
There are a lot of emerging supply-chain attacks, and I simply don't like the idea of installing tens of plugins to Vim/Neovim to make the editor usable.
To make the switch from Neovim easier, I had to make some changes to the configuration. I want to share them to save you some time, because discovering them is not straightforward.
Tmux setup
I use tmux as a terminal multiplexer.
One thing that I miss from Neovim setup is a good file manager and TUI for git. I rarely use a file manager, but when I need to, I usually want to move a bunch of selected files quickly. Unfortunately, Helix does not support file editing in the explorer. You can only view them.
To overcome it, I added new keybindings to my tmux config:
# Yazi related
set -g allow-passthrough on
set -ga update-environment TERM
set -ga update-environment TERM_PROGRAM
bind-key y display-popup -d '#{pane_current_path}' -x R -h 95% -w 95% -E 'tmux new-session yazi \; set status off'
bind-key g popup -E -w 95% -h 95% -d '#{pane_current_path}' lazygit
bind-key e display-popup -w 95% -h 90% -E "tmux capture-pane -Jp -S- | hx -"
When I hit one of the keys, a new pop-up window opens.
prefix - y
- opensyazi
file managerprefix - g
- openslazygit
prefix - e
- opens Helix editor with tmux output history.
The default prefix for tmux is Ctrl + b
, but I'm using Ctrl + \
.
The last binding is useful when you want to work with terminal output in your editor. I use it to search the history using regexes or copy selected output quickly. For example, I use it quite a lot to copy output from clickhouse
client that outputs SQL results in CSV or JSON to the terminal. Although it can output it to a file, that's an extra step, since I usually only need to copy-paste the output to Slack. This can be done via mouse, but painful with tmux setup, since you need to scroll the buffer when the output does not fit in one screen.
The yazi
and lazygit
tools are usually opened on top of the Helix Editor.
Vim bindings
I'm pretty used to Helix keybinds now, but there are still some bindings that I ported from vim:
[keys.select]
0 = "goto_line_start"
"$" = "goto_line_end"
"^" = "goto_first_nonwhitespace"
G = "goto_file_end"
D = ["extend_to_line_bounds", "delete_selection", "normal_mode"]
k = ["extend_line_up", "extend_to_line_bounds"]
j = ["extend_line_down", "extend_to_line_bounds"]
[keys.normal]
D = ["ensure_selections_forward", "extend_to_line_end", "delete_selection"]
0 = "goto_line_start"
"$" = "goto_line_end"
"^" = "goto_first_nonwhitespace"
G = "goto_file_end"
V = ["select_mode", "extend_to_line_bounds"]
esc = ["collapse_selection", "keep_primary_selection"]
I don't like how Helix selects lines in visual mode. That's why I switched to vim-like behavior. Going one line up/down in a select mode selects the whole line. Helix selects them partially.
I have also rebinded ESC so it resets multiple cursors as well. By default, you need to press comma.
Lastly, removing text until the end of the line takes too many keypresses, so I ported the D motion as well. It removes everything to the right of your cursor in select mode.
Improved status line
The default status line lacks some important information, such as the current git branch.
I'm using the following config for my status line:
[editor.statusline]
left = [
"mode",
"spinner",
"version-control",
"spacer",
"separator",
"file-name",
"read-only-indicator",
"file-modification-indicator",
]
center = []
right = [
"diagnostics",
"workspace-diagnostics",
"position",
"total-line-numbers",
"position-percentage",
"file-encoding",
"file-line-ending",
"file-type",
"register",
"selections",
]
separator = "│"
Useful keybindings
You can make your life way easier with custom keybindings. Discovering them took me some time.
In my opinion, the most useful are: file reloading, soft wrap toggle, git undo, and git blame.
Here is a full list of my custom bindings:
space - e - w
- Write current buffer to file.space - e - c
- Close current buffer.space - e - x
- Close other buffers. This is useful when you have tens of buffers open.space - e - l
- Toggle inlay type hints. They can be useful, but also noisy to display them every time.+ - f
- Format current file.+ - w
- Render whitespace symbols. Useful to check what kind of invisible characters are in the document.+ - W
- Disable rendering whitespace symbols.space - f - .
- Show/hide git ignored files in file picker.space - f - r
- Reload all files. This is very useful, since Helix does not support auto-reloading right now. When a file gets changes externally or when I commit changes, I press this keybinding to update the gutters and sync file changes.space - f - x
- Undo git change at the current cursor.space - f - w
- Show git blame for the current line.
[keys.normal.space]
e = { w = ":write", c = ":bc", x = ":bco", l = ":toggle lsp.display-inlay-hints" }
q = ":quit"
[keys.normal."+"]
f = ":format"
w = ":toggle whitespace.render all"
W = ":set whitespace.render none"
s = ":toggle soft-wrap.enable"
[keys.normal.space.f]
f = "file_picker_in_current_directory"
F = "file_picker"
b = "file_picker_in_current_buffer_directory"
"." = ":toggle-option file-picker.git-ignore"
g = "global_search"
e = "file_explorer"
r = ":reload-all"
x = ":reset-diff-change"
w = ":echo %sh{git blame -L %{cursor_line},+1 %{buffer_name}}"
Editor config
After using Helix for 6 months, I discovered that it supports autosave when you switch tabs in your terminal. Some of the newer features in Helix are disabled by default, so old users won't see unexpected changes. You need to go through each option to discover them.
Here is my config:
[editor]
line-number = "relative"
mouse = true
rulers = [120]
true-color = true
completion-replace = true
trim-trailing-whitespace = true
end-of-line-diagnostics = "hint"
color-modes = true
rainbow-brackets = true
[editor.inline-diagnostics]
cursor-line = "warning"
[editor.file-picker]
hidden = false
[editor.indent-guides]
render = true
character = "╎"
skip-levels = 0
[editor.soft-wrap]
enable = false
[editor.auto-save]
focus-lost = true
after-delay.enable = true
after-delay.timeout = 300000
Some notable options:
true-color
- Forces true color support.editor.file-picker.hidden
- Show dot files in file picker.rulers
- Sets visual vertical rulers. Useful when you want to limit the maximum line length of your code without autoformatting.completion-replace
- Competitions replace the whole word.editor.inline-diagnostics.cursor-line
- Makes diagnostics look better. See screenshot.color-modes
- Makes the mode indicator colored.editor.indent-guides
- Adds visual indent guides.editor.auto-save.focus-lost
- Automatically saves file when focus is lost. Requires terminal support.editor.auto-save.after-delay.enable
- Automatically saves file after specified delay.rainbow-brackets
- Use different colors for nested brackets. Recent feature, not part of the most recent release yet.
LSP tweaks
For every language, I usually add harper-ls
LSP to highlight grammar errors in comments.
User setups
I'm curious to hear more tricks from Helix users. So please share your findings in the comments!