Convert Figma logo to code with AI

justbur logoemacs-which-key

Emacs package that displays available keybindings in popup

1,769
86
1,769
74

Top Related Projects

3,420

Emacs incremental completion and selection narrowing framework

A use-package declaration for simplifying your .emacs

2,355

Ivy - a generic completion frontend for Emacs, Swiper - isearch with an overview, and more. Oh, man!

5,191

Prelude is an enhanced Emacs 25.1+ distribution that should make your experience with Emacs both more pleasant and more powerful.

24,142

A community-driven Emacs distribution - The best editor is neither Emacs nor Vim, it's Emacs *and* Vim!

20,602

An Emacs framework for the stubborn martian hacker

Quick Overview

The emacs-which-key package is an Emacs plugin that provides a helpful popup window that displays available keybindings when you start typing a key sequence. This can be particularly useful for discovering and learning new keyboard shortcuts in Emacs.

Pros

  • Improved Discoverability: The popup window makes it easier to discover and learn new keyboard shortcuts, especially for less frequently used commands.
  • Customizable: The package provides a wide range of customization options, allowing users to tailor the appearance and behavior of the popup window to their preferences.
  • Actively Maintained: The project is actively maintained, with regular updates and bug fixes.
  • Integrates Well with Emacs: The package is designed to seamlessly integrate with the Emacs ecosystem, providing a smooth user experience.

Cons

  • Initial Setup: Some users may find the initial setup and configuration of the package to be slightly more complex than they would prefer.
  • Performance Impact: Depending on the size of your Emacs configuration and the number of keybindings, the package may have a small performance impact on your Emacs startup time.
  • Potential Conflicts: The package may occasionally conflict with other Emacs packages or customizations, requiring some troubleshooting.
  • Learning Curve: While the package aims to improve discoverability, some users may still need to invest time in learning the various keybinding conventions and patterns used in Emacs.

Code Examples

N/A (This is not a code library)

Getting Started

N/A (This is not a code library)

Competitor Comparisons

3,420

Emacs incremental completion and selection narrowing framework

Pros of emacs-helm/helm

  • Provides a powerful and flexible interface for searching and selecting from a variety of sources, including files, buffers, and more.
  • Supports a wide range of functionality, including fuzzy matching, sorting, and customization.
  • Integrates well with other Emacs packages, making it a versatile tool for navigating and managing your Emacs environment.

Cons of emacs-helm/helm

  • Can have a steeper learning curve compared to simpler completion frameworks like which-key.
  • May be overkill for users who only need basic completion and navigation features.
  • Can be resource-intensive, especially on older or less powerful systems.

Code Comparison

Here's a brief comparison of how the which-key and helm packages handle key binding display:

which-key:

(which-key-add-key-based-replacements
 "C-x" "File"
 "C-x C-f" "Find File")

helm:

