Helix (editor)

As lazyvim gets more and more bloated, this is looking like an interesting alternative:

I tried Helix over the past few months. I like the pop-up menus and hints about key commands. However, it seems to require some JS components for language support, which I’d rather not install.

I spent some more time with Helix this morning – overall, it is working well. Going through the :tutor was instructive to learn the basics. I like the consistency.

Language servers have changed the game and allow things to be a lot more standard, greatly reducing the need for plugins.

Most language server features seem to be working for the languages I program in (C, Go, Elm, Js, Bash, etc) except for linting. I would really like to get linting working in the editor.

Helix does not bind Ctrl-C to exit INS mode (along with Esc), which I use heavily in Vim. I’m trying to stick with standard keybindings as much as possible, so I’ll see if I can learn Esc.

By far the most important thing is the following tmux tweak that gets rid of a 1s delay when hitting Esc to exit INS mode. This made Helix feel sluggish inside a tmux session.

.tmux.conf

set -sg escape-time 0

Helix config so far:

config.toml

# theme = "onedark"
# theme = "gruvbox"
theme = "dracula"
# theme = "solarized_dark"

[editor]
line-number = "relative"
true-color = true

languages.toml

[[language]]
name = "markdown"
auto-format = true
formatter = {command = "prettier", args = ["--parser", "markdown"]}

[[language]]
name = "go"
auto-format = true
formatter = {command = "goimports"}
language-servers = ["gopls", "golangci-lint-langserver"]

[[language]]
name = "javascript"
auto-format = true
formatter = {command = "prettier", args = ["--parser", "typescript"]}

[[language]]
name = "jsx"
auto-format = true
formatter = {command = "prettier", args = ["--parser", "typescript"]}

[[language]]
name = "bash"
auto-format = true
formatter = {command = "shfmt"}

I also created a shell script to install various language servers and formatters I use:

#!/bin/sh

sudo pacman -S shfmt zls shellcheck
npm install -g typescript-language-server typescript prettier bash-language-server
go install golang.org/x/tools/gopls@latest
go install golang.org/x/tools/cmd/goimports@latest
go install github.com/nametake/golangci-lint-langserver@latest
npm update -g

I like installing my own tools vs. having something like Mason manage them in Vim. LazyVIM was always telling me I had updates to install, etc. Configuration in the LazyVIM Lua code is also very difficult to understand compared to Helix.

Overall the experience is very good. The configuration is minimal and sane. The defaults are good. Keybindings are more consistent than Vim. I’m not sure if I like the select-action which is the reverse of action-select in Vim, but it seems logical.

I have been using it as well quite a bit and might switch to it as default too nvim+lazy has made my nvim feel like VSCode, regardless, I open quite large log files from builds etc. and helix is the only viable option which is fast to load and search etc. Here is my config

config.toml

    #theme = "catppuccin_macchiato"
    #theme = "base16_default_dark"
    theme = "onelight"
    #theme = "dracula_at_night"
    #theme = "dracula"

    [editor]
    #line-number = "absolute"
    mouse = false
    true-color = true

    [editor.cursor-shape]
    insert = "bar"
    normal = "block"
    select = "underline"

    [editor.file-picker]
    hidden = false

languages.toml

    use-grammars = { except = [ "gemini" ] }

    [[language]]
    name = "markdown"
    language-servers = [ "marksman", "ltex-ls" ]

    [[language]]
    name = "python"
    language-servers = [ "pyright" ]

    [[language]]
    name = "bitbake"
    scope = ""
    file-types = [ "bb", "bbappend", "bbclass", "inc" ]
    roots = []

    [[grammar]]
    name = "bitbake"
    source = { git = "https://github.com/amaanq/tree-sitter-bitbake", rev = "10bacac929ff36a1e8f4056503fe4f8717b21b94" }

The folks in the Helix Matrix suggest binding Caps-lock to Esc. This is easy to do in KDE:

The neat thing about this approach is that it will work in any app (vim, etc).

shellcheck (shell linter) is now working:

