Sublime Forum

Remapping Keys to use hjkl to replace arrow keys

#1

Is there an easy way to substitute hjkl for the arrow keys in ST3? I have managed to remap them using the following, but all the other key combinations that involve arrow keys do not work. Do I need to remap all of them or is there a simpler way?

/* Disable arrow keys */ { "keys": "right" ], "command": "pass", "context": { "key": "setting.command_mode", "operand": false } ] }, { "keys": "left" ], "command": "pass", "context": { "key": "setting.command_mode", "operand": false } ] }, { "keys": "up" ], "command": "pass", "context": { "key": "setting.command_mode", "operand": false } ] }, { "keys": "down" ], "command": "pass", "context": { "key": "setting.command_mode", "operand": false } ] }, /* Remap up/down/left/right to h/j/k/l */ { "keys": "super+h" ], "command": "move", "args": { "by": "characters", "forward": false } }, { "keys": "super+j" ], "command": "move", "args": { "by": "lines", "forward": true } }, { "keys": "super+k" ], "command": "move", "args": { "by": "lines", "forward": false } }, { "keys": "super+l" ], "command": "move", "args": { "by": "characters", "forward": true } }

0 Likes

#2

I think the direct answer to your question would be a no. You will have to remap ALL possibilities.

I have personally remap quite a bit of frequently used operation and replace the movement part to alt+h/j/k/l (similar to your attempt), which you already know how. eg.

    // ** normal non-vintageous operations
    // arrow keys to jkhl
    { "keys": "alt+h"], "command": "move", "args": {"by": "characters", "forward": false} },
    { "keys": "alt+l"], "command": "move", "args": {"by": "characters", "forward": true} },
    { "keys": "alt+k"], "command": "move", "args": {"by": "lines", "forward": false} },
    { "keys": "alt+j"], "command": "move", "args": {"by": "lines", "forward": true} },
    // other combinations that uses up down left right
    { "keys": "shift+alt+h"], "command": "move", "args": {"by": "characters", "forward": false, "extend": true} },
    { "keys": "shift+alt+l"], "command": "move", "args": {"by": "characters", "forward": true, "extend": true} },
    { "keys": "shift+alt+k"], "command": "move", "args": {"by": "lines", "forward": false, "extend": true} },
    { "keys": "shift+alt+j"], "command": "move", "args": {"by": "lines", "forward": true, "extend": true} },
... and lots more

You can see this gets long, and potentially you will have lots of tricky keymaps.

One thing I have found useful is that when you are choosing item in command palette, autocomplete or side bars:

    // ** in command palette etc.
    // these two allows me to move up and down in overlay 
    { "keys": "alt+j"], "command": "move", "args": {"by": "lines", "forward": true}, "context":
        { "key": "overlay_visible", "operator": "equal", "operand": true} ] },
    { "keys": "alt+k"], "command": "move", "args": {"by": "lines", "forward": false}, "context":
        { "key": "overlay_visible", "operator": "equal", "operand": true} ] },

    { "keys": "h"], "command": "move", "args": {"by": "characters", "forward": false}, "context":
         {"key": "control", "operand": "sidebar_tree"} ] },
    { "keys": "j"], "command": "move", "args": {"by": "lines", "forward": true}, "context":
         {"key": "control", "operand": "sidebar_tree"} ] },
    { "keys": "k"], "command": "move", "args": {"by": "lines", "forward": false}, "context":
         {"key": "control", "operand": "sidebar_tree"} ] },
    { "keys": "l"], "command": "move", "args": {"by": "characters", "forward": true}, "context":
         {"key": "control", "operand": "sidebar_tree"} ] },

I didn’t understand why this was designed like this before, but now I can see the bigger issue if you are allowed to do that, because it will become much harder to have clear logic of which key overwrite other keys. The current sublime keymap overwriting mechanism is clear.

One other thing you can do though, is to use system level mapping, that way all the applications will not even know that you are using other keys instead of arrow key. There may have some problems in that I am not sure.

0 Likes

#3

Thanks. Really appreciate the comprehensive reply. Using the arrow keys is the big speed-bump in my workflow at the moment.

If you have all the arrow-related re-mappings in one place, would you mind posting them in full? Would be good to see them.

0 Likes

#4

