branch: elpa/with-simulated-input
commit e8738fe72cf572fda2b00b239f789c549a84b0e1
Author: Ryan C. Thompson <[email protected]>
Commit: Ryan C. Thompson <[email protected]>
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)