Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Name the config keybindings that are used in every mode, to simplify the process of remapping them #527

Closed
ameliabradley opened this issue May 20, 2021 · 4 comments
Labels
config Improvements to the configuration system enhancement New feature or request

Comments

@ameliabradley
Copy link

ameliabradley commented May 20, 2021

The process of remapping a key is too "in the weeds".

As a practical example, ctrl+r is used by Zellij for pane resizing. Because ctrl+r is already bound by bash's "reverse-i-search" and vim's "redo", I went to update the config file to replace the ctrl+r keybinding with ctrl+y.

This required creating a config.yaml file, where I tripped up three times:

  • First mistake: Not unbinding the default key
  • Second mistake: Not listing out every mode
  • Third mistake: Not getting every SwitchToMode correct

My config file now:

keybinds:
    unbind: [ Ctrl: 'r']
    normal:
        - action: [SwitchToMode: Resize,]
          key: [Ctrl: 'y',]
    locked:
        - action: [SwitchToMode: Resize,]
          key: [Ctrl: 'y',]
    pane:
        - action: [SwitchToMode: Resize,]
          key: [Ctrl: 'y',]
    tab:
        - action: [SwitchToMode: Resize,]
          key: [Ctrl: 'y',]
    resize:
        - action: [SwitchToMode: Normal,]
          key: [Ctrl: 'y',]
    scroll:
        - action: [SwitchToMode: Resize,]
          key: [Ctrl: 'y',]

I've only remapped one common keybinding, and I felt my config.yaml was a little long for that.

