Support a new ["..."] key binding syntax
* doc/lispref/keymaps.texi (Key Sequences): (Changing Key Bindings): Document the various key syntaxes. * lisp/emacs-lisp/byte-opt.el (byte-optimize-define-key) (byte-optimize-define-keymap) (byte-optimize-define-keymap--define): New functions to check and expand ["..."] syntax at compile time. * src/keymap.c (Fdefine_key): Understand the ["..."] syntax. (syms_of_keymap): Define `kbd' symbols.
This commit is contained in:
parent
8122501fca
commit
e36d3fc452
4 changed files with 142 additions and 22 deletions
|
@ -1186,6 +1186,67 @@ See Info node `(elisp) Integer Basics'."
|
|||
|
||||
(put 'concat 'byte-optimizer #'byte-optimize-concat)
|
||||
|
||||
(defun byte-optimize-define-key (form)
|
||||
"Expand key bindings in FORM."
|
||||
(let ((key (nth 2 form)))
|
||||
(if (and (vectorp key)
|
||||
(= (length key) 1)
|
||||
(stringp (aref key 0)))
|
||||
;; We have key on the form ["C-c C-c"].
|
||||
(if (not (kbd-valid-p (aref key 0)))
|
||||
(error "Invalid `kbd' syntax: %S" key)
|
||||
(list (nth 0 form) (nth 1 form)
|
||||
(kbd (aref key 0)) (nth 4 form)))
|
||||
;; No improvement.
|
||||
form)))
|
||||
|
||||
(put 'define-key 'byte-optimizer #'byte-optimize-define-key)
|
||||
|
||||
(defun byte-optimize-define-keymap (form)
|
||||
"Expand key bindings in FORM."
|
||||
(let ((result nil)
|
||||
(orig-form form)
|
||||
improved)
|
||||
(push (pop form) result)
|
||||
(while (and form
|
||||
(keywordp (car form))
|
||||
(not (eq (car form) :menu)))
|
||||
(push (pop form) result)
|
||||
(when (null form)
|
||||
(error "Uneven number of keywords in %S" form))
|
||||
(push (pop form) result))
|
||||
;; Bindings.
|
||||
(while form
|
||||
(let ((key (pop form)))
|
||||
(if (and (vectorp key)
|
||||
(= (length key) 1)
|
||||
(stringp (aref key 0)))
|
||||
(progn
|
||||
(unless (kbd-valid-p (aref key 0))
|
||||
(error "Invalid `kbd' syntax: %S" key))
|
||||
(push (kbd (aref key 0)) result)
|
||||
(setq improved t))
|
||||
;; No improvement.
|
||||
(push key result)))
|
||||
(when (null form)
|
||||
(error "Uneven number of key bindings in %S" form))
|
||||
(push (pop form) result))
|
||||
(if improved
|
||||
(nreverse result)
|
||||
orig-form)))
|
||||
|
||||
(defun byte-optimize-define-keymap--define (form)
|
||||
"Expand key bindings in FORM."
|
||||
(let ((optimized (byte-optimize-define-keymap (nth 1 form))))
|
||||
(if (eq optimized (nth 1 form))
|
||||
;; No improvement.
|
||||
form
|
||||
(list (car form) optimized))))
|
||||
|
||||
(put 'define-keymap 'byte-optimizer #'byte-optimize-define-keymap)
|
||||
(put 'define-keymap--define 'byte-optimizer
|
||||
#'byte-optimize-define-keymap--define)
|
||||
|
||||
;; I'm not convinced that this is necessary. Doesn't the optimizer loop
|
||||
;; take care of this? - Jamie
|
||||
;; I think this may some times be necessary to reduce ie (quote 5) to 5,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue