Subject: Re: bug#52380: 28.0.50; [PATCH v2] run-python no longer focuses interpreter

From: Kévin Le Gouguec <[email-masked]>
Date: Sun, 12 Dec 2021 15:03:43 +0100

Lars Ingebrigtsen <[email-masked]> writes:

> Kévin Le Gouguec <[email-masked]> writes:
>
>> We could keep the call to (set-buffer) in run-python, but AFAICT it's
>> redundant for user interaction: pop-to-buffer selects the window, so
>> when the command loop returns to the user the *Python* buffer will be
>> made current anyway.
>>
>> Does this sound… sound?  If so, I'll submit a v2 amending
>> python-tests--bug31398.
>
> Sounds good to me.

Alright, here goes; after reviewing the original bug#31398 report, I
also took the liberty of adjusting the test name, commentary and
docstring.

It'd be great if the rationale bit of the commit message made it in 🙏

>From 9b61be086d9651a9f07962e20a1f5e09cd46f1f2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= <[email-masked]>
Date: Sun, 12 Dec 2021 12:24:24 +0100
Subject: [PATCH] Make `M-x run-python' select the window again

Interactively, we want M-x run-python to focus the interpreter buffer.
The previous code failed in two ways:

- the call to 'display-buffer' was not reached if an interpreter
  was already running,

- set-buffer is ineffectual if the interpreter's window is not
  selected: once Emacs returns to the command loop, the current buffer
  will revert back to what the selected window contains.

* lisp/progmodes/python.el (python-shell-make-comint): Handle the SHOW
argument regardless of whether an interpreter buffer exists, and use
pop-to-buffer to select the window.
(run-python): Delegate buffer management to
'python-shell-make-comint'.

* test/lisp/progmodes/python-tests.el
(python-tests--run-python-selects-window): Rename from
'python-tests--bug31398', and adjust assertions.
---
 lisp/progmodes/python.el            |  4 ++--
 test/lisp/progmodes/python-tests.el | 18 ++++++++++++------
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 47d8d1ce8e..b403de8b7a 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -2996,8 +2996,9 @@ python-shell-make-comint
                   (mapconcat #'identity args " ")))
             (with-current-buffer buffer
               (inferior-python-mode))
-            (when show (display-buffer buffer))
             (and internal (set-process-query-on-exit-flag process nil))))
+        (when show
+          (pop-to-buffer proc-buffer-name))
         proc-buffer-name))))
 
 ;;;###autoload
@@ -3029,7 +3030,6 @@ run-python
          (python-shell-make-comint
           (or cmd (python-shell-calculate-command))
           (python-shell-get-process-name dedicated) show)))
-    (set-buffer buffer)
     (get-buffer-process buffer)))
 
 (defun run-python-internal ()
diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el
index 15bda5c197..2d1ccdca41 100644
--- a/test/lisp/progmodes/python-tests.el
+++ b/test/lisp/progmodes/python-tests.el
@@ -5449,15 +5449,21 @@ python-tests--python-nav-end-of-statement--infloop
                     (python-nav-end-of-statement)))
     (should (eolp))))
 
-;; After call `run-python' the buffer running the python process is current.
-(ert-deftest python-tests--bug31398 ()
-  "Test for https://debbugs.gnu.org/31398 ."
+;; Interactively, `run-python' focuses the buffer running the
+;; interpreter.
+(ert-deftest python-tests--run-python-selects-window ()
+  "Test for bug#31398.  See also bug#44421 and bug#52380."
   (skip-unless (executable-find python-tests-shell-interpreter))
-  (let ((buffer (process-buffer (run-python nil nil 'show))))
-    (should (eq buffer (current-buffer)))
+  (let* ((buffer (process-buffer (run-python nil nil 'show)))
+         (window (get-buffer-window buffer)))
+    ;; We look at `selected-window' rather than `current-buffer'
+    ;; because as `(elisp)Current buffer' says, the latter will only
+    ;; be synchronized with the former when returning to the "command
+    ;; loop"; until then, `current-buffer' can change arbitrarily.
+    (should (eq window (selected-window)))
     (pop-to-buffer (other-buffer))
     (run-python nil nil 'show)
-    (should (eq buffer (current-buffer)))))
+    (should (eq window (selected-window)))))
 
 (ert-deftest python-tests--fill-long-first-line ()
   (should
-- 
2.34.1