(global-set-key (kbd "C-x C-f") 'helm-find-files)
(helm-mode 1)

The which-key approach focuses on providing a concise, contextual display of available key bindings, while helm provides a more comprehensive interface for navigating and selecting from a variety of sources.

A use-package declaration for simplifying your .emacs

Pros of use-package

  • Provides a concise and organized way to configure Emacs packages, making it easier to manage a large number of packages.
  • Supports lazy-loading of packages, which can improve Emacs startup time.
  • Offers a variety of configuration options, such as :ensure, :bind, and :config, to customize package behavior.

Cons of use-package

  • The configuration syntax can be more complex than some users prefer, especially for beginners.
  • Requires an additional package to be installed, which may not be desirable for some users.
  • Might not be as flexible as manually configuring packages in an Emacs init file.

Code Comparison

use-package:

(use-package which-key
  :ensure t
  :config
  (which-key-mode))

which-key:

(require 'which-key)
(which-key-mode)
2,355

Ivy - a generic completion frontend for Emacs, Swiper - isearch with an overview, and more. Oh, man!

Pros of Swiper

  • Swiper provides a more powerful and flexible search functionality compared to Which-Key, allowing users to search through a wider range of content, including files, buffers, and more.
  • Swiper's interface is highly customizable, allowing users to tailor the search experience to their preferences.
  • Swiper integrates well with other Emacs packages, making it a versatile tool for power users.

Cons of Swiper

  • Swiper has a steeper learning curve compared to Which-Key, as it offers more advanced features and configuration options.
  • Swiper may be overkill for users who only need basic search functionality, as Which-Key provides a more lightweight and focused solution.

Code Comparison

Which-Key:

(which-key-add-key-based-replacements
 "C-x" '(("C-f" . "find-file")
         ("C-b" . "switch-to-buffer")
         ("C-s" . "save-buffer")))

Swiper:

(ivy-mode 1)
(setq ivy-use-virtual-buffers t)
(setq enable-recursive-minibuffers t)
(global-set-key "\C-s" 'swiper)
(global-set-key (kbd "C-c C-r") 'ivy-resume)
(global-set-key (kbd "<f6>") 'ivy-resume)
5,191

Prelude is an enhanced Emacs 25.1+ distribution that should make your experience with Emacs both more pleasant and more powerful.

Pros of Prelude

  • Prelude provides a comprehensive set of customizations and utilities, making it a great starting point for new Emacs users.
  • Prelude includes a wide range of packages and configurations, covering various aspects of the Emacs experience.
  • Prelude's documentation and community support can be beneficial for users who are new to Emacs.

Cons of Prelude

  • Prelude's extensive customizations may not align with the preferences of experienced Emacs users, who may prefer a more minimalist approach.
  • The large codebase and number of dependencies in Prelude can make it more challenging to understand and customize.

Code Comparison

Prelude's prelude-packages.el file:

(defvar prelude-packages
  '(ace-jump-mode
    ace-window
    anzu
    avy
    beacon
    browse-kill-ring
    crux
    dash
    diminish
    discover-my-major
    editorconfig
    expand-region
    flycheck
    gist
    git-timemachine
    gitconfig-mode
    gitignore-mode
    goto-chg
    guide-key
    highlight-indentation
    ido-ubiquitous
    ido-vertical-mode
    imenu-anywhere
    magit
    markdown-mode
    move-text
    multiple-cursors
    projectile
    rainbow-delimiters
    smartparens
    smex
    undo-tree
    volatile-highlights
    which-key
    zenburn-theme)
  "A list of packages to ensure are installed at launch.")

emacs-which-key's which-key.el file:

(defvar which-key-idle-delay 0.5
  "The number of seconds to wait before displaying the which-key buffer.")

(defvar which-key-popup-type 'side-window
  "The type of popup to use for displaying key completions.
Possible values are `side-window', `minibuffer', and `frame'.")

(defvar which-key-side-window-location 'bottom
  "The location of the which-key popup window.
Possible values are `left', `right', `top', and `bottom'.")

(defvar which-key-side-window-max-width 0.33
  "The maximum width of the which-key popup window as a fraction of the frame width.")

(defvar which-key-side-window-max-height 0.25
  "The maximum height of the which-key popup window as a fraction of the frame height.")
24,142

A community-driven Emacs distribution - The best editor is neither Emacs nor Vim, it's Emacs *and* Vim!

Pros of Spacemacs

  • Spacemacs provides a comprehensive and well-organized configuration for Emacs, making it easier for beginners to get started with the editor.
  • The project has a large and active community, which means more support and resources available for users.
  • Spacemacs includes a wide range of pre-configured packages and layers, covering a variety of use cases and workflows.

Cons of Spacemacs

  • Spacemacs can be more complex and overwhelming for users who prefer a more minimalist approach to Emacs configuration.
  • The project's focus on providing a complete solution may limit the flexibility and customization options for advanced users.
  • Spacemacs may have a steeper learning curve compared to a more lightweight Emacs configuration like emacs-which-key.

Code Comparison

Here's a brief comparison of the code for emacs-which-key and Spacemacs:

emacs-which-key (justbur/emacs-which-key):

(which-key-mode)
(which-key-setup-side-window-right-bottom)
(setq which-key-idle-delay 0.4)
(setq which-key-max-display-columns nil)
(setq which-key-side-window-max-width 0.33)

Spacemacs (syl20bnr/spacemacs):

(use-package which-key
  :config
  (which-key-mode)
  (which-key-setup-side-window-right-bottom)
  (setq which-key-idle-delay 0.4)
  (setq which-key-max-display-columns nil)
  (setq which-key-side-window-max-width 0.33))

The main difference is that Spacemacs uses the use-package macro to manage the configuration of which-key, while emacs-which-key directly sets the configuration variables.

20,602

An Emacs framework for the stubborn martian hacker

Pros of doomemacs/doomemacs

  • Comprehensive configuration with a wide range of pre-configured packages and settings
  • Streamlined workflow with a focus on productivity and efficiency
  • Active community and regular updates

Cons of doomemacs/doomemacs

  • Steep learning curve for users unfamiliar with Emacs
  • Potential difficulty in customizing the configuration to individual preferences
  • Larger codebase and dependencies compared to a more lightweight solution

Code Comparison

justbur/emacs-which-key

(use-package which-key
  :config
  (which-key-mode)
  (setq which-key-idle-delay 0.4))

doomemacs/doomemacs

(use-package which-key
  :config
  (which-key-mode)
  (setq which-key-idle-delay 0.4)
  (setq which-key-allow-imprecise-window-fit t))

The doomemacs configuration includes an additional setting which-key-allow-imprecise-window-fit, which can improve the appearance and positioning of the which-key popup window.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

** ARCHIVE NOTICE

which-key is now included in the master branch of Emacs and will likely be released with Emacs v30. Bug reports and contributions to which-key will now be considered through standard Emacs channels, and this repository is being archived.

** Introduction =which-key= is a minor mode for Emacs that displays the key bindings following your currently entered incomplete command (a prefix) in a popup. For example, after enabling the minor mode if you enter =C-x= and wait for the default of 1 second the minibuffer will expand with all of the available key bindings that follow =C-x= (or as many as space allows given your settings). This includes prefixes like =C-x 8= which are shown in a different face. Screenshots of what the popup will look like are included below. =which-key= started as a rewrite of [[https://github.com/kai2nenobu/guide-key][guide-key-mode]], but the feature sets have diverged to a certain extent.

** Table of Contents :TOC_3:

  • [[#which-key][which-key]]
    • [[#archive-notice][ARCHIVE NOTICE]]
    • [[#introduction][Introduction]]
    • [[#install][Install]]
      • [[#melpa][MELPA]]
      • [[#manually][Manually]]
    • [[#initial-setup][Initial Setup]]
      • [[#side-window-bottom-option][Side Window Bottom Option]]
      • [[#side-window-right-option][Side Window Right Option]]
      • [[#side-window-right-then-bottom][Side Window Right then Bottom]]
      • [[#minibuffer-option][Minibuffer Option]]
    • [[#manual-activation][Manual Activation]]
    • [[#additional-commands][Additional Commands]]
    • [[#special-features-and-configuration-options][Special Features and Configuration Options]]
      • [[#popup-type-options][Popup Type Options]]
      • [[#custom-string-replacement-options][Custom String Replacement Options]]
      • [[#sorting-options][Sorting Options]]
      • [[#paging-options][Paging Options]]
      • [[#face-customization-options][Face Customization Options]]
      • [[#other-options][Other Options]]
    • [[#support-for-third-party-libraries][Support for Third-Party Libraries]]
      • [[#key-chord][Key-chord]]
      • [[#evil-operators][Evil operators]]
      • [[#god-mode][God-mode]]
    • [[#more-examples][More Examples]]
      • [[#nice-display-with-split-frame][Nice Display with Split Frame]]
    • [[#known-issues][Known Issues]]
    • [[#thanks][Thanks]]

** Install *** MELPA After setting up [[http://melpa.org][MELPA]] as a repository, use =M-x package-install which-key= or your preferred method. You will need to call =which-key-mode= to enable the minor mode of course.

*** Manually Add which-key.el to your =load-path= and require. Something like #+BEGIN_SRC emacs-lisp (add-to-list 'load-path "path/to/which-key.el") (require 'which-key) (which-key-mode) #+END_SRC

** Initial Setup No further setup is required if you are happy with the default setup. To try other options, there are 3 choices of default configs that are preconfigured (then customize to your liking). The main choice is where you want the which-key buffer to display. Screenshots of the default options are shown in the next sections.

In each case, we show as many key bindings as we can fit in the buffer within the constraints. The constraints are determined by several factors, including your Emacs settings, the size of the current Emacs frame, and the which-key settings, most of which are described below.

There are many substitution abilities included, which are quite flexible (ability to use regexp for example). This makes which-key very customizable.

*** Side Window Bottom Option Popup side window on bottom. This is the current default. To restore this setup use

#+BEGIN_SRC emacs-lisp

(which-key-setup-side-window-bottom) #+END_SRC

[[./img/which-key-bottom.png]]

*** Side Window Right Option Popup side window on right. For defaults use

#+BEGIN_SRC emacs-lisp

(which-key-setup-side-window-right) #+END_SRC

Note the defaults are fairly conservative and will tend to not display on
narrower frames. If you get a message saying which-key can't display the
keys, try making your frame wider or adjusting the defaults related to the
maximum width (see =M-x customize-group which-key=).

[[./img/which-key-right.png]]

*** Side Window Right then Bottom This is a combination of the previous two choices. It will try to use the right side, but if there is no room it will switch to using the bottom, which is usually easier to fit keys into. This setting can be helpful if the size of the Emacs frame changes frequently, which might be the case if you are using a dynamic/tiling window manager.

#+BEGIN_SRC emacs-lisp
(which-key-setup-side-window-right-bottom)
#+END_SRC

*** Minibuffer Option Take over the minibuffer. For the recommended configuration use

#+BEGIN_SRC emacs-lisp
(which-key-setup-minibuffer)
#+END_SRC

[[./img/which-key-minibuffer.png]]

Note the maximum height of the minibuffer is controlled through the built-in
variable =max-mini-window-height=. Also, the paging commands do not work
reliably with the minibuffer option. Use the side window on the bottom
option if you need paging.

** Manual Activation #+NAME: #manual-activation If you only want the =which-key= popup when you need it, you can try a setup along the following lines

#+BEGIN_SRC emacs-lisp ;; Allow C-h to trigger which-key before it is done automatically (setq which-key-show-early-on-C-h t) ;; make sure which-key doesn't show normally but refreshes quickly after it is ;; triggered. (setq which-key-idle-delay 10000) (setq which-key-idle-secondary-delay 0.05) (which-key-mode) #+END_SRC

This will prevent which-key from showing automatically, and allow you to use =C-h= in the middle of a key sequence to show the =which-key= buffer and keep it open for the remainder of the key sequence.

** Additional Commands

  • =which-key-show-top-level= will show most key bindings without a prefix. It is most and not all, because many are probably not interesting to most users.
  • =which-key-show-major-mode= will show the currently active major-mode bindings. It's similar to =C-h m= but in a which-key format. It is also aware of evil commands defined using =evil-define-key=.
  • =which-key-show-next-page-cycle= / =which-key-show-previous-page-cycle= will flip pages in a circle.
  • =which-key-show-next-page-no-cycle= / =which-key-show-previous-page-no-cycle= will flip pages and stop at first/last page.
  • =which-key-undo= can be used to undo the last keypress when in the middle of a key sequence.

** Special Features and Configuration Options There are more options than the ones described here. All of the configurable variables are available through =M-x customize-group which-key=. *** Popup Type Options There are three different popup types that which-key can use by default to display the available keys. The variable =which-key-popup-type= decides which one is used. **** minibuffer #+BEGIN_SRC emacs-lisp (setq which-key-popup-type 'minibuffer) #+END_SRC Show keys in the minibuffer. **** side window #+BEGIN_SRC emacs-lisp (setq which-key-popup-type 'side-window) #+END_SRC Show keys in a side window. This popup type has further options: #+BEGIN_SRC emacs-lisp ;; location of which-key window. valid values: top, bottom, left, right, ;; or a list of any of the two. If it's a list, which-key will always try ;; the first location first. It will go to the second location if there is ;; not enough room to display any keys in the first location (setq which-key-side-window-location 'bottom)

 ;; max width of which-key window, when displayed at left or right.
 ;; valid values: number of columns (integer), or percentage out of current
 ;; frame's width (float larger than 0 and smaller than 1)
 (setq which-key-side-window-max-width 0.33)

 ;; max height of which-key window, when displayed at top or bottom.
 ;; valid values: number of lines (integer), or percentage out of current
 ;; frame's height (float larger than 0 and smaller than 1)
 (setq which-key-side-window-max-height 0.25)
 #+END_SRC

**** frame

 #+BEGIN_SRC emacs-lisp
 (setq which-key-popup-type 'frame)
 #+END_SRC
 Show keys in a popup frame. This popup won't work very well in a terminal,
 where only one frame can be shown at any given moment. This popup type has
 further options:
 #+BEGIN_SRC emacs-lisp
 ;; max width of which-key frame: number of columns (an integer)
 (setq which-key-frame-max-width 60)

 ;; max height of which-key frame: number of lines (an integer)
 (setq which-key-frame-max-height 20)
 #+END_SRC

**** custom Write your own display functions! This requires you to write three functions, =which-key-custom-popup-max-dimensions-function=, =which-key-custom-show-popup-function=, and =which-key-custom-hide-popup-function=. Refer to the documentation for those variables for more information, but here is a working example (this is the current implementation of side-window bottom).

 #+BEGIN_SRC emacs-lisp
   (setq which-key-popup-type 'custom)
   (defun which-key-custom-popup-max-dimensions-function (ignore)
     (cons
      (which-key-height-or-percentage-to-height
       which-key-side-window-max-height)
      (frame-width)))
   (defun fit-horizonatally ()
     (let ((fit-window-to-buffer-horizontally t))
       (fit-window-to-buffer)))
   (defun which-key-custom-show-popup-function (act-popup-dim)
     (let* ((alist '((window-width . fit-horizontally)
                     (window-height . fit-window-to-buffer))))
       (if (get-buffer-window which-key--buffer)
           (display-buffer-reuse-window which-key--buffer alist)
         (display-buffer-in-major-side-window which-key--buffer
                                              'bottom 0 alist))))
   (defun which-key-custom-hide-popup-function ()
     (when (buffer-live-p which-key--buffer)
       (quit-windows-on which-key--buffer)))
 #+END_SRC

*** Custom String Replacement Options #+NAME: #custom-string-replacement-options You can customize the way the keys show in the buffer using three different replacement methods. The first, keymap-based replacement, is preferred and will take precedence over the others. The remaining methods are still available, because they pre-date the first and are more flexible in what they can accomplish.

**** Keymap-based replacement Using this method, which-key can display a custom string for a key definition in some keymap. There are two ways to define a keymap-based replacement. The preferred way is to use =define-key= (or a command that uses =define-key= internally) with a cons cell as the definition. For example,

 #+BEGIN_SRC emacs-lisp
   (define-key some-map "f" '("foo" . command-foo))
   (define-key some-map "b" '("bar-prefix" . (keymap)))
   (setq my-map (make-sparse-keymap))
   (define-key some-map "b" (cons "bar-prefix" my-map))
 #+END_SRC

 binds =command-foo= to =f= in =some-map=, but also stores the string "foo"
 which which-key will extract to use to describe this command. The second
 example binds an empty keymap to =b= in =some-map= and uses "bar-prefix" to
 describe it. The last two lines replicate the functionality of the second
 line, while assigning the new keymap to the symbol =my-map= (note the use
 of =cons= to ensure that =my-map= is evaluated for =define-key=). These
 bindings are accepted by =define-key= natively (i.e., with or without
 which-key being loaded). Since many key-binding utilities use =define-key=
 internally, this functionality should be available with your favorite
 method of defining keys as well.

 The second method is to use =which-key-add-keymap-based-replacements=. The
 statement

 #+BEGIN_SRC emacs-lisp
   (define-key some-map "f" 'long-command-name-foo)
   (define-key some-map "b" some-prefix-map)
   (which-key-add-keymap-based-replacements some-map
     "f" '("foo" . long-command-name-foo)
     "b" '("bar-prefix" . (keymap)))
 #+END_SRC

 uses =define-key= to add two bindings and tells which-key to use the string
 "foo" in place of "command-foo" and the string "bar-prefix" for an empty
 prefix map. =which-key-add-keymap-based-replacements= just uses
 =define-key= to bind (or rebind) the command.

 There are other methods of telling which-key to replace command names,
 which are described next. The keymap-based replacements should be the most
 performant since they use built-in functionality of emacs. However, the
 alternatives can be more flexible in telling which-key how and when to
 replace text. They can be used simultaneously, but which-key will give
 precedence to the keymap-based replacement when it exists.

**** Key-Based replacement Using this method, the description of a key is replaced using a string that you provide. Here's an example

 #+BEGIN_SRC emacs-lisp
 (which-key-add-key-based-replacements
   "C-x C-f" "find files")
 #+END_SRC

 where the first string is the key combination whose description you want to
 replace, in a form suitable for =kbd=. For that key combination, which-key
 overwrites the description with the second string, "find files". In the
 second type of entry you can restrict the replacements to a major-mode. For
 example,

 #+BEGIN_SRC emacs-lisp
 (which-key-add-major-mode-key-based-replacements 'org-mode
   "C-c C-c" "Org C-c C-c"
   "C-c C-a" "Org Attach")
 #+END_SRC

 Here the first entry is the major-mode followed by a list of the first type
 of entries. In case the same key combination is listed under a major-mode
 and by itself, the major-mode version takes precedence.

**** Key and Description replacement

 The second and third methods target the text used for the keys and the
 descriptions directly. The relevant variable is
 =which-key-replacement-alist=.  Here's an example of one of the default key
 replacements

 #+BEGIN_SRC emacs-lisp
 (push '(("<\\([[:alnum:]-]+\\)>" . nil) . ("\\1" . nil))
       which-key-replacement-alist)
 #+END_SRC

 Each element of the outer cons cell is a cons cell of the form =(KEY
 . BINDING)=. The =car= of the outer cons determines how to match key
 bindings while the =cdr= determines how those matches are replaced. See the
 docstring of =which-key-replacement-alist= for more information.

 The next example shows how to replace the description.

 #+BEGIN_SRC emacs-lisp
 (push '((nil . "left") . (nil . "lft")) which-key-replacement-alist)
 #+END_SRC

 Here is an example of using key replacement to include Unicode characters
 in the results. Unfortunately, using Unicode characters may upset the
 alignment of the which-key buffer, because Unicode characters can have
 different widths even in a monospace font and alignment is based on
 character width.

 #+BEGIN_SRC emacs-lisp
 (add-to-list 'which-key-replacement-alist '(("TAB" . nil) . ("↹" . nil)))
 (add-to-list 'which-key-replacement-alist '(("RET" . nil) . ("⏎" . nil)))
 (add-to-list 'which-key-replacement-alist '(("DEL" . nil) . ("⇤" . nil)))
 (add-to-list 'which-key-replacement-alist '(("SPC" . nil) . ("␣" . nil)))
 #+END_SRC

 The =cdr= may also be a function that receives a =cons= of the form =(KEY
 . BINDING)= and produces a =cons= of the same form. This allows for
 interesting ideas like this one suggested by [[https://github.com/pdcawley][@pdcawley]] in [[https://github.com/justbur/emacs-which-key/pull/147][PR #147]].

 #+BEGIN_SRC emacs-lisp
 (push (cons '(nil . "paredit-mode")
             (lambda (kb)
               (cons (car kb)
                     (if paredit-mode
                         "[x] paredit-mode"
                       "[ ] paredit-mode"))))
       which-key-replacement-alist)
 #+END_SRC

 The box will be checked if =paredit-mode= is currently active.

*** Sorting Options By default the output is sorted by the key in a custom order. The default order is to sort lexicographically within each "class" of key, where the classes and their order are

=Special (SPC, TAB, ...) < Single Character (ASCII) (a, ...) < Modifier (C-, M-, ...) < Other=

You can control the order by setting this variable. This also shows the
other available options.

#+BEGIN_SRC emacs-lisp
;; default
(setq which-key-sort-order 'which-key-key-order)
;; same as default, except single characters are sorted alphabetically
;; (setq which-key-sort-order 'which-key-key-order-alpha)
;; same as default, except all prefix keys are grouped together at the end
;; (setq which-key-sort-order 'which-key-prefix-then-key-order)
;; same as default, except all keys from local maps shown first
;; (setq which-key-sort-order 'which-key-local-then-key-order)
;; sort based on the key description ignoring case
;; (setq which-key-sort-order 'which-key-description-order)
#+END_SRC

*** Paging Options

There are at least several prefixes that have many keys bound to them, like
=C-x=. which-key displays as many keys as it can given your settings, but
for these prefixes this may not be enough. The paging feature gives you the
ability to bind a key to the function =which-key-C-h-dispatch= which will
allow you to cycle through the pages without changing the key sequence you
were in the middle of typing. There are two slightly different ways of doing
this.

**** Method 1 (default): Using C-h (or =help-char=) This is the easiest way, and is turned on by default. Use #+BEGIN_SRC emacs-lisp (setq which-key-use-C-h-commands nil) #+END_SRC to disable the behavior (this will only take effect after toggling which-key-mode if it is already enabled). =C-h= can be used with any prefix to switch pages when there are multiple pages of keys. This changes the default behavior of Emacs which is to show a list of key bindings that apply to a prefix. For example, if you were to type =C-x C-h= you would get a list of commands that follow =C-x=. This uses which-key instead to show those keys, and unlike the Emacs default saves the incomplete prefix that you just entered so that the next keystroke can complete the command.

 The commands are:
 - Cycle through the pages forward with =n= (or =C-n=)
 - Cycle backwards with =p= (or =C-p=)
 - Undo the last entered key (!) with =u= (or =C-u=)
 - Call the default command bound to =C-h=, usually
   =describe-prefix-bindings=, with =h= (or =C-h=)

This is especially useful for those who like =helm-descbinds= but also want to use =C-h= as their which-key paging key.

Note =C-h= is by default equivalent to =?= in this context.

Note also that using =C-h= will not work with the =C-h= prefix, unless you make further adjustments. See Issues [[https://github.com/justbur/emacs-which-key/issues/93][#93]] and [[https://github.com/justbur/emacs-which-key/issues/175][#175]] for example.

**** Method 2: Bind your own keys

 Essentially, all you need to do for a prefix like =C-x= is the following
 which will bind =<f5>= to the relevant command.

 #+BEGIN_SRC emacs-lisp

(define-key which-key-mode-map (kbd "C-x ") 'which-key-C-h-dispatch) #+END_SRC

 This is completely equivalent to

 #+BEGIN_SRC emacs-lisp

(setq which-key-paging-prefixes '("C-x")) (setq which-key-paging-key "") #+END_SRC

 where the latter are provided for convenience if you have a lot of
 prefixes.

*** Face Customization Options The faces that which-key uses are | Face | Applied To | Default Definition | |----------------------------------------+-------------------------------+-------------------------------------------------------------| | =which-key-key-face= | Every key sequence | =:inherit font-lock-constant-face= | | =which-key-separator-face= | The separator (→) | =:inherit font-lock-comment-face= | | =which-key-note-face= | Hints and notes | =:inherit which-key-separator-face= | | =which-key-special-key-face= | User-defined special keys | =:inherit which-key-key-face :inverse-video t :weight bold= | | =which-key-group-description-face= | Command groups (i.e, keymaps) | =:inherit font-lock-keyword-face= | | =which-key-command-description-face= | Commands not in local-map | =:inherit font-lock-function-name-face= | | =which-key-local-map-description-face= | Commands in local-map | =:inherit which-key-command-description-face= |

The last two deserve some explanation. A command lives in one of many possible
keymaps. You can distinguish between local maps, which depend on the buffer you
are in, which modes are active, etc., and the global map which applies
everywhere. It might be useful for you to distinguish between the two. One way
to do this is to remove the default face from
=which-key-command-description-face= like this

#+BEGIN_SRC emacs-lisp

(set-face-attribute 'which-key-command-description-face nil :inherit nil) #+END_SRC

another is to make the local map keys appear in bold

#+BEGIN_SRC emacs-lisp

(set-face-attribute 'which-key-local-map-description-face nil :weight 'bold) #+END_SRC

You can also use =M-x customize-face= to customize any of the above faces to
your liking.

*** Other Options #+NAME: #other-options The options below are also available through customize. Their defaults are shown.

#+BEGIN_SRC emacs-lisp
  ;; Set the time delay (in seconds) for the which-key popup to appear. A value of
  ;; zero might cause issues so a non-zero value is recommended.
  (setq which-key-idle-delay 1.0)

  ;; Set the maximum length (in characters) for key descriptions (commands or
  ;; prefixes). Descriptions that are longer are truncated and have ".." added.
  ;; This can also be a float (fraction of available width) or a function.
  (setq which-key-max-description-length 27)

  ;; Use additional padding between columns of keys. This variable specifies the
  ;; number of spaces to add to the left of each column.
  (setq which-key-add-column-padding 0)

  ;; The maximum number of columns to display in the which-key buffer. nil means
  ;; don't impose a maximum.
  (setq which-key-max-display-columns nil)

  ;; Set the separator used between keys and descriptions. Change this setting to
  ;; an ASCII character if your font does not show the default arrow. The second
  ;; setting here allows for extra padding for Unicode characters. which-key uses
  ;; characters as a means of width measurement, so wide Unicode characters can
  ;; throw off the calculation.
  (setq which-key-separator " → " )
  (setq which-key-unicode-correction 3)

  ;; Set the prefix string that will be inserted in front of prefix commands
  ;; (i.e., commands that represent a sub-map).
  (setq which-key-prefix-prefix "+" )

  ;; Set the special keys. These are automatically truncated to one character and
  ;; have which-key-special-key-face applied. Disabled by default. An example
  ;; setting is
  ;; (setq which-key-special-keys '("SPC" "TAB" "RET" "ESC" "DEL"))
  (setq which-key-special-keys nil)

  ;; Show the key prefix on the left, top, or bottom (nil means hide the prefix).
  ;; The prefix consists of the keys you have typed so far. which-key also shows
  ;; the page information along with the prefix.
  (setq which-key-show-prefix 'left)

  ;; Set to t to show the count of keys shown vs. total keys in the mode line.
  (setq which-key-show-remaining-keys nil)
#+END_SRC

** Support for Third-Party Libraries Some support is provided for third-party libraries which don't use standard methods of looking up commands. Some of these need to be enabled explicitly. This code includes some hacks, so please report any problems. *** Key-chord Enabled by default. *** Evil operators Evil motions and text objects following an operator like =d= are not all looked up in a standard way. Support is controlled through =which-key-allow-evil-operators= which should be non-nil if evil is loaded before which-key and through =which-key-show-operator-state-maps= which needs to be enabled explicitly because it is more of a hack. The former allows for the inner and outer text object maps to show, while the latter shows motions as well. *** God-mode Call =(which-key-enable-god-mode-support)= after loading god-mode to enable support for god-mode key sequences. This is new and experimental, so please report any issues. ** More Examples *** Nice Display with Split Frame Unlike guide-key, which-key looks good even if the frame is split into several windows. #+CAPTION: which-key in a frame with 3 horizontal splits [[./img/which-key-right-split.png]]

#+CAPTION: which-key in a frame with 2 vertical splits
[[./img/which-key-bottom-split.png]]

** Known Issues

  • A few users have reported crashes related to which-key popups when quitting a key sequence with =C-g=. A possible fix is discussed in [[https://github.com/justbur/emacs-which-key/issues/130][this issue]]. ** Thanks Special thanks to
  • [[https://github.com/bmag][@bmag]] for helping with the initial development and finding many bugs.
  • [[https://github/iqbalansari][@iqbalansari]] who among other things adapted the code to make =which-key-show-top-level= possible.