abo-abo / lispy

Short and sweet LISP editing
http://oremacs.com/lispy/
1.2k stars 130 forks source link

Lispy movement and command inconsitencies #628

Open markgdawson opened 2 years ago

markgdawson commented 2 years ago

Currently in lispy I feel that there are two modes of operation, one when the region is active and one when the point is special and the region is inactive. I'll call these region-mode and point-mode for now. There are a small number of significant differences in how these two modes operate, which I feel introduces some unnecessary cognitive overhead.

One of the big difference is in movement, I might be in this position in special mode (which is typically the default mode of operation):

(if some-var
      |(fn-call)
    some-other-var)

In region mode (i.e. highlighting (fn-call)), j and k move to the atoms around it. I feel this is the behaviour I would like/expect. In point-mode it does nothing. To move to some-var I need to switch mode before I do this.

Conversely, if I'm in region-mode I need to switch back to point-mode to slurp/barf (e.g. some-other-var into the fn-call form). So in this case the key binding inconsistencies between the two modes are making me switch.

I think it would be much more natural (for me?) to have one mental context in which to work, and consistent key behaviour regardless of mode.

If we wanted to do this (maybe as a user mode), I can see two approaches we could take.

One is to auto-switch between point-mode and region-modes in movement commands so that movement in the two modes is always consistent. For example, switch to region selection if we're moving to something that is an atom and switch back to point mode if it's a form.

Alternatively, movement commands could always switch to region-selection mode. Or users who choose this option could give up point-only mode and always operate in region selection mode (that would be fine for me I think). Or we could have both (i.e. by default move immediately into region selection mode, but also preserve the behaviour with region off if point is special).

Then we'd need to fix the keys so that they're consistent. I think < and > are the biggest culprits here. One option that would work really well on english keyboards would be to move the slurp/barf to , and . (and move lispy-repeat somewhere else) and keep grow/shrink on < and >. The nice thing is that now we can support grow/shrink without needing to be in a region first.

Some operations might not work in all cases (e.g. eval on something that isn't a form clearly has no meaning) - but I think overall this would be a very nice experience.

Happy to put in the work to start implementing this, if this is something that's of interested in lispy core. But interested on thoughts on how we could go about implementing this and how it should behave.