zellij-org / zellij

A terminal workspace with batteries included
https://zellij.dev
MIT License
22.03k stars 673 forks source link

Feature: custom keybindings #169

Closed imsnif closed 3 years ago

imsnif commented 3 years ago

With the default keybindings of Zellij we have a limitation: we can't define a lot of keybindings that are not behind some sort of super/meta key because we would quickly collide with various operating system and terminal keybindings.

It would be nice to let users define these for themselves though (that way they can control what won't collide with their operating system and other applications).

This issue would involve thinking about a configuration format (probably yaml since we're using it in other places) and a "language" to allow users to define custom keybindings.

Once the above has been decided and worked out, we should be able to load this file from a default location on startup, set up Zellij to respond to those keybindings and ideally also display them in the status bar.

a-kenji commented 3 years ago

I will try to get a rough draft of a custom configuration for keybindings.

imsnif commented 3 years ago

That would be really awesome, @a-kenji ! I would very warmly recommend first making a plan and getting feedback on it before writing any code. Makes sense?

a-kenji commented 3 years ago

Yes, that is a good idea!

a-kenji commented 3 years ago

Configuration Draft:

A first Draft of a possible Configuration file.

Ultimately have three Options that can be triggered by a keybinding:

Action: Remapping Integrated Functionality (New Pane, etc.) Commands: Map a command to a keybinding Macro: Map a sequence of commands, or Actions to a Keybinding

Be able to either map a single key, or a List of Keys. Use a list of actions associated with each mode:

keybindings:
    normal:
        {action: "SwitchToMode(Pane)", keys: "^G"}
    pane:
        {action: "SwitchFocus(Right)", keys: "["L", "Right"]"}

In order to possibly not clutter the keybindings too much optionally allow for creation of a separate definition of commands as a list of named commands and macros as a named list of lists of either commands/actions.

commands:
{name: "show_all", program: "ls", args: ["-a"]}

keybindings:
    command:
         { command: "show_all", keys: "^L" }

is the same as:

keybindings:
    command:
        { command: {program: "ls", args: ["-a"]}, keys: "^L"}

The same goes for Macros:

macros:
 new_show_all:
    {action: "NewPane(Right)"}
    {command "show_all"}

keybindings:
    command:
        {macro: "new_show_all", keys: "^L"}

or

keybindings:
    command:
        {macro: [
        {action: "NewPane(Right)"}
        {command: "show_all"}
        ], keys: "^L"}

I am interested in feedback regarding all of this. Should it be possible to pass a list of keys, or a single key? Should it be possible to reference commands by name? I am also not sure If it is wanted to allow Zellij to run arbitrary commands. Also I think this way makes Configuration much more streamlined: having a command and then having a list of keys associated with that command, but there are merits to doing it differently.

I plan on first just implementing the simple action part. Probably the Macros need much more fleshing out.

Possible further Motivating Questions:

imsnif commented 3 years ago

@a-kenji - good start! Thanks for putting this together. As it happens, I'm doing some work on the default keys and input modes this week and so things may or may not change quite a bit. Do you think it would be possible for you to start with macros and then move on to the rest when the default keybindings are more fleshed out? This would mean allowing users to define macros (which could be one or more actions) and binding them to the root (normal mode) which I think is what most people would like right now. What do you think?

a-kenji commented 3 years ago

Yeah that makes sense! I will work on:

For now and we'll figure the rest out later.

imsnif commented 3 years ago

Very cool. Do feel free to reach out if you'd like input or help.