zed
zed copied to clipboard
helix: WIP
Release Notes:
- WIP: add helix mode (#4642)
This is nowhere near completion as of now, but i am interested in continuing work on it. Discussion is very welcome.
Current state:
- [ ] Basic normal mode movements: acceptable state, but not exactly like helix still
- [ ] Setting: Still starts in vim normal mode on startup
TODO (not exhaustive):
- [ ] Fix word movements
- [ ] Fix startup mode
- [ ] Setup keymap
- [ ] Implement missing functions
Since i don't have a lot of time, this will take quite some time to finish i think. If anyone want's to tackle one of the todos, we can discuss it here.
- N/A
Hey @blufony!
Thank you for sending this and getting the conversation going!
I want to figure out how we can support Helix/Kakaoune without a large upfront build or an ongoing maintenance burden.
From what I understand the primary differences from vim are:
- A focus on selection management
- No visual mode, but has selection mode
- Streamlined keymap
As they have many more similarities than differences (particularly as vim in zed has multi-cursor and LSP/tree-sitter support already), I wonder if there's a path forward where we actually do use the same code for both.
How I'd imagine this looking:
- We add a Helix keymap.
- Helix mode enables vim mode and the helix keymap (instead of the vim keymap).
- We add any Helix-specific actions to the vim crate directly.
It seems like the first helix-specific action we might need is a way to toggle selection mode. After that, I'm curious how much rust code is needed to make the top 75% of Helix keybindings work with the actions we already have within Zed.
Looking through https://docs.helix-editor.com/keymap.html, it seems like you could already get on-par with the vim crate for Movement, Changes, select mode, view mode, goto mode and match mode with just the keybindings file. (And most of the improvements needed for Helix - e.g. registers on paste, record/replay - are also needed for Vim, so we'd get a double-whammy).
Looking through selection manipulation, this is where it might get more fun: s is equivalent to running a search-within-range and selecting all, but would need some code to support to tie things together. k has no equivalent in vim or zed. And a bunch of other things like ;, _ are going to need new actions to work; but it would be nice to let people who are using vim (or even default) keymaps use these actions.
The main thing that would make this less great is if Helix has a large number of subtle differences from vim in things like the definition of word/WORD. I'm not sure that this is the care though. Are there other downsides with this path that you foresee?
What I'm hoping to find is a way forward where we can get to a point that people switching from Helix feel at home, but without needing to write too much code.
If we get far enough down this path to realize that there is a large amount of Helix-specific code that is not needed for Vim mode, we could try and factor the crates out; but I don't want to jump to something like a modal_editing layer before we need it.
it would be nice to let people who are using vim (or even default) keymaps use these actions.
This is a really good point. While I appreciate Helix's opinionated, batteries-included (ymmv) approach, I think I prefer just a bunch of commands/modes to choose from.
Also, while I imagine this could come later, Helix has some shell command interaction that operates on multi-selections that would be real nice to have regardless:
:insert-output - Run shell command, inserting output before each selection.
:append-output - Run shell command, appending output after each selection.
:pipe - Pipe each selection to the shell command.
:pipe-to - Pipe each selection to the shell command, ignoring output.
Similarly, "jump" functionality is builtin in Helix. Adding this in Zed would both make for parity with Helix and knockout general jump functionality requested for Zed.
improvements needed for Helix - e.g. registers on paste, record/replay - are also needed for Vim, so we'd get a double-whammy).
I only switched to Helix for a few weeks awhile back, but Helix registers seemed quite central to its operations. I've definitely felt the missing registers in Zed vim so would be great to have that for both.
Small nit:
No visual mode, but has selection mode
"Selection mode" is normal mode, normal mode in helix/kakoune is basically vim's visual mode, where the selection is always atleast 1 character.
So
It seems like the first helix-specific action we might need is a way to toggle selection mod
You could always start in Vim's visual...maybe? In the UI you could show it as 'normal' mode. It's not as clean as can be tho.
I use helix/kakoune for almost everything, but maybe for this implementation, looking at Dance for VSCode might be a better inspiration?
Thanks for all of your input, that really helps me out! Some comments from my side:
- We add any Helix-specific actions to the vim crate directly.
Sounds like a good plan to me, less code duplication for sure.
Are there other downsides with this path that you foresee?
I think naming could be tricky. My suggestion for that would be:
- Rename the vim crate to
modal_editingor something similar - Export any non vim / helix specific actions to editor or where they fit best
- Document all actions used by vim / helix mode, so that users can configure keybindings to their liking without having to search far for the action names
Other than that i don't think there should be many problems in definitions like what a word is, but a lot of the movements in helix cause the object to be selected and there are quite a few movement actions.
- No visual mode, but has selection mode
Actually selection mode works basically the same way as vim visual mode. It's the normal mode that's different in that you always have a selection and every 'movement' you do in helix results in a selection.
Helix registers seemed quite central to its operations
Those function basically the same in vim and helix and they aren't even implemented for vim mode either. So i would for now not handle this here, as i feel the system clipboard works fine as a simulation for now. Might change my opinion on that later on though.
You could always start in Vim's visual...maybe?
As i said before, vim visual mode extends selections and helix normal mode in general selects around the current movement, discarding the previous selection.
So for now i would first try to get the basics of helix normal mode working from the inside of the vim crate. Thanks again for all your input!
🎉 If you'd like me to pair with you for a bit on this: https://calendly.com/conradirwin/pairing
I hadn't appreciated the distinction between "move" and "extend selection" for the motion commands, but makes sense (and using different actions for that behavior seems right).
Some parts of the code for vim crate don't feel "great" yet either, so if you're running into issues with how the code is structured, I'm excited to make it better (in other words, refactoring welcome!).
I've been daily driving helix for about about a year and the worst thing about it lately is it's been holding me back from using Zed. I'd love to help make this happen if there is room for collaboration!
Sorry for the long silence, i've been sick for the past 3 weeks and there is no end in sight at the moment, so i have even less free time i can use for this project than i already did. The current state has normal character movement (left, right, up, down) and forward word movements are also mostly working. I also played around with a setting, but i don't the current way i did it is the best way of doing it, that wasn't really a priority though for now.
I'd love to help make this happen if there is room for collaboration!
Yeah there sure i would like to collaborate! As i stated i probably won't really have much time and energy to put into this at the moment, so some help would be very much appreciated :)
No worries! And sorry to hear what you're going through.
Overall I like the approach you're taking (and although it's not ideal, there's something super clear about "helix_mode": true).
I'd love to get this to a point where we can merge it (linters/tests passing), but there is no hurry at all from my side.
If anyone is interested in submitting PRs that target this branch to tidy things up and keep them moving, I'll try and stay on top of them.
I have started working on this, got some more bindings to work (most of word movement and find movements) branch: https://github.com/maan2003/zed/commits/ma/hx/
I am just changing vim code in place, breaking the vim functionality. Before merging I will refactor it.
current state: https://github.com/maan2003/zed/blob/ma/hx/crates/vim/src/HX_TODO.md
UPDATE: I am traveling till 22nd, this work is paused till then.
@maan2003 great!
When you're ready to talk through what it would look like to get this merged, you can book time here https://calendly.com/conradirwin/pairing.
@COCPORN has been working on an alternative implementation here: https://github.com/COCPORN/zed/blob/feature/helix-bindings/crates/helix/src/helix.rs.
I'm going to close this for now, but either of these approaches is still something I'd be excited to help get merged.