NeoVim Navigation Experiments
I've used leap.nvim as my primary mode of hopping around in Neovim, for a while now, where I'd define hopping as roughly "getting to some arbitrary point on the page that doesn't correspond to some more convenient motion in Vim that I know." The logic behind the plugin is compelling: We type two letters, similar to how we'd start a search, and then we choose some last letter for disambiguation, and the idea is that we can see the last letter while we're typing the previous letters so that there's not a big delay in mentally processing the letter that we want to jump to. However, this is just the hypothesis, and I've always sort of wondered if things really work out this way.
Some questions:
- Even though there's a bit of movement involved in grabbing the mouse and then putting hands back on the keyboard, how much time does that actually cost? Maybe it's actually tiny and we should all just be using the mouse for optimal time efficiency (setting aside things like ergonomics and personal preferences).
- In my experience with Leap, the philosophy doesn't fully pan out: There's always a bit of hesitation in recognizing and typing that last character ( maybe other people are better at this, but I suspect that visual recognition and reaction just takes a little time). This still doesn't necessarily mean that Leap.vim is slower than some other method; it's very possible that the overhead of that reaction time is justified by not having to change modes or having that single key for disambiguation that potentially saves you from typing multiple other keys.
- How much overhead is there just a good ol' search? With default mappings, we
have to type either
?or/and then some search and then<enter>. Definitely in terms of pure overhead, it's more keys than Leap's approach, but the workflow is more deterministic: We can potentially know all of the keys that we'll need to type in advance of doing the search.
To answer these questions, I set up a little experiment.
The Experiment
For someone like me who's got a lot of experience editing, the variation between these approaches is likely to be quite small, and without having someone record over your shoulder it's pretty hard to time precisely when you start and when you finish the navigation. So, what I did was to set my phone in a fixed place (to the right of my mousepad) and then use the following sequence:
- Start the timer
- Move hands to rest position on the keyboard
- Perform the navigation (returning hands to the rest position for mouse navigations)
- Stop the timer
This means that most of the time in my results will actually be the time spent moving to my phone and back, but we should be able to see which method is fastest based on the variations in these results.
Results
Each recording was done by jumping to locations in a different blog post that I haven't published yet. Here were the results:
Jump to: "Most abstractions"
- Mouse: 3.80s
- Leap: 3.2s
- Search: 2.8s <-- This is quite a bit faster (prefer typing more context)
Jump to: "Use of multiple languages"
- Mouse: 4.3s
- Leap: 3.0s
- Search: 2.94s
Jump to: "being messier"
- Mouse: 4.6s
- Leap: 2.74s
- Search: 2.13s
Jump down across the page to "early-stage [p]rototypes"
- Mouse: 4.39s
- Leap: 3.86s
- Search: 3.06s <-- Note that I fucked this one up a few times, but I think I'm just trying to type too fast.
Jump up across the page to "Quarantining complexity"
- Mouse: 4.85s
- Leap: 3.2s
- Search: 2.59s
Overall averages
- Mouse average: 4.388 seconds
- Leap average: 3.2 seconds
- Search average: 2.704 seconds
No Navigation Averages
I think the results will be more compelling if I correct for the time that it took me to start and stop the timer, so I recorded a few of those to get an average:
- 2.19s
- 2.19s
- 2.47s
- 2.47s
- 2.59s
- 2.39s
These average out to 2.383333 seconds.
Results
Our adjusted averages from above are:
- Mouse average: 2.004667 seconds
- Leap average: 0.816667 seconds
- Search average: 0.320667 seconds
Conclusion
Holy shit, I did not expect this result! For one thing, using the mouse actually is slow as fuck! But, actually typing out searches is like twice as fast as Leap is, too!
Overall time savings
What would this look like for our overall time editing efficiency? I think that, for the purposes of this post, I'm going to leave that question mostly open, because figuring out how much navigating I do on average while working on something is really hard. Probably the thing to do here would be to actually build a plugin for my editor to record these metrics (which would also provide much better data for this experiment). But, to take a stab at some rough brackets: I bet these generic hops happen maybe on average about ten times per minute for me during intensive editing? I think that once per second is definitely on the high end, and once per minute is definitely on the low end.
So, that means that I currently spend: (0.81 < time spent ?= 8.1 < 48.6) seconds navigating per minute.
So, my time saved per minute:
- Mouse: (1.51 < time saved ?= 15.1 < 90.6) seconds
- Leap: (0.49 < time saved ?= 4.9 < 29.4) seconds
Multiplying out for a year of editing (figuring roughly 15 hours of intensive editing per week):
- Mouse: (0.817917 < time saved ?= 8.17917 < 49.07502) days
- Leap: (0.265416 < time saved ?= 2.65416 < 15.925) days
As per usual, the numbers get pretty bananas when you multiply out for the year which is why, over time, working on small corrections is compelling.
Other thoughts
I think this conclusion underscores a big truth about time efficiency in general: Repeatable (deterministic) workflows that require more actions still end up being much faster than non-deterministic workflows that require fewer actions. If this doesn't match with your intuition about how things work, then go watch some professional cup stacking videos. We humans are quite good at making repeatable workflows fast over time. In my case, it also probably helps a lot that I've been practicing typing over the course of the last year, so this mode of navigation is already supported by another skill that I'm quite good at.
This is also essentially why AI workflows don't work well. The intuition is: "Completing this task takes N actions, and AI can perform 90% of those actions on its own, so it'll make me like 10x faster", but the reality is "Completing this task takes N actions, and Y of those actions are repeatable. The repeatable actions will actually take a very small percentage of the overall time spent performing the task, while the non-repeatable actions will take most of the time. AI introduces uncertainty, which is another way of saying that it takes repeatable actions and makes them non-repeatable (in the course of completing some work), but it also does this very quickly. So, the end result is that very short-term outcomes improve ever so slightly, while medium and long-term outcomes are demolished." And, the reason that AI removes repeatability is that repeatability is a side-effect of comprehension and skill. This is also just a specific subset of tech debt.
Notes
It's worth noting that I made many more typos when I was doing the search approach to navigation. I mostly chalked this up to me trying to type really fast, since this is usually not an issue for me. Just slowing down a bit got better results.
It's also worth considering how these results would be affected by workflows that don't require you to return your hand back to the rest position on the keyboard when using the mouse. This is probably the exception for me, but it would apply if, for example, I were reviewing some code and I was just clicking on a point because I wanted to center the view there, or if I'm just scrolling around.