@khem we should clean up Yoe envsetup.sh some :slight_smile:

golangci-lint-langserver still not working …

Yes shell check fixes are welcome

Default language config for helix:

Not sure if they bundle this with the app – I don’t see it installed by the package.

Go linting is now working:

diff --git a/.config/helix/languages.toml b/.config/helix/languages.toml
index 2acfb9521..1c63d4cd2 100644
--- a/.config/helix/languages.toml
+++ b/.config/helix/languages.toml
@@ -8,7 +8,13 @@ formatter = {command = "prettier", args = ["--parser", "markdown"]}
 name = "go"
 auto-format = true
 formatter = {command = "goimports"}
-language-servers = ["gopls", "golangci-lint-langserver"]
+language-servers = ["gopls", "golangci-lint-lsp"]
+
+[language-server.golangci-lint-lsp]
+command = "golangci-lint-langserver"
+
+[language-server.golangci-lint-lsp.config]
+command = ["golangci-lint", "run", "--out-format", "json", "--issues-exit-code=1"]

This is already in the default languages.toml for helix – perhaps it has just not made it into the Arch packaged version yet …

This now shows Go linting errors:

This is a cool hack:

diff --git a/.config/helix/config.toml b/.config/helix/config.toml
index 6ba117457..4924dcc67 100644
--- a/.config/helix/config.toml
+++ b/.config/helix/config.toml
@@ -6,3 +6,6 @@ theme = "dracula"
 [editor]
 line-number = "relative"
 true-color = true
+
+[keys.normal]
+C-g = ":sh tmux popup -d \"#{pane_current_path}\" -xC -yC -w80% -h80% -E lazygit"

This opens lazygit in a tmux popup:

Alright time to switch default to force muscle memory change :slight_smile:

1 Like

if you use ‘D’ in vim/nvim to delete till end of line then you can do so in helix by adding this to ~/.config/helix/config.toml

[keys.normal]
# Delete till end of line shortcut D to match vim
D = ["ensure_selections_forward", "extend_to_line_end", "delete_selection"]

Global search and replace

Summary:

  • % - select entire file
  • s - select
  • type text you want to find
  • enter
  • scroll through the file to make sure selections look good
  • c - change
  • type new text
  • , - remove select/multiple cursors
1 Like

As a vim nerd I want this feature

1 Like

Cleaning up disk space in my home dir (ncdu is an amazing tool!):

lazyvim is pretty heavy. It is neat that it downloads everything you might ever need into the .local/share/nvim, but it is also starting to resemble NPM or VSCode a bit …

One of the best things about Helix is it starts instantly and is not reminding me to update gobs of stuff every single day. I’m all for living on the edge, but there are practical limits. I don’t update my Arch system daily, rather weekly or bi-weekly.

There is a balance between getting new and good stuff, and the overhead of updating.

All is not rosy - Here is a simple crash seen editing a .bb file trying to change SRCREV hash thats all

❯ RUST_BACKTRACE=1 vi meta-networking/recipes-support/lksctp-tools/lksctp-tools_1.0.19.bb
thread 'main' panicked at helix-core/src/indent.rs:465:21:
Invalid indent query: Unknown predicate ("lua-match?")
stack backtrace:
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

My helix has quite a bit bt now, wait for few months :slight_smile:

kraj@apollo ~/.config/helix
❯ du -sh .
1.1G    .
1.1G    total
❯ ls
config.toml  languages.toml  runtime/

Do you have any idea where the “lua-match” is coming from? Is there Lua code running somewhere?

HTML auto-completion example:

(someone on YouTube was asking and I needed a place to upload an image).

Bufferline

I’ve always liked having a bufferline:

diff --git a/.config/helix/config.toml b/.config/helix/config.toml
index 58f818e..633a313 100644
--- a/.config/helix/config.toml
+++ b/.config/helix/config.toml
@@ -7,6 +7,7 @@ theme = "ayu_evolve"
 [editor]
 line-number = "relative"
 true-color = true
+bufferline = "multiple"
 
 [editor.cursor-shape]
 insert = "bar"