emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/with-simulated-input e8738fe72c 040/134: Fix issue #4 and


From: ELPA Syncer
Subject: [nongnu] elpa/with-simulated-input e8738fe72c 040/134: Fix issue #4 and add a test for it
Date: Mon, 10 Jan 2022 23:00:03 -0500 (EST)

branch: elpa/with-simulated-input
commit e8738fe72cf572fda2b00b239f789c549a84b0e1
Author: Ryan C. Thompson <rct@thompsonclan.org>
Commit: Ryan C. Thompson <rct@thompsonclan.org>

    Fix issue #4 and add a test for it
    
    The problem is that "execute-kbd-macro" can change the current buffer,
    so we work around this by manually switching to the buffer
    that's *supposed* to be current before doing anything else.
    
    See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=37396
---
 tests/test-with-simulated-input.el |  9 ++++++++
 with-simulated-input.el            | 47 +++++++++++++++++++++++++-------------
 2 files changed, 40 insertions(+), 16 deletions(-)

diff --git a/tests/test-with-simulated-input.el 
b/tests/test-with-simulated-input.el
index aee72e2641..24be75b80e 100644
--- a/tests/test-with-simulated-input.el
+++ b/tests/test-with-simulated-input.el
@@ -67,6 +67,15 @@
        (quit 'caught-quit))
      :to-be 'caught-quit))
 
+  ;; https://github.com/DarwinAwardWinner/with-simulated-input/issues/4
+  (it "should work inside code that switches buffer (issue #4)"
+    (let ((orig-current-buffer (current-buffer)))
+      (with-temp-buffer
+        (let ((temp-buffer (current-buffer)))
+          (with-simulated-input "a" (read-char))
+          (expect (current-buffer) :to-equal temp-buffer)
+          (expect (current-buffer) :not :to-equal orig-current-buffer)))))
+
   (describe "used with `completing-read'"
 
     :var (collection completing-read-function)
diff --git a/with-simulated-input.el b/with-simulated-input.el
index 99c90aec45..bcbd4b511b 100644
--- a/with-simulated-input.el
+++ b/with-simulated-input.el
@@ -162,6 +162,7 @@ in `progn'."
   (declare (indent 1))
   `(cl-letf*
        ((lexenv (wsi-current-lexical-environment))
+        (correct-current-buffer (current-buffer))
         (next-action-key (wsi-get-unbound-key))
         (result wsi--canary-sym)
         (thrown-error nil)
@@ -177,30 +178,23 @@ in `progn'."
         (keylist (if (listp keylist)
                      keylist
                    (list keylist)))
-        ;; Replace non-strings with `next-action-key' and concat
-        ;; everything together
-        (full-key-sequence
-         (cl-loop
-          for action in keylist
-          if (stringp action)
-          collect action into key-sequence-list
-          else
-          collect next-action-key into key-sequence-list
-          finally return
-          ;; Prepend and append `next-action-key' to run body and canary
-          (concat
-           next-action-key " "
-           (mapconcat #'identity key-sequence-list " ")
-           " " next-action-key)))
         ;; Extract non-string forms, adding body at the front and
         ;; canary at the back
         (action-list
          (nconc
-          (list body-form)
+          (list
+           ;; First we switch back to the correct buffer (since
+           ;; `execute-kbd-macro' switches to the wrong one).
+           (list 'switch-to-buffer correct-current-buffer)
+           ;; Then we run the body form
+           body-form)
+          ;; Then we run each of the actions specified in KEYS
           (cl-loop
            for action in keylist
            if (not (stringp action))
            collect action)
+          ;; Finally we throw the canary if we read past the end of
+          ;; the input.
           (list end-of-actions-form)))
         ;; Wrap each action in a lexical closure so it can refer to
         ;; variables from the caller.
@@ -208,6 +202,27 @@ in `progn'."
          (cl-loop
           for action in action-list
           collect (wsi-make-closure action lexenv)))
+        ;; Replace non-strings with `next-action-key' and concat
+        ;; everything together
+        (full-key-sequence
+         (cl-loop
+          for action in keylist
+          if (stringp action)
+          collect action into key-sequence-list
+          else
+          collect next-action-key into key-sequence-list
+          finally return
+          ;; Prepend and append `next-action-key' as appropriate to
+          ;; switch buffer, run body, and throw canary.
+          (concat
+           ;; Switch to correct buffer
+           next-action-key " "
+           ;; Start executing body
+           next-action-key " "
+           ;; Execute the actual key sequence
+           (mapconcat #'identity key-sequence-list " ")
+           ;; Throw the canary if BODY reads past the provided input
+           " " next-action-key)))
         ;; Define the next action command with lexical scope so it can
         ;; access `action-closures'.
         ((symbol-function 'wsi-run-next-action)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]