mjrusso / scoot

Keyboard-driven MacOS cursor actuator
BSD 3-Clause "New" or "Revised" License
333 stars 14 forks source link

Vi shortcut keys #12

Closed shadowgate15 closed 2 years ago

shadowgate15 commented 2 years ago

Would love if we could set it to use vi key shortcuts!

This is a super cool project! Have always wanted to use my keyboard to control the mouse!!!

mjrusso commented 2 years ago

The Mac OS text editing shortcuts and the Emacs ones require modifiers to be held down to activate, which has the benefit of not conflicting with the character sequences (regardless of whether you're in element-based nav mode, or grid-based nav mode).

To support vi bindings, we'll either need a way to enter a special mode that disables sequence entry, or alternatively (my preference, I think) we could add a new way to invoke Scoot. Currently we have these global shortcuts for activating Scoot:

We could add something like:

When Scoot is invoked this way, we wouldn't need to worry about any bindings conflicts. (What should this mode be called? Manual mode? Headless mode? Naming things is hard...)

[Sidenote: all these global keyboard shortcuts really need to be customizable. That's being tracked in #7.]

As for the vi shortcuts themselves, I'm not familiar with the bindings (apart from a passive understanding of what hjkl does). What should all the bindings be (and are there any special expectations around how they should compose together?). It would be really helpful if you (or another interested user) could augment these tables with the equivalent (or equivalent-ish) vi bindings:

Cursor Movement

System Emacs Description
C-p Move cursor up (partial step)
C-n Move cursor down (partial step)
C-b Move cursor left (partial step)
C-f Move cursor right (partial step)
⌥↑ M-a Move cursor up (full step)
⌥↓ M-e Move cursor down (full step)
⌥← M-b Move cursor left (full step)
⌥→ M-f Move cursor right (full step)
⌘↑ M-< Move cursor to top edge of screen
⌘↓ M-> Move cursor to bottom edge of screen
⌘← C-a Move cursor to left edge of screen
⌘→ C-e Move cursor to right edge of screen
⌃L C-l Move cursor to center, and (on repeat) cycle around corners

Clicking

Shortcut Description
Click left mouse button (at current cursor location)
⌘↵ Press and hold left mouse button (once activated, type ⌘↵ again to release)
⇧↵ Double-click left mouse button (at current cursor location)

Scrolling

System Alt Description
⇧↑ ⇧-p Scroll up (at current cursor location)
⇧↓ ⇧-n Scroll down (at current cursor location)
⇧← ⇧-b Scroll left (at current cursor location)
⇧→ ⇧-f Scroll right (at current cursor location)

(p.s. thank you for the kind words about the project!)

shadowgate15 commented 2 years ago

I think adding a way to get into Scoot without entering into one of the 'jump to' functionalities would be nice in general. I know there is a way to hide the grid when in grid view but would be nice to be able to immediately jump into a view that is not cluttered by that.

Perhaps a Normal mode, at least that would be reminiscent of "vi-world", since that is the mode in which you would typically navigate using vi.

Below you can find what I think would make the most sense based on typical vi defaults. Another potential consideration might be to use the leader flow, which is common in vi as well. Most commands could then be prefixed with the assigned leader key, which would then indicate that a command is coming soon.

Cursor Movement

System Emacs Vi Description
C-p j Move cursor up (partial step)
C-n k Move cursor down (partial step)
C-b h Move cursor left (partial step)
C-f l Move cursor right (partial step)
⌥↑ M-a C-j Move cursor up (full step)
⌥↓ M-e C-k Move cursor down (full step)
⌥← M-b C-h Move cursor left (full step)
⌥→ M-f C-l Move cursor right (full step)
⌘↑ M-< ⇧-j Move cursor to top edge of screen
⌘↓ M-> ⇧-k Move cursor to bottom edge of screen
⌘← C-a ⇧-h Move cursor to left edge of screen
⌘→ C-e ⇧-l Move cursor to right edge of screen
⌃L C-l ⇧-m Move cursor to center, and (on repeat) cycle around corners

Clicking

Don't think this needs to be changed.

Shortcut Description
Click left mouse button (at current cursor location)
⌘↵ Press and hold left mouse button (once activated, type ⌘↵ again to release)
⇧↵ Double-click left mouse button (at current cursor location)

Scrolling

System Alt Vi Description
⇧↑ ⇧-p C-b Scroll up (at current cursor location)
⇧↓ ⇧-n C-f Scroll down (at current cursor location)
⇧← ⇧-b C-i Scroll left (at current cursor location)
⇧→ ⇧-f C-a Scroll right (at current cursor location)
shadowgate15 commented 2 years ago

I would attempt to help develop but I currently don't have the time to and don't have a very good grasp on Swift.

niftylettuce commented 2 years ago

@mjrusso I tried to sponsor you on GitHub but saw you didn't have that set up yet - would love to see vi bindings/shortcuts here too.

mjrusso commented 2 years ago

I've implemented a new mode -- "freestyle mode" -- which doesn't bring up the grid or element views. (See b884a3d669f3e0b893343a91edd1b3fa58730e36. Not in main yet because it needs to be documented in the README.) Currently invoked with ⇧⌘L.

Below you can find what I think would make the most sense based on typical vi defaults.

Thanks for filling in those tables. I've started porting them over, but ran into a few conflicts with existing shortcuts.

In particular, this proposed cursor movement shortcut conflicts with an Emacs/system shortcut:

And all of the proposed scrolling shortcuts conflict (with the exception of C-i | Scroll left (at current cursor location)).

Are there any alternatives to these conflicting shortcuts that would still make sense for a vi user?

If not, seems like we'll need an explicit setting for explicitly enabling/disabling vi support. I was hoping to avoid this, but it might be inevitable.

mjrusso commented 2 years ago

change up the way that the grid/element shortcuts are generated to not include the bound keys 'hjkl'. In vi ; is commonly used at the start of shortcuts when letters run out.

Ah. This approach didn't occur to me before, but it definitely seems like an elegant way to also get vi support in to the element-based nav and grid-based nav modes.

For this, though, I'd definitely only want it enabled for users that explicitly want to opt in to vi bindings.

So: sounds like adding an explicit setting for enabling/disable vi support is the way to go.

mjrusso commented 2 years ago

@mjrusso I tried to sponsor you on GitHub but saw you didn't have that set up yet - would love to see vi bindings/shortcuts here too.

Thanks @niftylettuce :) I'm not planning on setting up sponsorship at the moment, but I appreciate the sentiment!

shadowgate15 commented 2 years ago

Yeah. I would probably have an option for either/or. I think most users who would choose to use vi shortcuts would prefer not messing with eMacs at all and probably vice versa.

mjrusso commented 2 years ago

This is shaping up pretty nicely. Major outstanding work is updating the documentation (for both the vi bindings and freestyle mode); once that's ready I'll cut a release.

(I punted the settings UI, as that's a can of worms I'm not ready to open right now. For now, you'll need to do a defaults write to turn on vi bindings.)

mjrusso commented 2 years ago

Docs are updated, and I've landed the changes. (I'll close this issue when I cut a new release.)

mjrusso commented 2 years ago

New release is out! Give it a shot and let me know what you think: https://github.com/mjrusso/scoot/releases/tag/v0.8