First, we define a global prefix key:
(general-create-definer global-definer
:keymaps 'override
:states '(insert emacs normal hybrid motion visual operator)
:prefix "SPC"
:non-normal-prefix "S-SPC")
Bind top level, global commands like so:
(global-definer
"!" 'shell-command
":" 'eval-expression)
To ease the creation of nested menus, we define a macro:
(defmacro +general-global-menu! (name infix-key &rest body)
"Create a definer named +general-global-NAME wrapping global-definer.
Create prefix map: +general-global-NAME. Prefix bindings in BODY with INFIX-KEY."
(declare (indent 2))
`(progn
(general-create-definer ,(intern (concat "+general-global-" name))
:wrapping global-definer
:prefix-map (quote ,(intern (concat "+general-global-" name "-map")))
:infix ,infix-key
:wk-full-keys nil
"" '(:ignore t :which-key ,name))
(,(intern (concat "+general-global-" name))
,@body)))
This macro defines top-level nested menus. e.g. a menu for “buffer” bindings:
(+general-global-menu! "buffer" "b"
"d" 'kill-current-buffer
"o" '((lambda () (interactive) (switch-to-buffer nil))
:which-key "other-buffer")
"p" 'previous-buffer
"r" 'rename-buffer
"M" '((lambda () (interactive) (switch-to-buffer "*Messages*"))
:which-key "messages-buffer")
"n" 'next-buffer
"s" '((lambda () (interactive) (switch-to-buffer "*scratch*"))
:which-key "scratch-buffer")
"TAB" '((lambda () (interactive) (switch-to-buffer nil))
:which-key "other-buffer"))
You can specify per-package keybindings with the :general
use-package keyword.
For example, here’s a minimal helm configuration that binds SPC bb
to helm-mini
:
(use-package helm
:init (require 'helm-config)
:defer 1
:config
(helm-mode)
:general
(+general-global-buffer
"b" 'helm-mini))
We define a global-leader definer to access major-mode specific bindings:
(general-create-definer global-leader
:keymaps 'override
:states '(emacs normal hybrid motion visual operator)
:prefix "SPC m"
"" '(:ignore t :which-key (lambda (arg) `(,(cadr (split-string (car arg) " ")) . ,(replace-regexp-in-string "-mode$" "" (symbol-name major-mode))))))
Again, we use the :general
keyword to bind mode-specific bindings.
For example, with the following, we can eval-buffer
when in emacs-lisp-mode
or lisp-interaction-mode
by pressing SPC m e b
:
(use-package elisp-mode
;;this is a built in package, so we don't want to try and install it
:ensure nil
:general
(global-leader
;;specify the major modes these should apply to:
:major-modes
'(emacs-lisp-mode lisp-interaction-mode t)
;;and the keymaps:
:keymaps
'(emacs-lisp-mode-map lisp-interaction-mode-map)
"e" '(:ignore t :which-key "eval")
"eb" 'eval-buffer
"ed" 'eval-defun
"ee" 'eval-expression
"ep" 'pp-eval-last-sexp
"es" 'eval-last-sexp
"i" 'elisp-index-search))
Hope this helps. ~ Nicholas Vollmer
I provided the answer to that question before you opened that issue here:
radian-software/straight.el#891 (comment)
I disabled issues on my personal config. I'm interested in sharing it so that others may take inspiration from it, but I'm not generally interested in providing support for it.