Possible UX improvement: Add option to make `smart_up`/`smart_down` take indentation into account
Opened this issue · 4 comments
Hi! I've been using Reform for a few days, and I like it! But I think smart_up
/smart_down
's behavior could be slightly improved.
Currently, this happens:
(the |
represents the cursor, the arrow shows how it moved after smart_down
)
def foo():
bar blah blah
baz bla|h blah
:
.---------'
↓
| boo blah blah
bee blah blah
But I'd prefer it to work like this:
def foo():
bar blah blah
baz bla|h blah
:
.-----'
↓
|boo blah blah
bee blah blah
To put that in words, smart_down
moves the cursor to the very beginning of the line ("hardbol"), but when I'm moving through blocks, I would usually prefer it to land where the actual text starts, right before boo
– basically, take indentation into account. This could be done by an argument:
{"keys": [...], "command": "smart_down", "args": {"jump_to_indent": true}}
or something similar.
My current workaround (using chain
from Chain of Command
to sequence commands) is replacing:
{"keys": [...], "command": "smart_down"}
with:
{ "keys": [...], "command": "chain", "args": {
"commands": [
["move_to", {"extend": false, "to": "hardbol"}], // had issues without this
["smart_down", {}],
["move_to", {"extend": false, "to": "hardbol"}], // make sure we're at hardbol
["move_to", {"extend": false, "to": "bol"}], // toggles position between harbol and bol. We're at hardbol, so it'll take us to bol
]}
},
This automatically places the cursor at indent after smart_up
makes the jump.
However, having an option to customize this behavior without resorting to hacks would be nice! Also, I think a better experience out of the box would be to respect the indentation by default, and possibly have a "jump_to_hardbol" option. Let me know what you think!
The full bindings are here:
// smart_up
{ "keys": ["alt+up"], "command": "chain", "args": {
"commands": [
["move_to", {"extend": false, "to": "hardbol"}], // see comment at the bottom for explanation
["smart_up", {}],
["move_to", {"extend": false, "to": "hardbol"}],
["move_to", {"extend": false, "to": "bol"}],
]}
},
// smart_down
{ "keys": ["alt+down"], "command": "chain", "args": {
"commands": [
["move_to", {"extend": false, "to": "hardbol"}],
["smart_down", {}],
["move_to", {"extend": false, "to": "bol"}],
]}
},
// Why does smart_up need that additional line? It works like this:
// if we're not at hardbol on the first line of the block,
// `smart_up`will move us there. But then the next two commands move us
// back to bol. So the next invocation of this sequence will move us to
// hardbol and back again. We'd be stuck! But with this line, we're
// already at hardbol when `smart_up` runs, so it works normally.
The version of smart_down I originally posted has ["move_to", {"extend": false, "to": "hardbol"}], // had issues without this
, but this line isn't necessary – I just copied the wrong one and then changed the command name.
Hello, thanks for your interest.
Maybe I don't feel this need because after this commands I mostly use line or block selection or deletion. And if you want to edit something then it's just Ctrl+Right. What's your use case?
I mostly use it for quick navigation – move a few blocks up/down, edit something, move back down.
BTW, what's your preferred way of selecting blocks? I couldn't find a Reform command for that.
It's select_scope_up/select_scope_down
, sometimes select_scope_words/expand_next_word
, see README. Also, delete_block
not selection, but one of my favorite commands.