which-key.nvim

repository·main·Indexed 27 days ago

https://github.com/folke/which-key.nvim

A Neovim plugin that helps users remember keybindings by displaying available mappings in a customizable popup. It features configurable layouts (classic, modern, helix), support for custom icons via mini.icons or nvim-web-devicons, and a Hydra mode for continuous popup display. The plugin includes built-in support for marks, registers, spelling, and presets for motions and operators.

Tokens
2.6K
Snippets
5
Records
9
Agent score
43%

What's inside which-key.nvim

  1. Use built-in WhichKey plugins

    main

    WhichKey includes several built-in plugins to enhance Neovim functionality:

    • Presets: Built-in help for motions, text-objects, operators, windows, nav, etc.
    • Marks: Displays a list of buffer-local and global marks when hitting ` or ' .
    • Registers: Displays a list of buffer-local and global registers when hitting " in NORMAL mode or <C-r> in INSERT mode.
    • Spelling: When enabled, hooks into z= to replace the full-screen spelling suggestions window with a WhichKey list.
  2. Install WhichKey with lazy.nvim

    main

    Install which-key.nvim using lazy.nvim. It is recommended to load it on the VeryLazy event. You can also define a keymap to show buffer-local keymaps using require("which-key").show({ global = false }).

    {
      "folke/which-key.nvim",
      event = "VeryLazy",
      opts = {
        -- your configuration comes here
        -- or leave it empty to use the default settings
        -- refer to the configuration section below
      },
      keys = {
        {
          "<leader>?",
          function()
            require("which-key").show({ global = false })
          end,
          desc = "Buffer Local Keymaps (which-key)",
        },
      },
    }
  3. Use WhichKey popup keybindings

    main

    When the WhichKey popup is active, you can navigate using these bindings:

    • Key press: Open a group or execute a binding.
    • <esc>: Cancel and close the popup.
    • <bs> (Backspace): Go up one level.
    • <c-d>: Scroll down.
    • <c-u>: Scroll up.
  4. Configure WhichKey triggers

    main

    WhichKey can be triggered via keymaps or ModeChanged events. By default, opts.triggers includes { "<auto>", mode = "nixsotc" }, which automatically sets up triggers for all modes and during mode changes.

    Note that auto-triggers are not created for existing Neovim builtin mappings. To trigger on a builtin keymap, you must add it manually to opts.triggers.

    To defer the popup (e.g., showing it only after an additional key is pressed during an operator sequence), use the opts.defer function.

    -- Manual trigger setup
    triggers = {
      { "<auto>", mode = "nixsotc" },
      { "a", mode = { "n", "v" } },
    }
    
    -- Example: Deferring specific operators
    -- This prevents the popup from showing immediately after 'y' or 'd'
    defer = function(ctx)
      if vim.list_contains({ "d", "y" }, ctx.operator) then
        return true
      end
      return vim.list_contains({ "<C-V>", "V" }, ctx.mode)
    end,
  5. Configure WhichKey options

    main

    WhichKey is highly configurable via the opts table. Key configuration areas include:

    • preset: Choose between "classic", "modern", or "helix" layouts.
    • delay: A number or function returning a number representing the delay before showing the popup.
    • spec: Initial mappings defined during setup.
    • triggers: Automatic or manual trigger definitions (defaults to { { "<auto>", mode = "nxso" } }).
    • plugins: Enable/disable built-in plugins like marks, registers, spelling, and presets (operators, motions, text_objects, etc.).
    • win: Configure the popup window properties like padding, title, border, and zindex.
    • layout: Set width and spacing for columns.
    • sort: Define sorting order using values like "local", "order", "group", "alphanum", "mod", etc.
    • icons: Customize symbols for breadcrumb, separator, group, and specific key modifiers.
    • disable: Disable WhichKey for specific filetypes (ft) or buffertypes (bt).

    Run :checkhealth which-key if you encounter issues.

  6. Configure WhichKey icons

    main

    To use icons, you must have mini.icons or nvim-web-devicons installed. You can set icons via custom rules or directly in your mapping specification.

    In a mapping spec, the icon attribute can be a string or a wk.Icon object.

    Valid color values for wk.Icon: azure, blue, cyan, green, grey, orange, purple, red, yellow.

    Valid cat (category) values: file, filetype, extension.

    To disable icons entirely, set opts.icons.mappings to false.

  7. Enable Hydra Mode

    main

    Hydra mode keeps the WhichKey popup open continuously until you press <esc>. This is useful for repetitive tasks like window navigation.

    -- Show hydra mode for changing windows
    require("which-key").show({
      keys = "<c-w>",
      loop = true, -- this will keep the popup open until you hit <esc>
    })
  8. Add or update mappings with `add()`

    main

    Use require("which-key").add() to define mappings or groups. This method can be called multiple times.

    Mapping Attributes:

    • lhs (string, required): The key sequence.
    • rhs (string|fun, optional): The command or function to execute.
    • desc (string|fun, required for non-groups): The description shown in the popup.
    • group (string|fun, optional): The name of the group this mapping belongs to.
    • mode (string|string[], optional): The mode (defaults to "n").
    • cond (boolean|fun, optional): Condition to enable the mapping.
    • hidden (boolean, optional): If true, hides the mapping from the popup.
    • icon (string|wk.Icon|fun, optional): Icon specification.
    • proxy (string, optional): Proxy to another mapping.
    • expand (fun, optional): Function to create dynamic nested mappings.

    Note: desc, group, and icon can be functions that are evaluated every time the popup is shown.

    local wk = require("which-key")
    wk.add({
      { "<leader>f", group = "file" }, -- group
      { "<leader>ff", "<cmd>Telescope find_files<cr>", desc = "Find File", mode = "n" },
      { "<leader>fb", function() print("hello") end, desc = "Foobar" },
      { "<leader>fn", desc = "New File" },
      { "<leader>f1", hidden = true }, -- hide this keymap
      { "<leader>w", proxy = "<c-w>", group = "windows" }, -- proxy to window mappings
      { "<leader>b", group = "buffers", expand = function()
          return require("which-key.extras").expand.buf()
        end
      },
      {
        -- Nested mappings are allowed and can be added in any order
        -- Most attributes can be inherited or overridden on any level
        -- There's no limit to the depth of nesting
        mode = { "n", "v" }, -- NORMAL and VISUAL mode
        { "<leader>q", "<cmd>q<cr>", desc = "Quit" }, -- no need to specify mode since it's inherited
        { "<leader>w", "<cmd>w<cr>", desc = "Write" },
      }
    })
  9. Reference WhichKey highlight groups

    main

    The following highlight groups are defined by WhichKey. You can use these to customize the appearance of the popup window.

    | Highlight Group | Default Group | Description |
    | --- | --- | --- |
    | **WhichKey** | ***Function*** | |
    | **WhichKeyBorder** | ***FloatBorder*** | Border of the which-key window |
    | **WhichKeyDesc** | ***Identifier*** | description |
    | **WhichKeyGroup** | ***Keyword*** | group name |
    | **WhichKeyIcon** | ***@markup.link*** | icons |
    | **WhichKeyIconAzure** | ***Function*** | |
    | **WhichKeyIconBlue** | ***DiagnosticInfo*** | |
    | **WhichKeyIconCyan** | ***DiagnosticHint*** | |
    | **WhichKeyIconGreen** | ***DiagnosticOk*** | |
    | **WhichKeyIconGrey** | ***Normal*** | |
    | **WhichKeyIconOrange** | ***DiagnosticWarn*** | |
    | **WhichKeyIconPurple** | ***Constant*** | |
    | **WhichKeyIconRed** | ***DiagnosticError*** | |
    | **WhichKeyIconYellow** | ***DiagnosticWarn*** | |
    | **WhichKeyNormal** | ***NormalFloat*** | Normal in th which-key window |
    | **WhichKeySeparator** | ***Comment*** | the separator between the key and its description |
    | **WhichKeyTitle** | ***FloatTitle*** | Title of the which-key window |
    | **WhichKeyValue** | ***Comment*** | values by plugins (like marks, registers, etc) |