I've been a vim user for more than 20 years now. I've moved to neovim a couple of years ago, attracted by the smaller codebase, the gradual port to lua both for plugins and internals, tree-sitter integration, LSP support, …
But I gradually grown to dislike it: rewriting my vimrc into lua felt like a cumbersome chore that only increases its verbosity at the price of its portability, for no gains at all. LSP support is done via yet another plugin and a ton of boilerplate, same for tree-sitter. Moreover, neovim doesn't have plans to have support for vimscript9, meaning that the plugin ecosystem will soon be split into vimscript/lua/vimscript9.
Speaking of plugins: everything requires one: Want a theme? plugin. Want fuzzy-finding? plugins. Want a file explorer that doesn't look horrible? plugin. Want to show vcs annotations? plugin. Modern debugging support? plugin. LSP support? plugins. Language independent commenting? plugin. Snippets? plugin. Code outline? plugin. EditorConfig support? plugin.
Coupled with configuration
directives that evolved organically for more than 30 years,
it makes things brittle. For example, set ttyfast
,
let c_ansi_typedefs=1
, autocmd BufnewFile,BufReadPost *.c,*.cpp,*.h,*.hpp
syn match cType "\<[a-zA-Z_][a-zA-Z0-9_]\+_t\>"
, nnoremap <Leader>oc :e
%<.c<CR>
, map <Leader>q ::b#<bar>bd#<CR>
, set fillchars+=vert:│
, … Good
luck figuring out what they're doing, or even why you added them to your
configuration in the first place.
Reading (neo)vim's documentation is a trip down memory-lane: :help
php3.vim
(1997) is still a thing, :help java.vim
mentions java 1.0.2 (1996),
:help mapple.vim
mentions Maple V
RC4 (1996),
:help postscript.vim
says that the default highlighted version is Postscript
2 (1991) "since
this is the most prevalent version currently.",
:help xf86conf.vim
only mentions XFree86 v3 (1994)
and XFree86 v4 (2000),
…
Speaking of legacy, some keymaps are weird as well: C-]
to follow a symbol
but C-t
to jump back because C-[
is equivalent to <Esc>
, u
to undo but
C-r
to redo, the g
prefix is usually used for go to
commands like gd
for g
o to d
eclaration, except that g~
is to swap case, gUU
to uppercase
the current line,nd gv
to reselect the previous selection. z
is to
manage folds except z{number}
is to resize panes and z=
is to
suggest spellings for the words under/after the cursor.
Autocompletion is interesting as well, with
C-x
to enter completion, then C-l
, C-n
, C-k
, C-t
, C-i
,
C-]
, C-f
, C-d
, C-v
, C-u
,
C-q
, s
or C-p
depending on how you want to autocomplete, and so on.
Moreover, while the idea of modal
editing is the best thing since
the invention of the banana curving machine, vim's Verb → Object
construct is
awkward at best. Text editing isn't
linguistics: I
might say "I want to delete this line of text", but what I'm thinking when
dealing with code is "this part of the code, here, I'd like to delete it". It's
pretty common to apply an action
to the wrong object: maybe you wanted to delete 6 lines instead of 5, but you
eyeballed it wrong? It's possible to fix this by making use of
vim's visual mode,
transforming it into Selection → Action
, letting you see what you're doing.
Enter Helix: written in Rust, inspired by vim and kakoune, with a neat vision: Cross-platform, modal, terminal first, native, lightweight, batteries included, modern, actively developed, …
Visually, my neovim and my helix
are super-similar, but for the later, there is no
need to fiddle around to get LSP working, it just works. For
openmw, a large C++ project, I
only had to cd openmw; mkdir build; cd build; cmake
-DCMAKE_EXPORT_COMPILE_COMMANDS=1 ..; make -j $(nproc)
to generate the
compile_commands.json
and that was it, LSP was simply working. To use tree-sitter, hx -g fetch build
and that's it.
EditorConfig is natively supported.
Multi-selection is a thing, no need to hack with macros and visual mode. Every
cool thing from vim is there as well: buffers, registers, windows, command
mode, … it also comes with a bunch of modern
themes: no
plugins required.
While vim commands are burned in my brain, helix' ones are making way more sense.
For example, to replace the word one
with two
in a whole document:
- vim:
:%s/one/two/g<Cr>
, with:
to enter command mode,%
to apply the next operand to the whole document,s
for searching,/
as a marker,one
as the word to be replaced, marker again,two
to replace, marker,g
to replace globally. - helix:
%sone<Cr>ctwo<esc>
, with%
to select the whole document,s
tos
elect,one
for the word to select, thenc
toc
hange withtwo
.
In insert mode, helix uses the Readline Emacs Key Binding, aka the
one used in bash, zsh, osx, emacs, … so should one get lost, insert mode has
familiar shortcuts. Moreover, if you don't like the default configuration or keybindings, it's ok: everything
can be changed by editing a toml file. It's possible to
map any keymap to any
command,
like C = ["goto_line_start", "extend_to_line_bounds", "change_selection"]
and d = { d = ["extend_to_line_bounds",
"delete_selection"], t = ["extend_till_char"], s = ["surround_delete"], i =
["select_textobject_inner"], a = ["select_textobject_around"] }
to make C
and d
behave like in vim, without resorting to cryptic black
magic vimscript-like incantations. Check
helix-vim for inspiration,
or even my config if you're feeling
adventurous.
There are of course still a bit of rough edges, like the lack of soft
wrap,
no git integration,
no EditoConfig support,
no :help
,
no virtual text support,
no snippets support,
more than 150 dependencies,
my helix folder (sources + binaries) weights 1.5G,
… but it's getting there.
If you want to give it a try, there is of course an equivalent to
vimtutor that can be invoked via the
:tutor
command,
and there are cheat-sheets
and documentation. And if you
don't want to read things and simply start using it, minor
modes will make it
easy: pressing <space>
will open a menu in
which pressing w
(for W
indow Management) opens another
one and so on. The same system is used for
registers management, jumping to places, command mode, match mode, …
Moreover, it's fast compared to vim/neovim: editing large yaml file isn't sluggish, visual selection and completion are instant, syntax highlighting doesn't choke on long lines, …
In a couple of years, or maybe months, this could become a serious contender to (neo)vim, but more importantly, my main editor.