Rethinking Helix
40 points by hush
40 points by hush
To me, this misses the point of the selection -> action model. If one is using it like vim, and making exactly one selection and then performing exactly one action, it is by all means more cumbersome and less ergonomic.
The point of selecting before acting is that the commands can compose to a much greater degree. With helix, you can make a selection, perform an action on that selection (which preserves the selection), then expand the selection, perform two more actions, etc.
Suppose I’m editing foo(baz.qux), am currently inside the parens, and I would like to change it to foo(bar(baz.qux)).
In helix, I can type:
mi( to select inside the parens, yielding foo([baz.qux]) (brackets denoting selection)ms( to surround it with parens, yielding foo([(baz.qux)])
ibar to insert bar before the selection, yielding foo(bar(baz.qux))
In vim, I could type ysi(( (if memory serves) to accomplish the first two steps. And if that’s all I want to do, it was one character shorter! However, after I do that, all context related to the parens is gone, so when I want to prepend bar, I need to perform another motion to get back there.
I find that editing in vim essentially follows a model of small, independent changes. What is really powerful in helix is that you can chain multiple selections and actions together in complex ways. This is especially enhanced by multi cursor editing, which combined with helix's other features, allows performing complex structural modifications in multiple places simultaneously.
So yes, individual commands are longer, because of the shared namespace, and there are more things to think about in each command, but the result is, IMO, an editing language that is significantly more expressive and powerful.
I do agree with done of the article's critiques, in the there are some commands which are inconsistent with others, or behaviors that haven't been standardized, etc. But I think this is to be expected in the early days, and can improve with time. Many of these rough edges can also be fixed with a local keymap — for example, I have w bound to miw, like the article suggests, and instead of using x (which has rather odd behavior), I have a V binding which extends to line bounds and enters selection mode, and shift-[direction] keys in selection mode which moves in that direction and extends to line bounds, allowing a visual line like mode, with the slight modification that shift is held through the whole selection, not just for V.
Got super curious to see that input sequence in action. If anyone else had the same feeling, demo at https://henry.catalinismith.se/2026/01/12/helix-demo.mp4
I find that editing in vim essentially follows a model of small, independent changes. What is really powerful in helix is that you can chain multiple selections and actions together in complex ways.
Is "independent changes" part is essential to vim or incidental? If the model is based on non-inteactive Ed, then I see why they happen to be independent — if editor can't easily show where a command got you and you have to evaluate it in your head, then interdependence and extra state (like selections) bring a lot of mental overhead. But if you were making an interactive editor and you were free of Ed legacy, there's no reason why the Vim commands had to be independent in this manner.
I don't think it's essential that editing commands are independent. Vim treats each regex or operator-motion command as a program, and you're like shooting these "programs" at your text. There's no reason why your whole session between opening and closing the file can't be your program, carrying some selection-state between individual steps. On demand, the user can reset this state and collapse all selections to one cursor, breaking the session into steps that are somewhat isolated. The user can make them as independent as he chooses.
I think that expressive language of composable commands is the essential idea of Vim, making commands independent is not. By this interpretation, Kakoune and Helix are closer to Vim spirit than Vim and NeoVim, since they bring out the essence of the idea striping away the incidental that was in the way.
In vim is this not ci)bar(<C-r>-)? IOW change the text inside the parents and type out bar() but recall the changed text inside the new parens?
I suppose that is a way to do it, yes. I still think that it is a good example of how helix's commands can chain together, and I regularly use much longer chains than that.
I see what you mean, definitely. Also this way of thinking reminds me of Cusorless, which isn't discussed much but which has a rich and well-developed philosophy around selection and action.
Helix conflates movement and selection. Each command decides what happens to the anchor. We lose in predictability what we gain in flexibility.
I've switched first to Kakoune back when that made a splash and later to Helix when it became viable enough. I have never found them to be unpredictable in any way. In fact the massively increased interactive feedback from building up selections makes everything more predictable!
I just started (a week ago) dipping my toes into the select -> act editors and I’m completely convinced it’s the right approach. Being able to see what I’m acting on before I act is an innovation in the vim ecosystem.
I also think in general the key bindings are more thoughtful, the one exception being leveraging the alt key as a modifier sucks for us small keyboard users. I just don’t have that binding in a good position.
But I actually chose kakoune over helix. I like the minimalism of it and thinking merging normal and visual mode together is fantastic.
I’d be curious to read your thoughts on the differences between kak and helix since it was a tough call for me. One on hand I like the minimalism but on the other hand helix has captured this niche quite well with its built pickers and LSP
merging normal and visual mode together is fantastic
You can mostly do that in helix's config anyway. You don't have to stick to the default keymap!
Nice! I was torn on which to pick so if kak doesn’t work the next option is helix. After that it’ll be build my own lol
I have never found them to be unpredictable in any way.
Except, of course, x doing a different thing on empty line, selecting the next line instead of current one..
This behavior was inherited from Kakoune. Kakoune has since patched it out (mawww considers it a bug), and Helix kept it.
Indeed, Kakoune moved towards more predictable, less smart primitives over time, as this works better with multiselection and scrupting. The previous x behaviour breaks down when one selection is on an empty line and another is not, its unlikely the user expects only one selection to move to next line. IIRC we had an alt-x version that disabled this behaviour that was used when scripting to get predictable behaviour.
Thanks for letting me know. I was using forked Kakoune due to this before I switched to Helix and had to fork again.
That always felt completely intuitive to me. There's nothing to select on an empty line, what would you select there? Moving to the 0 of the next line would be weirder to me.
in helix, i often press xd to delete the current line. but this doesn't work when the current line is empty, and this trips me up all the time
It changes the behavior of line-wise operation based on the content of the line which should be irrelevant. Anyway, I don't want to be debating this. I accepted my fate and I have a fork of Helix that fixes it. :D
I disagree, I've always understood x to mean "extend the selection to select from the first until the last character" (for each selection). So, in my opinion what happens in Kakoune is more intuitive. When you press x on an empty line, nothing happens, because the selection already spans the entire line, and there is no extending to do.
I love to see someone (over)thinking through things like this, even (or especially) when I find their thoughts very strange. I especially appreciated this bit of self-awareness, as a former Vim user who learned Helix quickly.
It astounds me when Vim users learn Helix in a few weeks because to me they are nothing alike.
To me they are extremely similar, but I appreciate the effort of making the strongest possible case that they are not.
Less abstractly, I wonder how much of this comes down to going really deep in Vim. I used Vim and Vim modes as my primary editor for several years, but I never felt particularly great at it and I always found the verb-object model confusing — I strongly prefer to see what I’m operating on as I do it. I imagine the long tail of Vim users are quite shallow users, and that type of usage maps pretty naturally to Helix. The author gets at this:
Neovim's complexity lives in its commands: its vocabulary for targeting text. Those targets can be complex, but they are always ephemeral. We type our command and we are back at ground level with our finger in the book. Helix lives on the first floor. We have two fingers to point with. Anchor and cursor. We always target something and the target is always on screen.
Ultimately I do not buy the author’s argument that selections are a form of mediation, in contrast to Vim’s more direct access.
Neovim's motions and operators are both intimately tied to the text at hand. Helix's model severs the connection between operator and text by introducing a middleman, the first-class selection.
This would feel more plausible to me as a claim about non-modal editors. In Vim, your access to the text is mediated by what amounts of a programming language — every command is a little program you have to compose in your head without seeing its effect on screen until you’re done.
I'm a (neo)vim user and have tried helix a few times at different points, but always end up going back. I think the author nails at least one of the quirks of helix that didn't jive with me, and that's the constant implicit selection as state that you just have to be aware of at all times. I kept doing things that I didn't intend because my mental model of what the selection was didn't match reality. One of the selling points of helix was that since you select first, you can see what the selection is at any time. But that means that you have to look and notice when it differs from the mental model. I rarely look at my cursor, my focus is usually elsewhere. It feels like looking at the keys while typing.
I don't think there is a right or wrong here, but for me personally I ended up being unconvinced of helix mode and actually prefer vim.
My experience was similar. I tried using Helix for a couple of weeks, and while parts of it like the LSP integration and command discoverability are very nice, I went back to neovim. I may be looking at the screen while I'm editing, but I'm not usually thinking about the literal symbols on the screen, and I found that Helix brought my focus to those while I can do what I want in vim without thinking too much about it. I guess it doesn't help that I learned vim and its bindings when I was working as a copyeditor and got really good at doing what I want quickly, so I might just be too ruined to appreciate the future.
Aren't the times when selection differs from what you expect exactly the times when you made an accidental mistake, which are the times when seeing the selection is very helpful? Noticing you got the selection wrong is much easier when you see… well… the selection than when you only see the end result of applying an operator to a wrong range.
You were about to perfectly explain the objective benefit of Kakoune model over Vim, but then made a sudden turn to "I don't think there's right and wrong". There is right and wrong here. It's totally ok to be personally unused to "right" and keep using "wrong" if you don't feel like re-learning, but it doesn't discard the notion of right and wrong.
Most of your defense of Vim is roughly "I'm so used to the Vim model and it's downsides that learning something without these downsides feels unnatural".
The analogy with looking at your keyboard when typing doesn't hold well, because typing is just mindless transmission of a stream of symbols from fixed alphabet. Composing commands to your text editor is a complex language, where you program what you want from smaller steps — you're not just muscle-memory translating symbols. Programming is prone to errors, and seeing feedback from each step is more like tracing your program as you write it line by line.
You were about to perfectly explain the objective benefit of Kakoune model over Vim, but then made a sudden turn to "I don't think there's right and wrong". There is right and wrong here.
That’s just, like, your opinion, man.
I'm not sure. I don't think there's right and wrong here, in the matter of this being just my opinion. After all, this is just your subjective view. I guess we'll never know whether that was just my opinion or not.
Can you see the problem?
Helix is a layered editor or a two-tier editor. We edit our text via our selections. Neovim's motions and operators are both intimately tied to the text at hand.
The biggest difference and benefit of Kakoune-style editors like Helix for me is that "Vim golf" is pointless in them. While in Vim it's necessary. Let me explain.
Start with Vim model. Swap the order of motion and operator. This is still equivalent to Vim, we haven't changed anything meaningful. Now, observe that if motion is given first, the editor could highlight the range you're about to operate on. This is strictly better than original Vim since the user could still type the operator blindly without looking at the selection, so nothing is lost, while seeing whether you got your motion right before you operate can save you from a gotcha or two. You put less strain on your attention to getting things right blindly, freeing your energy to do something that's actually productive. Kakoune-style editors like Helix naturally take this idea further: if selections are shown interactively, you could afford to have a more elaborate way of building them, and additionally get something that covers the use case of "regex golf" of Vim.
You could see commands you send to Helix/Vim/Kakoune as programs and try to compare the "programming languages" they provide. Kakoune breaks your commands down into smaller elementary steps, i.e. changing selections is one kind of step and operating on text is another. Both can be interleaved arbitrarily and executed one by one with instant feedback. While Vim unnecessarily glues commands into unbreakable operator-motion pairs, that are executed atomically, or lets you shoot a regex at the text (atomically too). There isn't really a good reason for it (other than not knowing any better).
Suppose you need to do something in python, move some files around, make some http queries, build a plot. When is it better to write it in a .py file and run, and when to type line by line in repl? Putting it in a file allows re-using the program, sharing and documenting it, but takes more effort to debug. And if the task is one-off and the whole program is not complex, repl is better because you're seeing the feedback of each step and essentially debugging your code line by line. I argue that text editing commands are simple one-off programs, and you don't tend to save or share most of them. They need a language closer to being in a repl than writing a .py file. And Kakoune approach is more like repl: one language of selections and operators with instant feedback to replace both operator-motion and regex golf of Vim.
And while I agree that we all have our preferences and will use what clicks with us personally at this moment, I also think that objective measure of what's systematically better exists. What you end up using is a matter of opinion and taste, but sometimes what your taste picks is not the best thing objectively (and it's totally fine).
As a heavy user of visual mode in Vim (which can do selections over multiple lines, and you cna have "multiple cursors" via the block select mode) I think that from that standpoint Helix is less dissimilar to Vim than the article is trying to convince us to. However I still found Helix hard to learn tbh and ultimately am staying with Vim :D
I could never do in Vim what I do with multiple selections in Kakoune, I don't believe they're anywhere close. I only used Vim's block selection for indenting code or block commenting stuff. I feel it can only do a pre-set number of things, and you can't really "program" with it as you do with Kakoune's selections. Am I wrong? What are some of the surprising uses of block selection?
I fail to see when multiple selections are useful. Could you give me some examples?
A few examples from the top of my head (for Kakoune).
Swapping things. I really like to select two things and use <a-)> in Kakoune to swap, instead of full sequence of manual select, cut, navigate, paste, select, cut, navigate back, paste.
let x = some + expression;
func_call();
let longName = another * expression;
If you want to swap the expressions the variables are initialized with,
you can select the whole three lines then do s=ll<a-l> to put two cursors over =,
move them right and extend selections to the end of lines.
Then fire <a-)> to 'rotate' selections.
If you can't find some nice anchors (like =) in the file structure
to put your two selections where you want, you can do it manually with a selection register.
Editing table-like data. I'm not opening Python if I want to move around some columns in CSV file or a Markdown table, I can just jump with multiple selections through delimeters and do the job. This works even if the data is not indented for you. My jumping won't be perfect because something that looks like a delimeter may be escaped inside some cell, therefore I'll carefully check my selections at each step and at least will know if it went wrong and I need some smarted approach.
Powerful find-and-replace. Find and replace I've seen before Kakoune was usually either substring match or a regex. One is too weak, the other is too hard to get right.
\newcommand\mathR{\ensuremath{\mathbf R}}
\newcommand\keyword[1]{\emph{#1}}
Some long text \mathR{} with important \keyword{terms}.
Suppose you want to add a prefix to all macros names defined and called in a Latex document.
Macros are defined with \newcommand.
In Kakoune, you multi-select the newcommands, then move cursors right to select mathR and keyword,
save them to search register for later with one key,
hit i and prepend the prefix to both (bonus points for preserving snakeCase).
When we saved mathR and keyword to the search register,
Kakoune remembered it as a regex that matches both (something like \\mathR\b|\\keyword\b).
So now we can multi-select each remaining occurence of \mathR and \keyword in the document,
and edit them too with i.
The result is like this:
\newcommand\prefixMathR{\ensuremath{\mathbf R}}
\newcommand\prefixKeyword[1]{\emph{#1}}
Some long text \prefixMathR{} with important \prefixKeyword{terms}.
Show me how Vim can do this kind of indirect find-and-replace with feedback, where you can discover each new step as you go, check if each step went well and retry if not, and I'll eat my hat. This is a real thing I had to do when I was combining my Latex papers into a thesis, I needed to make sure that macro names between paper do not overlap, but preserve their original meaning. The real text had more variation in how macros are defined, but it wasn't an issue, you discover this kind of things along the way and fix right then, no need to write one regex or a macro to cover everything like in Vim.
Coming up with this took just a few minutes of playing around, and saved me a ton of time. Debugging these editing sequences in Kakoune is cheap, so you can go step by step and see how it works on all selections. Since it's cheap to try, you end up discovering uses for it that you wouldn't even approach with Vim.
You’ve given very appealing use cases for Kakoune (I always hear Blink-182 singing “Tatooine” in my head!), but I’m wondering: is this possible in Helix as well? Specifically number 3 with the multiselection and search.
I'm sure it is. The two translate back and forth pretty well.
I've figured this out in Helix. If some Helix guru knows of a better way, I'm all ears:
\ selected (gg)w — select newcommand
* — add it to the search buffervn — select both instances of newcommand
w — move the cursor over to the next \ character for each command name; — collapse the selections to a single instance of each cursorw — select the names of both commands* — add both command names to the search register.%s<ret> — select the whole file, then find and select within that using the search buffer populated in 8 above.i<right>prefix — enter insert mode, move after the backslashes, and add prefix to all 4 instances<esc>~ — return to Normal mode and toggle case of the previous first char in each name., — return to a single cursor.90% of comments here can be summed up with "I'm more used to Vim model".
And as much as I am Helix user myself, I don't think these models differ enough to (by itself) justify pain of switching + lack of existing support for "Helix mode" in software like shells or IDEs. Yeah, I think kak/hx model is marginally better in practice.
I prefer Helix for many other reasons. Eg. ~6 y ago when I was switching to Kakoune, (neo)Vim still suffered from lags due to syntax highlighting in larger files (was that ever improved?), and generally the features I wanted were often breaking in due to how many of them were coming from plugins.
I really appreciated reading that because I’ve tried multiple times to use Kakoune and foud myself completely lost for one simple reason: muscular memory.
The point about Vim shortcuts is that you quickly forget about their meaning. You just press the keys instinctively.
I switched my keyboard layout recently (from Bépo to Ergol) and Vim was a major painpoint. Not because I didn’t know that the "p" was in a new position. But because my brain as associated the "I want do paste" with a specific finger movement.
Similarly, for a long time, I’ve regretted that there was no easy way to insert at the end of a word. I needed to think "end of the word (e)" then "append (a)" . Cumbersome!
Then, one day, I saw it on someone Cheatsheet : "append at the end of the word: ea".
That’s when I realized that what I only needed wast to learn "ea" instead of separating it. It then became a reflex.
So, yeah, Vim is hard. If I had to start from scratch today, I would probably choose Kak or Hx. But once you master it, Vim is so incredibly efficient that’s ti’s hard to switch to something else.
But once you master it, Vim is so incredibly efficient that’s ti’s hard to switch to something else.
Wouldn't that also hold for Helix – or anything else you can "master", really? Once you master Helix, you become so incredibly efficient ... I assume you won't disagree as you say yourself that new users should pick Kakoune or Helix today. The interesting question would be which one makes you more efficient when given the same amount of time to (configure and) learn from scratch? Which is hard to answer when one is much older and has more users already, I guess.
I wouldn't consider myself a proficient Vim user by any means. Yet I've tried to switch to Helix by aliasing vi to hx (because that's where my muscle memory for "I want to edit this file" begins). And still I keep reopening files in Vim because I want to do (small) things that just don't work with the same muscle-memory keys in hx.
I would say that VIm forces you to do the extra step to put commands into muscle memory. It’s harder but, once you master it, more efficient.
My little experiment with Kakoune was that it seems easier but, then, you didn’t need the muscle memory. You don’t need to trully master it. @krig nailed it in her/his comment: it feels like looking at the keys when typing.
But this is all intuition.
Vim provides a small, finite set of primitives. You can combine these primitives to build more complex commands. The total number of composite commands you can potentially build is infinite. Much like your favourite programming language, where you use a finite set of syntactic elements to assemble one of infinitely many potential programs. This sets Vim apart from Emacs or VSCode where you could technically program a plugin for every shortcut idea you have, but you can only make a fixed,. limited set of such shortcuts.
If you end up using only a fixed, limited in size subset of composite Vim commands, do you really need Vim? You could have a custom keybinding in VSCode for each thing like "ea" that you need. Much like you wouldn't need to code in Python if you only want 15 scripts for pre-defined tasks that you can write once and put on your desktop to double click.
I don't think the number of "theoretically possible" commands should really be an argument here. Or rather: the fact that Vim composes complex actions from smaller operations is an advantage, since those smaller operations and their bindings are much easier to remember than trying to remember 15 arbitrary hotkeys, no?
Regardless, I also find the comparison of Vim and VS Code a bit ... misguided? I use both but for different purposes. While I certainly know it's possible, I wouldn't use Vim as an IDE in larger projects (with dependencies etc.). Same as I wouldn't usually launch VS Code to edit config files in my home directory.
When would you choose to use Vim over VSCode and why?
I didn't intend the number itself to be an argument. I brought it up to show the contrast between what you pay with (learning a small number of pre-defined building blocks) and what you get for it (ability to build many sequences you come up with that were not pre-defined by the author of the building blocks). And to connect it to an actual programming language (infinitely many programs from finite number of basic blocks is one of properties a programming language must have). My point was that if you're only using a fixed set of sequences (which the parent comment implied IMO when they said they have sequences they trained muscle memory for — you won't use muscle memory for a sequence if you're building it from smaller steps on the go), you're neglecting the main feature of Vim that makes it stand out from VSCode and Emacs.
If you're not using this feature, Vim is as good as anything else to you. You may still use it for a personal reason (liking aesthetics or your identity of a hardcore terminal user) or circumstances (having no other editor on a machine), but another, non-modal editor could easily take Vim's place for you if tastes or circumstances were different.
UPD
In Vim, it's admittedly more difficult to make up sequences on the go than in Kakoune. Vim users tend to make up new sequences in somewhat of a disconnection from using them. Like when parent commenter said it took them time to discover "ea", and this has become something they added to their library of things they do automatically. Kakoune/Helix make this so much easier due to interactivity. I can't imagine a Kakoune user being excited to discover something like "ea".
TLDR: Vim brings a new idea to editing, but it's clunky realization gets in the way of users taking full advantage of it — sometimes even them becoming aware of it. Kakoune implements the same idea in a friendlier way, and actually brings you closer to Vim spirit than Vim would.
My point was that if you're only using a fixed set of sequences (which the parent comment implied IMO when they said they have sequences they trained muscle memory for — you won't use muscle memory for a sequence if you're building it from smaller steps on the go), you're neglecting the main feature of Vim that makes it stand out from VSCode and Emacs.
Then I might have just misunderstood your point because I agree insofar as this composition is a very strong feature for Vim. However, I wouldn't go so far as to say "do you really need Vim?", if you don't use it to "it's fullest". Well, do I need it? No. But I also use a pretty limited set of actions, yet I vastly prefer it over something like nano or gedit, for example. Mostly that's dd and p/P, deleting the line with D, changing words with cw or the occasional multi-line edit; I don't even use the hjkl keys to navigate and it always trips me up when vi (not vim) doesn't handle ctrl + arrow keys properly.
So maybe my usage is a perfect example where I would (have) benefit(ed) from Helix. But Vim was always there and easy to reach and by now the few things I regularly use an editor in a terminal for are already ingrained in muscle memory. Don't get me wrong: I like Helix and objectively, I prefer it over Vim. I even symlinked vi to hx on some machines .. but still.
When would you choose to use Vim over VSCode and why?
Vim for:
vimdiff
I know all these modal editors have buffers and panes and tabs and whatever. But for the life of me I can't remember how to use them efficiently and I'm glad I learned qa to exit from vimdiff in a single command at some point ;). Even the LSP features in Helix are mostly a "good syntax highlighting" for me. Which basically brings me to reasons to use VS Code:
I did a patch to solve the 3wd thing, still polishing it but the other maintainers don't have much opinion on this and some people are against it. https://github.com/helix-editor/helix/pull/1570