From 15e4e45dbddb5fb387d1d3fda43b1b72d054fb41 Mon Sep 17 00:00:00 2001 From: Joel Pettersson Date: Thu, 12 Jan 2023 02:50:46 +0100 Subject: [PATCH] Allow describing commands when using :bind in use-package In `use-package' declarations, `:bind' entries turn into individual `bind-key' forms when (partially) expanded; `bind-key' is a macro defined in the `use-package' package that wraps `define-key'. It accepts a cons `(STRING . DEFN)' as its `COMMAND' argument---as an alternative to a plain command name---where `STRING' is a description of the command named `DEFN'. This allows the user to provide a custom description of a command when binding it to a key. The description can be used by other code dealing with key bindings. For example, the GNU ELPA `which-key' package displays the description when showing key bindings, instead of the plain command name. Previously, however, `:bind' did not accept such description/command conses---it only ever expected plain command names. These changes teach `:bind' how to handle description/command conses. In addition to passing them on to `bind-key', `:bind' is taught to look at the command names inside the conses and deal with them the same way plain commands names are dealt with, including having corresponding `:commands' entries set up so that autoloading works as intended. * doc/misc/use-package.texi (Key bindings): Document `:bind''s new ability to handle description/command conses in key bindings. * etc/NEWS: Mention this new feature of `use-package'. * lisp/use-package/bind-key.el (bind-key): Update macro docs to reflect these changes. * lisp/use-package/use-package-bind-key.el (use-package-normalize-binder): Allow description/command conses in `:bind' entries. * lisp/use-package/use-package-core.el (use-package-autoloads-mode): Ensure autoloads are set up for description/command conses. * test/lisp/use-package/use-package-tests.el (use-package-test/:bind-1, use-package-test/:bind-2): Include key bindings with description/command conses in existing tests. --- doc/misc/use-package.texi | 34 ++++++++++++++++++---- etc/NEWS | 10 +++++++ lisp/use-package/bind-key.el | 3 +- lisp/use-package/use-package-bind-key.el | 11 ++++++- lisp/use-package/use-package-core.el | 14 +++++++-- test/lisp/use-package/use-package-tests.el | 8 ++--- 6 files changed, 66 insertions(+), 14 deletions(-) diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi index 87105c4db0..574dd0d965 100644 --- a/doc/misc/use-package.texi +++ b/doc/misc/use-package.texi @@ -869,11 +869,14 @@ Global keybindings @findex :bind To bind keys globally, the @code{:bind} keyword takes as its argument either a single cons or a list of conses. Each cons has the form -@w{@code{(@var{key} . @var{command})}}, where @var{key} is a string -indicating the key to bind, and @var{command} is the name of a command -(a symbol). The syntax for the keys is similar to the syntax used by -the @code{kbd} function (see @ref{Init Rebinding,,, emacs, GNU Emacs -Manual}, for more information). +@w{@code{(@var{key} . @var{definition})}}, where @var{key} is a string +indicating the key to bind, and @var{definition} is the name of a +command (a symbol). Alternatively, @var{definition} may be a cons +@w{@code{(@var{desc} . @var{command})}}, where @var{desc} is a string +describing @var{command}, which is the name of a command to bind +@var{key} to. The syntax for the keys is similar to the syntax used +by the @code{kbd} function (see @ref{Init Rebinding,,, emacs, GNU +Emacs Manual}, for more information). @subheading Using @code{:bind} with a single cons @@ -933,6 +936,27 @@ Global keybindings @end group @end lisp +@subheading Providing custom descriptions of commands + +When binding keys to commands with @code{:bind}, custom descriptions +of the commands may optionally be provided. + +Examples: + +@lisp +@group +(use-package avy + :bind ("C-:" ("Jump to char" . avy-goto-char) + "M-g f" ("Jump to line" . avy-goto-line))) +@end group +@end lisp + +@noindent +These descriptions can be used by other code that deals with key +bindings. For example, the @acronym{GNU} @acronym{ELPA} package +@file{which-key} displays them when showing key bindings, instead of +the plain command names. + @subheading Remapping commands @cindex remapping commands with @code{:bind} @cindex @code{:bind}, and remapping of commands diff --git a/etc/NEWS b/etc/NEWS index 90a6c6a052..251d55993d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -102,6 +102,16 @@ If you want to get back the old behavior, set the user option to the value (setopt gdb-locals-table-row-config `((type . 0) (name . 0) (value . ,gdb-locals-value-limit))) +** Declarative package configuration + +*** Custom descriptions of commands can now be provided when binding keys. +The 'bind-key' macro from 'use-package' already had support for +providing a custom description of the command in a key binding. Now, +it is possible to do the same when defining key bindings with ':bind'. +These descriptions can be used by other code that deals with key +bindings. For example, the GNU ELPA 'which-key' package displays them +when showing key bindings, instead of the plain command names. + ** VC --- diff --git a/lisp/use-package/bind-key.el b/lisp/use-package/bind-key.el index b216c668d8..178e377740 100644 --- a/lisp/use-package/bind-key.el +++ b/lisp/use-package/bind-key.el @@ -166,7 +166,8 @@ bind-key spelled-out keystrokes, e.g., \"C-c C-z\". See the documentation of `edmacro-mode' for details. -COMMAND must be an interactive function or lambda form. +COMMAND must be an interactive function, lambda form, or a cons +`(STRING . DEFN)'. KEYMAP, if present, should be a keymap variable or symbol. For example: diff --git a/lisp/use-package/use-package-bind-key.el b/lisp/use-package/use-package-bind-key.el index 47eb066eba..72ff3fdabd 100644 --- a/lisp/use-package/use-package-bind-key.el +++ b/lisp/use-package/use-package-bind-key.el @@ -69,8 +69,17 @@ use-package-normalize-binder (let ((arg args) args*) (while arg - (let ((x (car arg))) + (let ((x (car arg)) + (y (cadr arg))) (cond + ;; (KEY DESC . COMMAND), i.e. (KEY . (DESC . COMMAND)) + ((and (or (stringp x) + (vectorp x)) + (consp y) + (stringp (car y)) + (or (use-package-recognize-function (cdr y) t #'stringp))) + (setq args* (nconc args* (list (cons x y)))) + (setq arg (cddr arg))) ;; (KEY . COMMAND) ((and (consp x) (or (stringp (car x)) diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el index 379e119b60..ee3845652d 100644 --- a/lisp/use-package/use-package-core.el +++ b/lisp/use-package/use-package-core.el @@ -961,10 +961,18 @@ use-package-normalize-mode (defun use-package-autoloads-mode (_name _keyword args) (mapcar - #'(lambda (x) (cons (cdr x) 'command)) + #'(lambda (x) + (cond + ((consp (cdr x)) + (cons (cddr x) 'command)) + ((consp x) + (cons (cdr x) 'command)))) (cl-remove-if-not #'(lambda (x) - (and (consp x) - (use-package-non-nil-symbolp (cdr x)))) + (or (and (consp x) + (use-package-non-nil-symbolp (cdr x))) + (and (consp x) + (consp (cdr x)) + (use-package-non-nil-symbolp (cddr x))))) args))) (defun use-package-handle-mode (name alist args rest state) diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el index 6374a0d103..673d567592 100644 --- a/test/lisp/use-package/use-package-tests.el +++ b/test/lisp/use-package/use-package-tests.el @@ -575,7 +575,7 @@ use-package-test-normalize/:bind-3 (ert-deftest use-package-test/:bind-1 () (match-expansion - (use-package foo :bind ("C-k" . key1) ("C-u" . key2)) + (use-package foo :bind ("C-k" . key1) ("C-u" ("Key 2" . key2))) `(progn (unless (fboundp 'key1) @@ -585,11 +585,11 @@ use-package-test/:bind-1 (autoload #'key2 "foo" nil t)) (bind-keys :package foo ("C-k" . key1) - ("C-u" . key2))))) + ("C-u" "Key 2" . key2))))) (ert-deftest use-package-test/:bind-2 () (match-expansion - (use-package foo :bind (("C-k" . key1) ("C-u" . key2))) + (use-package foo :bind (("C-k" . key1) ("C-u" ("Key 2" . key2)))) `(progn (unless (fboundp 'key1) (autoload #'key1 "foo" nil t)) @@ -597,7 +597,7 @@ use-package-test/:bind-2 (autoload #'key2 "foo" nil t)) (bind-keys :package foo ("C-k" . key1) - ("C-u" . key2))))) + ("C-u" "Key 2" . key2))))) (ert-deftest use-package-test/:bind-3 () (match-expansion -- 2.39.0