These are the ones I found in my keymap dealing with normal view editing. Looks like it’s not really complete, I might have removed some because it’s either hard to press or used up too many combinations. Note I didn’t make it entirely like VIM. eg. I change home and end to ,/. (or <>). Also n and p (from emacs?) to o and p, which supposed for page up and down. Becareful making these keys complete would overwrite many of the useful default keys, same case if I use d and u. You can see the darwback clearly… lots of awkward combos. The worse is that it’s not perfect of either world, not real vim and not real traditional sublime way.

    // ** normal non-vintageous operations
    // Home and End to < and >
    { "keys": "alt+,"], "command": "move_to", "args": {"to": "bol", "extend": false} },
    { "keys": "alt+."], "command": "move_to", "args": {"to": "eol", "extend": false} },
    { "keys": "shift+alt+,"], "command": "move_to", "args": {"to": "bol", "extend": true} },
    { "keys": "shift+alt+."], "command": "move_to", "args": {"to": "eol", "extend": true} },
    { "keys": "ctrl+alt+,"], "command": "move_to", "args": {"to": "bof", "extend": false} },
    { "keys": "ctrl+alt+."], "command": "move_to", "args": {"to": "eof", "extend": false} },
    { "keys": "ctrl+shift+alt+,"], "command": "move_to", "args": {"to": "bof", "extend": true} },
    { "keys": "ctrl+shift+alt+."], "command": "move_to", "args": {"to": "eof", "extend": true} },
    // PageUp and PageDown to p and o
    { "keys": "alt+p"], "command": "move", "args": {"by": "pages", "forward": false} },
    { "keys": "alt+o"], "command": "move", "args": {"by": "pages", "forward": true} },
    // arrow keys to jkhl
    { "keys": "alt+h"], "command": "move", "args": {"by": "characters", "forward": false} },
    { "keys": "alt+l"], "command": "move", "args": {"by": "characters", "forward": true} },
    { "keys": "alt+k"], "command": "move", "args": {"by": "lines", "forward": false} },
    { "keys": "alt+j"], "command": "move", "args": {"by": "lines", "forward": true} },
    { "keys": "shift+alt+h"], "command": "move", "args": {"by": "characters", "forward": false, "extend": true} },
    { "keys": "shift+alt+l"], "command": "move", "args": {"by": "characters", "forward": true, "extend": true} },
    { "keys": "shift+alt+k"], "command": "move", "args": {"by": "lines", "forward": false, "extend": true} },
    { "keys": "shift+alt+j"], "command": "move", "args": {"by": "lines", "forward": true, "extend": true} },
    // scroll
    { "keys": "ctrl+alt+k"], "command": "scroll_lines", "args": {"amount": 1.0 } },
    { "keys": "ctrl+alt+j"], "command": "scroll_lines", "args": {"amount": -1.0 } },
    // move by words
    { "keys": "ctrl+alt+h"], "command": "move", "args": {"by": "words", "forward": false} },
    { "keys": "ctrl+alt+l"], "command": "move", "args": {"by": "word_ends", "forward": true} },
    { "keys": "ctrl+shift+alt+h"], "command": "move", "args": {"by": "words", "forward": false, "extend": true} },
    { "keys": "ctrl+shift+alt+l"], "command": "move", "args": {"by": "word_ends", "forward": true, "extend": true} },
    { "keys": "alt+b"], "command": "move", "args": {"by": "words", "forward": false}, "context": {"key": "panel_has_focus", "operand": false}] },
    { "keys": "alt+w"], "command": "move", "args": {"by": "words", "forward": true}, "context": {"key": "panel_has_focus", "operand": false}] },
    { "keys": "shift+alt+b"], "command": "move", "args": {"by": "words", "forward": false, "extend": true} },
    { "keys": "shift+alt+w"], "command": "move", "args": {"by": "words", "forward": true, "extend": true} },
    // move lines up and down
    { "keys": "ctrl+shift+alt+k"], "command": "swap_line_up" },
    { "keys": "ctrl+shift+alt+j"], "command": "swap_line_down" },

    // a special one: find next, instead of reaching f3
    { "keys": "alt+n"], "command": "find_next" },
    { "keys": "shift+alt+n"], "command": "find_prev" },

    // simulating zt and zb in vim, need (custom) show_at_top command
    { "keys": "ctrl+k", "ctrl+t"], "command": "show_at_top" },
    { "keys": "ctrl+k", "ctrl+c"], "command": "show_at_center" },

Also in a related topic, I use some more move by paragraph type of keys that speeds up navigation. Here are what I did.

    // use package Move By Symbol ... 
    { "keys": "ctrl+alt+"], "command": "move_by_symbols", "args": {"forward": false}},
    { "keys": "ctrl+alt+]"], "command": "move_by_symbols", "args": {"forward": true}},

    { "keys": "alt+up"], "command": "move", "args": {"by": "stops", "empty_line": true, "forward": false} },
    { "keys": "alt+down"], "command": "move", "args": {"by": "stops", "empty_line": true, "forward": true} },
    { "keys": "alt+"], "command": "move", "args": {"by": "stops", "empty_line": true, "forward": false} },
    { "keys": "alt+]"], "command": "move", "args": {"by": "stops", "empty_line": true, "forward": true} },

    // this set is the same as previous, but center the view after jump
    { "keys": "super+"], 
        "command": "run_multiple",
        "args": {"commands": 
            {"command": "move", "args": {"by": "stops", "empty_line": true, "forward": false}},
            {"command": "show_at_center"}
            ] } },
    { "keys": "super+]"], 
        "command": "run_multiple",
        "args": {"commands": 
            {"command": "move", "args": {"by": "stops", "empty_line": true, "forward": true}},
            {"command": "show_at_center"}
            ] } },

    { "keys": "shift+alt+up"], "command": "move", "args": {"by": "stops", "empty_line": true, "forward": false, "extend": true} },
    { "keys": "shift+alt+down"], "command": "move", "args": {"by": "stops", "empty_line": true, "forward": true, "extend": true} },
    { "keys": "shift+alt+"], "command": "move", "args": {"by": "stops", "empty_line": true, "forward": false, "extend": true} },
    { "keys": "shift+alt+]"], "command": "move", "args": {"by": "stops", "empty_line": true, "forward": true, "extend": true} },

Hope you or someone can find a better way. Again, maybe I should get used to Vintageous and learn switching modes instead of staying in the middle of two worlds.

0 Likes

#5

There’s a plugin that allow modal bindings if that’s of interest:
sublimetext.com/forum/viewt … 25&start=0

I had used it to try and get hjkl bindings in without having to remap everything. It didn’t work that well, honestly.

Alex

Edit: My attempt looked like this: gist.github.com/alehandrof/5183332

0 Likes