From: Lars Ingebrigtsen Date: Tue, 5 Oct 2021 08:34:37 +0000 (+0200) Subject: Change the call convention for `defvar-keymap' X-Git-Tag: emacs-29.0.90~3671^2~654 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=4103123806311aa42f8ee22082015c0a7c3e30dd;p=emacs.git Change the call convention for `defvar-keymap' * doc/lispref/keymaps.texi (Changing Key Bindings): Adjust documentation. * lisp/simple.el (special-mode-map): * lisp/net/shr.el (shr-map): * lisp/net/eww.el (eww-link-keymap): (eww-mode-map): (eww-submit-map): (eww-textarea-map): (eww-bookmark-mode-map): (eww-history-mode-map): (eww-buffers-mode-map): * lisp/gnus/message.el (message-mode-map): * lisp/gnus/gnus-html.el (gnus-html-image-map): * lisp/gnus/gnus-eform.el (gnus-edit-form-mode-map): * lisp/gnus/gnus-dired.el (gnus-dired-mode-map): * lisp/gnus/gnus-bookmark.el (gnus-bookmark-bmenu-mode-map): Adjust usage of `defvar-keymap'. * lisp/subr.el (define-keymap, define-keymap--define): Change how these functions call each other. (defvar-keymap): Change interface to be more like `define-keymap'. * lisp/emacs-lisp/lisp-mode.el (lisp-indent--defvar-keymap): Remove. (lisp-indent-function): Don't use it. --- diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi index adee7ce58ed..407bdca5ed4 100644 --- a/doc/lispref/keymaps.texi +++ b/doc/lispref/keymaps.texi @@ -1455,13 +1455,13 @@ returned by @code{define-keymap} instead of the map itself. @end defun -@defmac defvar-keymap name options &rest defs +@defmac defvar-keymap name &key options... &rest pairs... By far, the most common thing to do with a keymap is to bind it to a variable. This is what virtually all modes do---a mode called @code{foo} almost always has a variable called @code{foo-mode-map}. This macro defines @var{name} as a variable, and passes @var{options} -and @var{defs} to @code{define-keymap}, and uses the result as the +and @var{pars} to @code{define-keymap}, and uses the result as the default value for the variable. @var{options} is like the keywords in @code{define-keymap}, but adds a @@ -1471,7 +1471,8 @@ variable should be. Here's an example: @lisp -(defvar-keymap eww-textarea-map (:parent text-mode-map) +(defvar-keymap eww-textarea-map + :parent text-mode-map "\r" #'forward-line [?\t] #'shr-next-link) @end lisp diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index a465d189b7a..57196dfec49 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -1162,18 +1162,6 @@ STATE is the `parse-partial-sexp' state for current position." (goto-char (scan-lists (point) -1 0)) (point))))))))))) -(defun lisp-indent--defvar-keymap (state) - "Return the indent position in the options part of a `defvar-keymap' form." - (save-excursion - (let ((parens (ppss-open-parens state))) - (and (equal (nth 1 parens) (ppss-innermost-start state)) - (progn - (goto-char (nth 0 parens)) - (looking-at-p "(defvar-keymap")) - (progn - (goto-char (ppss-innermost-start state)) - (1+ (current-column))))))) - (defun lisp-indent-function (indent-point state) "This function is the normal value of the variable `lisp-indent-function'. The function `calculate-lisp-indent' calls this to determine @@ -1207,12 +1195,10 @@ Lisp function does not specify a special indentation." (if (and (elt state 2) (not (looking-at "\\sw\\|\\s_"))) ;; car of form doesn't seem to be a symbol - (cond - ((lisp--local-defform-body-p state) - ;; We nevertheless check whether we are in flet-like form - ;; as we presume local function names could be non-symbols. - (lisp-indent-defform state indent-point)) - (t + (if (lisp--local-defform-body-p state) + ;; We nevertheless check whether we are in flet-like form + ;; as we presume local function names could be non-symbols. + (lisp-indent-defform state indent-point) (if (not (> (save-excursion (forward-line 1) (point)) calculate-lisp-indent-last-sexp)) (progn (goto-char calculate-lisp-indent-last-sexp) @@ -1224,28 +1210,25 @@ Lisp function does not specify a special indentation." ;; thing on that line has to be complete sexp since we are ;; inside the innermost containing sexp. (backward-prefix-chars) - (current-column))) - ;; Indent `defvar-keymap' arguments. - (or (lisp-indent--defvar-keymap state) - ;; Other forms. - (let ((function (buffer-substring (point) - (progn (forward-sexp 1) (point)))) - method) - (setq method (or (function-get (intern-soft function) - 'lisp-indent-function) - (get (intern-soft function) 'lisp-indent-hook))) - (cond ((or (eq method 'defun) - (and (null method) - (> (length function) 3) - (string-match "\\`def" function)) - ;; Check whether we are in flet-like form. - (lisp--local-defform-body-p state)) - (lisp-indent-defform state indent-point)) - ((integerp method) - (lisp-indent-specform method state - indent-point normal-indent)) - (method - (funcall method indent-point state)))))))) + (current-column)) + (let ((function (buffer-substring (point) + (progn (forward-sexp 1) (point)))) + method) + (setq method (or (function-get (intern-soft function) + 'lisp-indent-function) + (get (intern-soft function) 'lisp-indent-hook))) + (cond ((or (eq method 'defun) + (and (null method) + (> (length function) 3) + (string-match "\\`def" function)) + ;; Check whether we are in flet-like form. + (lisp--local-defform-body-p state)) + (lisp-indent-defform state indent-point)) + ((integerp method) + (lisp-indent-specform method state + indent-point normal-indent)) + (method + (funcall method indent-point state))))))) (defcustom lisp-body-indent 2 "Number of columns to indent the second line of a `(def...)' form." diff --git a/lisp/gnus/gnus-bookmark.el b/lisp/gnus/gnus-bookmark.el index a6b1a0762ba..171da9d17a0 100644 --- a/lisp/gnus/gnus-bookmark.el +++ b/lisp/gnus/gnus-bookmark.el @@ -419,8 +419,9 @@ That is, all information but the name." (defvar gnus-bookmark-bmenu-bookmark-column nil) (defvar gnus-bookmark-bmenu-hidden-bookmarks ()) -(defvar-keymap gnus-bookmark-bmenu-mode-map (:full t - :suppress 'nodigits) +(defvar-keymap gnus-bookmark-bmenu-mode-map + :full t + :suppress 'nodigits "q" #'quit-window "\C-m" #'gnus-bookmark-bmenu-select "v" #'gnus-bookmark-bmenu-select diff --git a/lisp/gnus/gnus-dired.el b/lisp/gnus/gnus-dired.el index 08a4289714b..be46d3a341d 100644 --- a/lisp/gnus/gnus-dired.el +++ b/lisp/gnus/gnus-dired.el @@ -53,7 +53,7 @@ (autoload 'message-buffers "message") (autoload 'gnus-print-buffer "gnus-sum") -(defvar-keymap gnus-dired-mode-map () +(defvar-keymap gnus-dired-mode-map "\C-c\C-m\C-a" #'gnus-dired-attach "\C-c\C-m\C-l" #'gnus-dired-find-file-mailcap "\C-c\C-m\C-p" #'gnus-dired-print) diff --git a/lisp/gnus/gnus-eform.el b/lisp/gnus/gnus-eform.el index 922e25e277e..b0aa58f0f28 100644 --- a/lisp/gnus/gnus-eform.el +++ b/lisp/gnus/gnus-eform.el @@ -48,7 +48,8 @@ (defvar gnus-edit-form-buffer "*Gnus edit form*") (defvar gnus-edit-form-done-function nil) -(defvar-keymap gnus-edit-form-mode-map (:parent emacs-lisp-mode-map) +(defvar-keymap gnus-edit-form-mode-map + :parent emacs-lisp-mode-map "\C-c\C-c" #'gnus-edit-form-done "\C-c\C-k" #'gnus-edit-form-exit) diff --git a/lisp/gnus/gnus-html.el b/lisp/gnus/gnus-html.el index e9fa819d0b5..c1815d3486c 100644 --- a/lisp/gnus/gnus-html.el +++ b/lisp/gnus/gnus-html.el @@ -71,12 +71,12 @@ fit these criteria." :group 'gnus-art :type 'float) -(defvar-keymap gnus-html-image-map () +(defvar-keymap gnus-html-image-map "u" #'gnus-article-copy-string "i" #'gnus-html-insert-image "v" #'gnus-html-browse-url) -(defvar-keymap gnus-html-displayed-image-map () +(defvar-keymap gnus-html-displayed-image-map "a" #'gnus-html-show-alt-text "i" #'gnus-html-browse-image "\r" #'gnus-html-browse-url diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index 7ca43d603ff..e165a0429fd 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -2868,8 +2868,9 @@ Consider adding this function to `message-header-setup-hook'" ;;; Set up keymap. -(defvar-keymap message-mode-map (:full t :parent text-mode-map - :doc "Message Mode keymap.") +(defvar-keymap message-mode-map + :full t :parent text-mode-map + :doc "Message Mode keymap." "\C-c?" #'describe-mode "\C-c\C-f\C-t" #'message-goto-to diff --git a/lisp/net/eww.el b/lisp/net/eww.el index afcf2ce8b44..24c63352105 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el @@ -271,10 +271,12 @@ See also `eww-form-checkbox-selected-symbol'." "text/html, text/plain, text/sgml, text/css, application/xhtml+xml, */*;q=0.01" "Value used for the HTTP 'Accept' header.") -(defvar-keymap eww-link-keymap (:parent shr-map) +(defvar-keymap eww-link-keymap + :parent shr-map "\r" #'eww-follow-link) -(defvar-keymap eww-image-link-keymap (:parent shr-map) +(defvar-keymap eww-image-link-keymap + :parent shr-map "\r" #'eww-follow-link) (defun eww-suggested-uris nil @@ -969,7 +971,7 @@ the like." (setq result highest)))) result)) -(defvar-keymap eww-mode-map () +(defvar-keymap eww-mode-map "g" #'eww-reload ;FIXME: revert-buffer-function instead! "G" #'eww [?\M-\r] #'eww-open-in-new-buffer @@ -1223,20 +1225,21 @@ just re-display the HTML already fetched." (defvar eww-form nil) -(defvar-keymap eww-submit-map () +(defvar-keymap eww-submit-map "\r" #'eww-submit [(control c) (control c)] #'eww-submit) -(defvar-keymap eww-submit-file () +(defvar-keymap eww-submit-file "\r" #'eww-select-file [(control c) (control c)] #'eww-submit) -(defvar-keymap eww-checkbox-map () +(defvar-keymap eww-checkbox-map " " #'eww-toggle-checkbox "\r" #'eww-toggle-checkbox [(control c) (control c)] #'eww-submit) -(defvar-keymap eww-text-map (:full t :parent text-mode-map) +(defvar-keymap eww-text-map + :full t :parent text-mode-map "\r" #'eww-submit [(control a)] #'eww-beginning-of-text [(control c) (control c)] #'eww-submit @@ -1245,14 +1248,16 @@ just re-display the HTML already fetched." [?\M-\t] #'shr-previous-link [backtab] #'shr-previous-link) -(defvar-keymap eww-textarea-map (:full t :parent text-mode-map) +(defvar-keymap eww-textarea-map + :full t :parent text-mode-map "\r" #'forward-line [(control c) (control c)] #'eww-submit [?\t] #'shr-next-link [?\M-\t] #'shr-previous-link [backtab] #'shr-previous-link) -(defvar-keymap eww-select-map (:doc "Map for select buttons") +(defvar-keymap eww-select-map + :doc "Map for select buttons" "\r" #'eww-change-select [follow-link] 'mouse-face [mouse-2] #'eww-change-select @@ -2079,7 +2084,7 @@ If ERROR-OUT, signal user-error if there are no bookmarks." 'eww-bookmark))) (eww-browse-url (plist-get bookmark :url)))) -(defvar-keymap eww-bookmark-mode-map () +(defvar-keymap eww-bookmark-mode-map [(control k)] #'eww-bookmark-kill [(control y)] #'eww-bookmark-yank "\r" #'eww-bookmark-browse @@ -2155,7 +2160,7 @@ If ERROR-OUT, signal user-error if there are no bookmarks." (pop-to-buffer-same-window buffer))) (eww-restore-history history))) -(defvar-keymap eww-history-mode-map () +(defvar-keymap eww-history-mode-map "\r" #'eww-history-browse "n" #'next-line "p" #'previous-line @@ -2274,7 +2279,7 @@ If ERROR-OUT, signal user-error if there are no bookmarks." (forward-line -1)) (eww-buffer-show)) -(defvar-keymap eww-buffers-mode-map () +(defvar-keymap eww-buffers-mode-map [(control k)] #'eww-buffer-kill "\r" #'eww-buffer-select "n" #'eww-buffer-show-next diff --git a/lisp/net/shr.el b/lisp/net/shr.el index 8f11b140fbe..72d2ab78676 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el @@ -247,7 +247,7 @@ and other things: (defvar shr-target-id nil "Target fragment identifier anchor.") -(defvar-keymap shr-map () +(defvar-keymap shr-map "a" #'shr-show-alt-text "i" #'shr-browse-image "z" #'shr-zoom-image diff --git a/lisp/simple.el b/lisp/simple.el index 114c841c2c3..5c6adcf4907 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -529,7 +529,8 @@ Other major modes are defined by comparison with this one." ;; Special major modes to view specially formatted data rather than files. -(defvar-keymap special-mode-map (:suppress t) +(defvar-keymap special-mode-map + :suppress t "q" #'quit-window " " #'scroll-up-command [?\S-\ ] #'scroll-down-command diff --git a/lisp/subr.el b/lisp/subr.el index e4819c4b2bd..f751c297ed9 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -6491,30 +6491,26 @@ KEY/DEFINITION pairs are as KEY and DEF in `define-key'. KEY can also be the special symbol `:menu', in which case DEFINITION should be a MENU form as accepted by `easy-menu-define'. -\(fn (&key FULL PARENT SUPPRESS NAME PREFIX KEYMAP) &rest [KEY DEFINITION]...)" - ;; Handle keywords. - (let ((options nil)) +\(fn &key FULL PARENT SUPPRESS NAME PREFIX KEYMAP &rest [KEY DEFINITION]...)" + (define-keymap--define definitions)) + +(defun define-keymap--define (definitions) + (let (full suppress parent name prefix keymap) + ;; Handle keywords. (while (and definitions - (keywordp (car definitions))) + (keywordp (car definitions)) + (not (eq (car definitions) :menu))) (let ((keyword (pop definitions))) (unless definitions (error "Missing keyword value for %s" keyword)) - (push keyword options) - (push (pop definitions) options))) - (define-keymap--define (nreverse options) definitions))) - -(defun define-keymap--define (options definitions) - (let (full suppress parent name prefix keymap) - (while options - (let ((keyword (pop options)) - (value (pop options))) - (pcase keyword - (:full (setq full value)) - (:keymap (setq keymap value)) - (:parent (setq parent value)) - (:suppress (setq suppress value)) - (:name (setq name value)) - (:prefix (setq prefix value))))) + (let ((value (pop definitions))) + (pcase keyword + (:full (setq full value)) + (:keymap (setq keymap value)) + (:parent (setq parent value)) + (:suppress (setq suppress value)) + (:name (setq name value)) + (:prefix (setq prefix value)))))) (when (and prefix (or full parent suppress keymap)) @@ -6544,27 +6540,31 @@ should be a MENU form as accepted by `easy-menu-define'. (define-key keymap key def))))) keymap))) -(defmacro defvar-keymap (name options &rest defs) - "Define NAME as a variable with a keymap definition. -See `define-keymap' for an explanation of OPTIONS. In addition, -the :doc keyword can be used in OPTIONS to add a doc string to NAME. +(defmacro defvar-keymap (variable-name &rest defs) + "Define VARIABLE-NAME as a variable with a keymap definition. +See `define-keymap' for an explanation of the keywords and KEY/DEFINITION. + +In addition to the keywords accepted by `define-keymap', this +macro also accepts a `:doc' keyword, which (if present) is used +as the variable documentation string. -DEFS is passed to `define-keymap' and should be a plist of -key/definition pairs." +\(fn VARIABLE-NAME &key DOC FULL PARENT SUPPRESS NAME PREFIX KEYMAP &rest [KEY DEFINITION]...)" (let ((opts nil) doc) - (while options - (let ((keyword (pop options))) - (unless options - (error "Uneven number of options")) + (while (and defs + (keywordp (car defs)) + (not (eq (car defs) :menu))) + (let ((keyword (pop defs))) + (unless defs + (error "Uneven number of keywords")) (if (eq keyword :doc) - (setq doc (pop options)) + (setq doc (pop defs)) (push keyword opts) - (push (pop options) opts)))) + (push (pop defs) opts)))) (unless (zerop (% (length defs) 2)) - (error "Uneven number of key definitions: %s" defs)) - `(defvar ,name - (define-keymap--define (list ,@(nreverse opts)) (list ,@defs)) + (error "Uneven number of key/definition pairs: %s" defs)) + `(defvar ,variable-name + (define-keymap--define (list ,@(nreverse opts) ,@defs)) ,@(and doc (list doc))))) ;;; subr.el ends here diff --git a/test/lisp/progmodes/elisp-mode-resources/elisp-indents.erts b/test/lisp/progmodes/elisp-mode-resources/elisp-indents.erts index 70642e230cb..d3eaac9ba5a 100644 --- a/test/lisp/progmodes/elisp-mode-resources/elisp-indents.erts +++ b/test/lisp/progmodes/elisp-mode-resources/elisp-indents.erts @@ -52,7 +52,8 @@ Name: defun-space Name: defvar-keymap =-= -(defvar-keymap eww-link-keymap (:copy shr-map - :foo bar) +(defvar-keymap eww-link-keymap + :copy shr-map + :foo bar "\r" #'eww-follow-link) =-=-=