Fix key-parse problem with C-x ( ... sequences
authorLars Ingebrigtsen <larsi@gnus.org>
Tue, 3 May 2022 14:19:50 +0000 (16:19 +0200)
committerLars Ingebrigtsen <larsi@gnus.org>
Tue, 3 May 2022 14:19:50 +0000 (16:19 +0200)
* lisp/keymap.el (key-parse): Move the read-kbd-macro compat code
from here...
* lisp/subr.el (kbd): ... to here.  (And fix the logic, too.)
This allows `key-parse' to have a less puzzling result while
maintaining backwards compatibility (bug#38775).

lisp/keymap.el
lisp/subr.el
test/lisp/subr-tests.el

index db37d80b363f811acf827fc00ac2de2104103e55..71454eba5e5fb53d897945d08bebcd1c38cfc080 100644 (file)
@@ -281,18 +281,7 @@ See `kbd' for a descripion of KEYS."
           (when key
             (dolist (_ (number-sequence 1 times))
               (setq res (vconcat res key))))))
-      (if (and (>= (length res) 4)
-               (eq (aref res 0) ?\C-x)
-               (eq (aref res 1) ?\()
-               (eq (aref res (- (length res) 2)) ?\C-x)
-               (eq (aref res (- (length res) 1)) ?\)))
-          (apply #'vector (let ((lres (append res nil)))
-                            ;; Remove the first and last two elements.
-                            (setq lres (cdr (cdr lres)))
-                            (nreverse lres)
-                            (setq lres (cdr (cdr lres)))
-                            (nreverse lres)))
-        res))))
+      res)))
 
 (defun key-valid-p (keys)
   "Say whether KEYS is a valid key.
index cb7572423af6454810976c845b35b43661b17686..dec3b9190ed24ff9bb7b956fb12bfd5ff21d8fe1 100644 (file)
@@ -941,6 +941,20 @@ Here's some example key sequences:
 For an approximate inverse of this, see `key-description'."
   (declare (pure t) (side-effect-free t))
   (let ((res (key-parse keys)))
+    ;; For historical reasons, parse "C-x ( C-d C-x )" as "C-d", since
+    ;; `kbd' used to be a wrapper around `read-kbd-macro'.
+    (when (and (>= (length res) 4)
+               (eq (aref res 0) ?\C-x)
+               (eq (aref res 1) ?\()
+               (eq (aref res (- (length res) 2)) ?\C-x)
+               (eq (aref res (- (length res) 1)) ?\)))
+      (setq res (apply #'vector (let ((lres (append res nil)))
+                                  ;; Remove the first and last two elements.
+                                  (setq lres (cddr lres))
+                                  (setq lres (nreverse lres))
+                                  (setq lres (cddr lres))
+                                  (nreverse lres)))))
+
     (if (not (memq nil (mapcar (lambda (ch)
                                  (and (numberp ch)
                                       (<= 0 ch 127)))
index 62cf2266d61d70233b5c2d3b6385ca0d28dd34e6..a4f531ea4e63b84d82b40d09a3d92674f950bea2 100644 (file)
@@ -1053,5 +1053,9 @@ final or penultimate step during initialization."))
   (should (equal (string-lines "foo\n\n\nbar" t t)
                  '("foo\n" "bar"))))
 
+(defun test-keymap-parse-macros ()
+  (should (equal (key-parse "C-x ( C-d C-x )") [24 40 4 24 41]))
+  (should (equal (kbd "C-x ( C-d C-x )") "\ 4")))
+
 (provide 'subr-tests)
 ;;; subr-tests.el ends here