]> git.eshelyaron.com Git - emacs.git/commitdiff
* lisp/international/mule-cmds.el: Fix bug#38642
authorStefan Monnier <monnier@iro.umontreal.ca>
Fri, 20 Dec 2019 22:34:38 +0000 (17:34 -0500)
committerStefan Monnier <monnier@iro.umontreal.ca>
Fri, 20 Dec 2019 22:34:38 +0000 (17:34 -0500)
(universal-coding-system-argument): Adjust the code to the way
`universal-argument` works nowadays.  Handle `prefix-arg` a bit more
like `command_loop` does.

* test/lisp/international/mule-tests.el
(mule-cmds--test-universal-coding-system-argument): New test.

lisp/international/mule-cmds.el
test/lisp/international/mule-tests.el

index e4f5bb2a5f05e35a25a2d825bbcdd1f9e0480ca5..0a8a4aa6610c0b7b9f17cfd0a59ab3f91ca81551 100644 (file)
@@ -295,10 +295,14 @@ wrong, use this command again to toggle back to the right mode."
                (format "Coding system for following command (default %s): " default)
              "Coding system for following command: ")
            default))))
+  ;; FIXME: This "read-key-sequence + call-interactively" loop is trying to
+  ;; reproduce the normal command loop, but this "can't" be done faithfully so
+  ;; it necessarily suffers from breakage in corner cases (e.g. it fails to run
+  ;; pre/post-command-hook, doesn't properly set this-command/last-command, it
+  ;; doesn't handle keyboard macros, ...).
   (let* ((keyseq (read-key-sequence
                  (format "Command to execute with %s:" coding-system)))
-        (cmd (key-binding keyseq))
-        prefix)
+        (cmd (key-binding keyseq)))
     ;; read-key-sequence ignores quit, so make an explicit check.
     (if (equal last-input-event (nth 3 (current-input-mode)))
        (keyboard-quit))
@@ -309,28 +313,21 @@ wrong, use this command again to toggle back to the right mode."
       (while (progn
               (setq keyseq (read-key-sequence nil t)
                     cmd (key-binding keyseq t))
-              (not (eq cmd 'universal-argument-other-key)))
-       (let ((current-prefix-arg prefix-arg)
-             ;; Have to bind `last-command-event' here so that
-             ;; `digit-argument', for instance, can compute the
-             ;; `prefix-arg'.
-             (last-command-event (aref keyseq 0)))
-         (call-interactively cmd)))
-
-      ;; This is the final call to `universal-argument-other-key', which
-      ;; sets the final `prefix-arg'.
-      (let ((current-prefix-arg prefix-arg))
-       (call-interactively cmd))
-
-      ;; Read the command to execute with the given `prefix-arg'.
-      (setq prefix prefix-arg
-           keyseq (read-key-sequence nil t)
-           cmd (key-binding keyseq)))
+              (memq cmd '(negative-argument digit-argument
+                          universal-argument-more)))
+       (setq current-prefix-arg prefix-arg prefix-arg nil)
+       ;; Have to bind `last-command-event' here so that
+       ;; `digit-argument', for instance, can compute the
+       ;; `prefix-arg'.
+       (setq last-command-event (aref keyseq 0))
+       (call-interactively cmd)))
 
     (let ((coding-system-for-read coding-system)
          (coding-system-for-write coding-system)
-         (coding-system-require-warning t)
-         (current-prefix-arg prefix))
+         (coding-system-require-warning t))
+      (setq current-prefix-arg prefix-arg prefix-arg nil)
+      ;; Have to bind `last-command-event' e.g. for `self-insert-command'.
+      (setq last-command-event (aref keyseq 0))
       (message "")
       (call-interactively cmd))))
 
index 678cbc297381762f9ab07522581190f6b640459d..881d92a2cae88e67ddfca6fffb5245fe43192af2 100644 (file)
   (should (equal (encode-coding-char ?a 'ebcdic-int) "\201"))
   (should (not (multibyte-string-p (encode-coding-char ?a 'utf-8)))))
 
+(ert-deftest mule-cmds--test-universal-coding-system-argument ()
+  (skip-unless (not noninteractive))
+  (should (equal "ccccccccccccccccab"
+                 (let ((enable-recursive-minibuffers t)
+                       (unread-command-events
+                        (append (kbd "C-x RET c u t f - 8 RET C-u C-u c a b RET") nil)))
+                   (read-string "prompt:")))))
+
 ;; Stop "Local Variables" above causing confusion when visiting this file.
 \f