config.phundrak.com/docs/emacs/keybinding-managers.org

5.0 KiB
Raw Blame History

Emacs — Keybinding Managers

Keybinding Managers

Which-key

Which key is, I think, one of my favorite quality of life package. When you begin a keybind, Emacs will show you all keybinds you can follow the first one with in order to form a full keychord. Very useful when you have a lot of keybinds and dont remember exactly what is what.

(use-package which-key
  :straight (:build t)
  :defer t
  :init (which-key-mode)
  :diminish which-key-mode
  :config
  (setq which-key-idle-delay 1))

General

General is an awesome package for managing keybindings. Not only is it oriented towards keychords by default (which I love), but it also provides some integration with evil so that we can declare keybindings for certain states only! This is a perfect replacement for define-key, evil-define-key, and any other function for defining keychords. And it is also possible to declare a prefix for my keybindings! By default, all keybinds will be prefixed with SPC and keybinds related to a specific mode (often major modes) will be prefixed by a comma , (and by C-SPC and M-m respectively when in insert-mode or emacs-mode). You can still feel some influence from my Spacemacs years here.

(use-package general
  :straight (:build t)
  :init
  (general-auto-unbind-keys)
  :config
  (general-create-definer phundrak/undefine
    :keymaps 'override
    :states '(normal emacs))
  (general-create-definer phundrak/evil
    :states '(normal))
  (general-create-definer phundrak/leader-key
    :states '(normal insert visual emacs)
    :keymaps 'override
    :prefix "SPC"
    :global-prefix "C-SPC")
  (general-create-definer phundrak/major-leader-key
    :states '(normal insert visual emacs)
    :keymaps 'override
    :prefix ","
    :global-prefix "M-m"))

Evil

Evil emulates most of vims keybinds, because lets be honest here, they are much more comfortable than Emacs.

(use-package evil
  :straight (:build t)
  :after (general)
  :init
  (setq evil-want-integration t
        evil-want-keybinding nil
        evil-want-C-u-scroll t
        evil-want-C-i-jump nil)
  (require 'evil-vars)
  :config
  <<evil-undefine-keys>>
  <<evil-bepo>>
  (evil-mode 1)
  (setq evil-want-fine-undo t) ; more granular undo with evil
  (evil-set-initial-state 'messages-buffer-mode 'normal)
  (evil-set-initial-state 'dashboard-mode 'normal))

I want to undefine some default keybinds of Evil because it does not match my workflow. Namely, I use the space key and the comma as leaders for my keybinds, and Im way too used to Emacs C-t, C-a, C-e, and C-y.

(evil-global-set-key 'motion "t" 'evil-next-visual-line)
(evil-global-set-key 'motion "s" 'evil-previous-visual-line)

(general-define-key
 :keymaps 'evil-motion-state-map
 "SPC" nil
 ","   nil)
(general-define-key
 :keymaps 'evil-insert-state-map
 "C-t" nil)
(general-define-key
 :keymaps 'evil-insert-state-map
 "U"   nil
 "C-a" nil
 "C-y" nil
 "C-e" nil)

Something else that really bugs me is I use the bépo layout, which is not at all like the qwerty layout. For instance, hjkl becomes ctsr. Thus, I need some bépo-specific changes.

(dolist (key '("c" "C" "t" "T" "s" "S" "r" "R" "h" "H" "j" "J" "k" "K" "l" "L"))
  (general-define-key :states 'normal key nil))

(general-define-key
 :states 'motion
 "h" 'evil-replace
 "H" 'evil-replace-state
 "j" 'evil-find-char-to
 "J" 'evil-find-char-to-backward
 "k" 'evil-substitute
 "K" 'evil-smart-doc-lookup
 "l" 'evil-change
 "L" 'evil-change-line

 "c" 'evil-backward-char
 "C" 'evil-window-top
 "t" 'evil-next-visual-line
 "T" 'evil-join
 "s" 'evil-previous-visual-line
 "S" 'evil-lookup
 "r" 'evil-forward-char
 "R" 'evil-window-bottom)

This package enables and integrates Evil into a lot of different modes, such as org-mode, dired, mu4e, etc. Again, I need some additional code compared to most people due to the bépo layout.

(use-package evil-collection
  :after evil
  :straight (:build t)
  :config
  ;; bépo conversion
  (defun my/bépo-rotate-evil-collection (_mode mode-keymaps &rest _rest)
    (evil-collection-translate-key 'normal mode-keymaps
      ;; bépo ctsr is qwerty hjkl
      "c" "h"
      "t" "j"
      "s" "k"
      "r" "l"
      ;; add back ctsr
      "h" "c"
      "j" "t"
      "k" "s"
      "l" "r"))
  (add-hook 'evil-collection-setup-hook #'my/bépo-rotate-evil-collection)
  (evil-collection-init))

Hydra

Hydra is a simple menu creator for keybindings.

(use-package hydra
  :straight (:build t)
  :defer t)