vim: subword motions
Add subword motions to vim, inspired by nvim-spider, CamelCaseMotion.
Release Notes:
- Added subword motions to vim
@romgrk I think we could go one of two ways here:
- Add the actions and don't bind them to keys, but document that on zed.dev/vim
- Re-use the existing actions for this, and add a setting
{"vim": {"use_subword_boundaries": true}}(similar to the recently added"use_multiline_find")
In typical use do you use both subword and whole-word motions, or do you tend to use just one or the other?
@romgrk Thanks for taking a pass at this, happy to work together to get it over the line if you'd like https://calendly.com/conradirwin/pairing.
It seems like there's also (possibly?) some refactoring we could do to clarify why we sometimes adjust the point before calling preceding_boundaries, and sometimes we don't; but it may just be "that's what makes the tests work" :D.
I think my prefered solution would be to document the commands but let the user map them manually. This stems from my own usage, where I mix and match motions between word & subword. E.g. in normal mode I only use subword motions, but in operator-pending mode I use w for "next-subword-end" and e for "next-word-end", because it gives me access to both the word & subword motion. Very convenient because operating on the first subword or the full word are both common operations. There is also a history behind that, because vim's native w motion is inconsistent: in normal mode it acts as "next-word-start", and in operator mode as "next-word-end" unless the cursor is on a whitespace, in which case it acts as "next-word-start".
why we sometimes adjust the point before calling preceding_boundaries
Sometimes we need to start scanning at n+1 characters, otherwise starting at n yields n due to how boundary detection logic works: in the boundary predicate, we don't have access to the current position, only to the |left, right| characters. It could be easier to add an incremental counter to the surrounding lexical scope and avoid matching when it's 0, but I copied the logic from one of the existing word/subword motions in the codebase so I kept the same pattern for consistency.
Sometimes we also need to move the point post-match, because the find-boundary function provide |left, right| which are sometimes look-ahead or look-behind (depending on the direction we're going), but the boundary detection logic might require looking in the direction that's not available, thus we have no choice but to match after the fact and backtrack. I think this could have an edge-case if matching at the EOF.
happy to work together to get it over the line if you'd like https://calendly.com/conradirwin/pairing
I'm more comfortable with an async/written workflow, but I'll keep that in mind if needed.
May I suggest putting the suggestion key map but in a comment? That would help discover Zed features
All done here, this is ready for review.
Ok, now it should be fixed.
Thanks for this!