Skip to content

[Feature]Collapsible/Foldable Keybinding Hints #3774

@VigneshR387

Description

@VigneshR387

yazi --debug output


Yazi
    Version: 26.1.22 (Arch Linux 2026-02-20)
    Debug  : false
    Triple : x86_64-unknown-linux-gnu (linux-x86_64)
    Rustc  : 1.93.1 (01f6ddf7 2026-02-11)

Ya
    Version: 26.1.22 (Arch Linux 2026-02-20)

Config
    Init             : /home/vigr/.config/yazi/init.lua (16946 chars)
    Yazi             : /home/vigr/.config/yazi/yazi.toml (3889 chars)
    Keymap           : /home/vigr/.config/yazi/keymap.toml (20652 chars)
    Theme            : /home/vigr/.config/yazi/theme.toml (35346 chars)
    VFS              : /home/vigr/.config/yazi/vfs.toml (No such file or directory (os error 2))
    Package          : /home/vigr/.config/yazi/package.toml (6960 chars)
    Dark/light flavor: "rose-pine" / "rose-pine-dawn"

Emulator
    TERM                : Some("xterm-kitty")
    TERM_PROGRAM        : None
    TERM_PROGRAM_VERSION: None
    Brand.from_env      : Some(Kitty)
    Emulator.detect     : Emulator { kind: Left(Kitty), version: "kitty(0.46.1)", light: false, csi_1
6t: (9, 20), force_16t: false }

Adapter
    Adapter.matches    : Kgp
    Dimension.available: Dimension { rows: 49, columns: 101, width: 909, height: 980 }

Desktop
    XDG_SESSION_TYPE           : Some("wayland")
    WAYLAND_DISPLAY            : Some("wayland-0")
    DISPLAY                    : Some(":0")
    SWAYSOCK                   : None
    HYPRLAND_INSTANCE_SIGNATURE: None
    WAYFIRE_SOCKET             : None

SSH
    shared.in_ssh_connection: false

WSL
    WSL: false

Variables
    SHELL              : Some("/bin/zsh")
    EDITOR             : Some("nvim")
    VISUAL             : Some("nvim")
    YAZI_FILE_ONE      : None
    YAZI_CONFIG_HOME   : None
    FZF_DEFAULT_OPTS   : Some("--bind 'ctrl-a:select-all,ctrl-d:deselect-all,ctrl-t:toggle-all'")
    FZF_DEFAULT_COMMAND: None

Text Opener
    default     : Some(OpenerRule { run: "${EDITOR:-vi} %s", block: true, orphan: false, desc: "$EDIT
OR", for: None, spread: true })
    block-create: Some(OpenerRule { run: "${EDITOR:-vi} %s", block: true, orphan: false, desc: "$EDIT
OR", for: None, spread: true })
    block-rename: Some(OpenerRule { run: "${EDITOR:-vi} %s", block: true, orphan: false, desc: "$EDIT
OR", for: None, spread: true })

Multiplexers
    TMUX               : false
    tmux version       : tmux 3.6a
    tmux build flags   : enable-sixel=Supported
    ZELLIJ_SESSION_NAME: None
    Zellij version     : 0.43.1

Dependencies
    file          : 5.47
    ueberzugpp    : No such file or directory (os error 2)
    ffmpeg/ffprobe: 8.0.1 / 8.0.1
    pdftoppm      : 26.03.0
    magick        : 7.1.2-17
    fzf           : 0.70.0
    fd/fdfind     : 10.4.2 / No such file or directory (os error 2)
    rg            : 15.1.0
    chafa         : 1.18.1
    zoxide        : 0.9.9
    7zz/7z        : No such file or directory (os error 2) / 26.00
    resvg         : 0.47.0
    jq            : 1.8.1

Clipboard
    wl-copy/paste: 2.2.1 / 2.2.1
    xclip        : 0.13
    xsel         : No such file or directory (os error 2)

Routine
    `file -bL --mime-type`: text/plain


See https://yazi-rs.github.io/docs/plugins/overview#debugging on how to enable logging or debug runti
me errors.



Please describe the problem you're trying to solve

Currently, keybinding hints display all possible key combinations at once, even when the bindings are part of a logical multi-level hierarchy. This can make the hint display visually cluttered and harder to understand, especially when many bindings share the same prefix.

For example, when using the Yazi plugin toggle-pane.yazi, the keymap configuration might look like this:

[[mgr.prepend_keymap]]
on   = ["u","p","r"]
run  = "plugin toggle-pane reset"
desc = "Resets to user ratio"

[[mgr.prepend_keymap]]
on   = ["u","p","+","a"]
run  = "plugin toggle-pane max-parent"
desc = "Maximize or restore the parent pane"

[[mgr.prepend_keymap]]
on   = ["u","p","+","c"]
run  = "plugin toggle-pane max-current"
desc = "Maximize or restore the current pane"

[[mgr.prepend_keymap]]
on   = ["u","p","+","p"]
run  = "plugin toggle-pane max-preview"
desc = "Maximize or restore the preview pane"

[[mgr.prepend_keymap]]
on   = ["u","p","-","a"]
run  = "plugin toggle-pane min-parent"
desc = "Minimize or Hide the parent pane"

[[mgr.prepend_keymap]]
on   = ["u","p","-","c"]
run  = "plugin toggle-pane min-current"
desc = "Minimize or Hide the current pane"

[[mgr.prepend_keymap]]
on   = ["u","p","-","p"]
run  = "plugin toggle-pane min-preview"
desc = "Minimize or Hide the preview pane"

When the keybinding hint is displayed, all combinations are shown simultaneously, resulting in a flat list of bindings that can be difficult to scan and understand.

This becomes especially problematic as the number of bindings grows, since the UI does not reflect the logical grouping of prefixes.

Would you be willing to contribute this feature?

  • Yes, I'll give it a shot

Describe the solution you'd like

A support for hierarchical (multi-level) keybinding hints so nested keymaps are displayed progressively instead of all combinations being shown at once(Similiar to which-key in Emacs). This makes keybinding hints look less visually cluttered and allows users to organize the keybindings into meaningful groups.

Example Use Case 1:

For instance, the current keybinding hint looks like this :

image

Desired Outcome

image

Example Use Case 2

For Instance, All the keybindings related to files can be organized into this specific format:

f  → File

├─ f → Find
│   ├─ f → Find file (fzf)
│   ├─ r → Recent files
│   └─ g → Grep / smart filter

├─ a → Actions
│   ├─ a → File actions menu
│   ├─ r → Rename
│   ├─ c → Compress
│   └─ x → Delete

├─ y → Yank / Copy
│   ├─ y → Copy
│   └─ p → Paste

├─ m → Metadata / Info
│   ├─ m → Toggle metadata
│   └─ s → Size info

└─ o → Open
    ├─ o → Open interactive
    └─ l → Lazygit

and so on

Additional context

No response

Checklist

  • I have searched the existing issues/discussions
  • The latest nightly build doesn't already have this feature

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions