summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/byte-opt.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/emacs-lisp/byte-opt.el')
-rw-r--r--lisp/emacs-lisp/byte-opt.el66
1 files changed, 66 insertions, 0 deletions
diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el
index c8990f23531..9b3b2e5ce14 100644
--- a/lisp/emacs-lisp/byte-opt.el
+++ b/lisp/emacs-lisp/byte-opt.el
@@ -1186,6 +1186,72 @@ 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)))
+ (unless (memq (car form)
+ '(:full :keymap :parent :suppress :name :prefix))
+ (error "Invalid keyword: %s" (car form)))
+ (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."
+ (if (not (consp (nth 1 form)))
+ 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,