Not only is it long, but now my config.yaml is tightly coupled with modes. This makes the configuration fragile. As soon as a new mode is added (for instance the new move mode in #164), my config file will "break" and I'll need to alter it to fix the resize keybinding in that mode.

Proposed solution:

This is an example of how Zellij could make remapping a key relatively intuitive and short in a backwards-compatible manner.

To remap a single keybinding, a config.yaml file could contain only the following:

keybinds:
    global:
       resize: [Ctrl: 'y',]

Where the Zellij default.yaml keybindings in the codebase could be modified to look like this:

keybinds:
    unbind: true
    global:
       lock: [Ctrl: 'g',]
       pane: [Ctrl: 'p',]
       resize: [Ctrl: 'r',]
       ...
    normal:
        - action: [SwitchToMode: Locked,]
          key: lock
        - action: [SwitchToMode: Pane,]
          key: pane
        - action: [SwitchToMode: Resize,]
          key: resize
       ...
    locked:
        - action: [SwitchToMode: Normal,]
          key: lock
        - action: [SwitchToMode: Pane,]
          key: pane
        - action: [SwitchToMode: Resize,]
          key: resize
         ...

The neat part of this solution is that it is a non-breaking change that still allows users the specificity they had before, using the same syntax as before... but now there is an additional concept of global keybindings that work across modes.

So users could still mix and match if they need to, for example:

keybinds:
    global:
       resize: [Ctrl: 'y',]
    normal:
        - action: [SwitchToMode: Locked,]
          key: [Ctrl: 'l',]

Additional notes

If this this is done, it might be good to create a followup PR to update the documentation relating to keybindings the website: https://github.com/zellij-org/zellij-org.github.io

Post Edits:

  • Updated named to global
  • Minor cleanup
@matu3ba
Copy link
Contributor

matu3ba commented May 20, 2021

@LeeBradley I understand under named keybindings that I can define keybinding groups similar to what alacritty allows.
Otherwise its unclear to ambiguous to the user what config is actually chosen (or would need to take additional space).
Its also not immediately clear from your suggestion what named or normal is semantically.

For example I have for my colorscheme in Alacritty

# Colors (Modus)
schemes:
solarized-dark: &dark
  # Default colors
  primary:
    background: '#002b36' # base03
    foreground: '#839496' # base0

  # Cursor colors
  cursor:
    text:   '#002b36' # base03
    cursor: '#839496' # base0

  # Normal colors
  normal:
    black:   '#073642' # base02
    ....
    white:   '#eee8d5' # base2

  # Bright colors
  bright:
    black:   '#002b36' # base03
    ...
    white:   '#fdf6e3' # base3
solarized-light: &light
  # Default colors
  primary:
    background: '#fdf6e3' # base3
    foreground: '#657b83' # base00

  # Cursor colors
  cursor:
    text:   '#fdf6e3' # base3
    cursor: '#657b83' # base00

  # Normal colors
  normal:
    black:   '#002b36' # base03
    ...
    white:   '#eee8d5' # base2

  # Bright colors
  bright:
    black:   '#073642' # base02
    ...
    white:   '#fdf6e3' # base3
colors: *dark

and switch beween them by simply changing to colors: *light.

Only potential drawback for reusing the Alacritty code is that it is licensed under Apache 2.0 and thus the origin of the used code would need to be mentioned (unless there is a statement of all respective code contributors of the functionality on relicensing). This is defined by yaml 1.2 spec and not alacritty-specific.

@ameliabradley ameliabradley changed the title Add named keybindings to config file Consolidate common keybindings in config and simplify the process of remapping May 21, 2021
@ameliabradley ameliabradley changed the title Consolidate common keybindings in config and simplify the process of remapping Name the config keybindings that are used in every mode, to simplify the process of remapping them May 21, 2021
@ameliabradley
Copy link
Author

@matu3ba You're correct that named might not have been the best descriptor. With the exception of unbind, all the other nodes under keybinds are Zellij modes. I think global probably makes more sense, and I've updated my initial post to reflect that.

I'm not sure that YAML alias nodes would be helpful in this context, or I'm unsure of how they would help make the user's configuration overrides less verbose.

@a-kenji a-kenji added config Improvements to the configuration system enhancement New feature or request labels May 22, 2021
@a-kenji
Copy link
Contributor

a-kenji commented May 22, 2021

Thank you for taking the time in creating this issue!
Having aliases for keybindings is a good solution I think.

keybinds:
    unbind: true
    global:
       lock: [Ctrl: 'g',]
       pane: [Ctrl: 'p',]
       resize: [Ctrl: 'r',]
       ...
    normal:
        - action: [SwitchToMode: Locked,]
          key: lock
        - action: [SwitchToMode: Pane,]
          key: pane
        - action: [SwitchToMode: Resize,]
          key: resize
       ...
    locked:
        - action: [SwitchToMode: Normal,]
          key: lock
        - action: [SwitchToMode: Pane,]
          key: pane
        - action: [SwitchToMode: Resize,]
          key: resize
         ...

I am unsure if this is a syntax that is clear enough.
I think we probably need to structure it more once we add more
capabilities to the keybinds config. For now every single toplevel configuration is already global and every other configuration is a mode.

---
binds:
    unbind: false
    global:
       lock: [Ctrl: 'g',]
       pane: [Ctrl: 'p',]
       resize: [Ctrl: 'r',]
    mode:
      normal:
        unbind: true
        keys:
          - action: [SwitchToMode: Locked,]
            key: lock
          - action: [SwitchToMode: Pane,]
            key: pane
          - action: [SwitchToMode: Resize,]
            key: resize
      locked:
        unbind: false
        keys:
          - action: [SwitchToMode: Normal,]
            key: lock
          - action: [SwitchToMode: Pane,]
            key: pane
          - action: [SwitchToMode: Resize,]
            key: resize

To be clearer the configuration then probably needs to look similar to this, and I think that
might be a little much nesting. On the other hand many people could then already configure
quite easily certain commands that are indeed more or less shared between modes.

    normal:
        - action: [SwitchToMode: Locked,]
          key: lock
       ...
    locked:
        - action: [SwitchToMode: Normal,]
          key: lock

This seems slightly confusing, even though it is correct. I think an action that can toggle between multiple modes could make this clearer.

I'm not sure that YAML alias nodes would be helpful in this context, or I'm unsure of how they would help make the user's configuration overrides less verbose.

We could change the config to make use of the alias nodes, but I am pretty sure we don't want to do that.

@a-kenji
Copy link
Contributor

a-kenji commented Feb 12, 2022

In #1036 we found a way to address this problem, without naming the keybindings. Thanks for all the great insight!

@a-kenji a-kenji closed this as completed Feb 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
config Improvements to the configuration system enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants