Suor/sublime-reform

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.

Suor commented

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.

Suor commented

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.