Merge lp:~tcaswell-gmail/python-mode/window_fix into lp:python-mode

Proposed by Thomas Caswell
Status: Merged
Approved by: Andreas Roehler
Approved revision: 1165
Merged at revision: 1165
Proposed branch: lp:~tcaswell-gmail/python-mode/window_fix
Merge into: lp:python-mode
Diff against target: 145 lines (+77/-36)
1 file modified
python-mode.el (+77/-36)
To merge this branch: bzr merge lp:~tcaswell-gmail/python-mode/window_fix
Reviewer Review Type Date Requested Status
Andreas Roehler Pending
Review via email: mp+141166@code.launchpad.net

Description of the change

related to bug #1018996

To post a comment you must log in.
Revision history for this message
Andreas Roehler (a-roehler) wrote :

Looks like you spotted the bug with changes of `py-execute-buffer-file' and `py-execute-buffer-finally', congratulations!

As for the remaining stuff, IMO we need some distance to go, it's not at the bottom yet.
Please do me the favor and restrict your patch at the changes mentioned above, so I may merge this branch.

If interested, we may dig a little big deeper afterward into the architecture of this section.
Would welcome if may take it in charge somehow. As a starting-point we may take the pseudo-code mailed by Yaroslav lately. Addressing this and some more rationales might help to choose solutions if issues rise up.

Revision history for this message
Thomas Caswell (tcaswell-gmail) wrote :

On Mon, Dec 24, 2012 at 7:15 AM, Andreas Roehler
<email address hidden> wrote:
> with changes of `py-execute-buffer-file' and `py-execute-buffer-finally'

Here is a patch of just those two lines.

--
Thomas Caswell
<email address hidden>

1From 8ed76840779139ba64d61e6c51f81b8a13e72acc Mon Sep 17 00:00:00 2001
2From: Thomas A Caswell <tcaswell@uchicago.edu>
3Date: Mon, 24 Dec 2012 11:57:59 -0600
4Subject: [PATCH] fixed bug with changes of `py-execute-buffer-file' and
5 `py-execute-buffer-finally'
6
7---
8 python-mode.el | 2 --
9 1 file changed, 2 deletions(-)
10
11diff --git a/python-mode.el b/python-mode.el
12index 56cca75..82c3f08 100644
13--- a/python-mode.el
14+++ b/python-mode.el
15@@ -8725,7 +8725,6 @@ When called from a programm, it accepts a string specifying a shell which will b
16 (kill-buffer localname)))
17
18 (defun py-execute-buffer-file (start end pyshellname dedicated switch nostars sepchar split file)
19- (delete-other-windows)
20 (let* ((oldbuf (current-buffer))
21 (py-exception-buffer oldbuf)
22 (pyshellname (or pyshellname (py-choose-shell)))
23@@ -8772,7 +8771,6 @@ When called from a programm, it accepts a string specifying a shell which will b
24 erg))
25
26 (defun py-execute-buffer-finally (start end &optional pyshellname dedicated switch nostars sepchar split)
27- (delete-other-windows)
28 (let* ((oldbuf (current-buffer))
29 (pyshellname (or pyshellname (py-choose-shell)))
30 (execute-directory
31--
321.8.0.2
Revision history for this message
Andreas Roehler (a-roehler) wrote :

Am 24.12.2012 19:04, schrieb Thomas Caswell:
> On Mon, Dec 24, 2012 at 7:15 AM, Andreas Roehler
> <email address hidden> wrote:
>> with changes of `py-execute-buffer-file' and `py-execute-buffer-finally'
>
>
> Here is a patch of just those two lines.
>
>
> --
> Thomas Caswell
> <email address hidden>
>

Thanks. May you still upload it? Otherwise your branch remains with a merge-proposal without merge...

Cheers,

Andreas

Revision history for this message
Andreas Roehler (a-roehler) wrote :

ah, okay, you did it already. So I'm going to merge.

Revision history for this message
Andreas Roehler (a-roehler) wrote :

hmmn, was just your patch displayed.

Revision history for this message
Thomas Caswell (tcaswell-gmail) wrote :
Download full text (3.6 KiB)

I would re-arrange the psudo-code of Yaroslav a bit to include the
limit on the number of windows that can be made. It also deals with
the case where switching and splitting are both off, and there is more
than one window, the user may want the execution buffer to be
displayed in one of the other windows.

Consider the case where switching is off, splitting is on, there are 2
windows neither of which are showing *Python*, and
py-max-split-windows = 2 (which I think is equivalent to splitting
being turned off). What we want is this case is to put *Python* in the
window that our code is not in. This generalizes to more than 2 windows
directly by selecting the least recently used window.

(I wrote the psudo-code like python because I assume everyone
interested in this mode can read python. )

if py-manage-buffers-on-execute-p:
    # we want to make sure the user can see the output
    if *Python* buffer is visible:
        # we can already see *Python*, thus we are done
        p_win = window *Python* is in
        pass
    else:
        # we need to try and make *Python* visible
        if py-split-windows-on-execute-p and count-windows < py-max-split-windows:
            # we can make a new window
            do the split and put *Python* in the new window
            p_win = new window
        else:
            if count-windows > 1:
                seleect some other window and put *Python* in it
                p_win = window *Python* was put in
            else:
                # this is the only branch where *Python* is not visible at the end
                p_win = None
                do nothing

    if py-switch-buffers-on-execute-p:
        if p_win:
            switch focus to p_win
        else:
            # this is the only branch that replaces the code window with the output
            switch the buffer displayed in the current window, replacing the code
else:
    # DO NOTHING
    pass

To deal with the use case where the user wants to always replace
the code window with the output (with what I think is a reasonable
exception of *Python* being already visible, in which case it behaves
like switching is turned on and splitting is turned off), we need to
add another flag. If this flag (py-replace-code-on-execute-p) is set,
the values of the split and switch flag are irrelevant.

This logic is not in the lisp yet.

if py-manage-buffers-on-execute-p:
    # we want to make sure the user can see the output
    if *Python* buffer is visible:
        # we can already see *Python*, thus we are done
        p_win = window *Python* is in
        pass
    else:
        if py-replace-code-on-execute-p:
            p_win = None
        # we need to try and make *Python* visible
        elif py-split-windows-on-execute-p and count-windows < py-max-split-windows:
            # we can make a new window
            do the split and put *Python* in the new window
            p_win = new window
        else:
            if count-windows > 1:
                seleect some other window and put *Python* in it
                p_win = window *Python* was put in
            else:
                # this is the only branch w...

Read more...

Revision history for this message
Andreas Roehler (a-roehler) wrote :
Download full text (4.8 KiB)

Am 30.12.2012 21:36, schrieb Thomas Caswell:
> I would re-arrange the psudo-code of Yaroslav a bit

Great, was meant just as a starting point.

  to include the
> limit on the number of windows that can be made. It also deals with
> the case where switching and splitting are both off, and there is more
> than one window, the user may want the execution buffer to be
> displayed in one of the other windows.
>
> Consider the case where switching is off, splitting is on, there are 2
> windows neither of which are showing *Python*, and
> py-max-split-windows = 2 (which I think is equivalent to splitting
> being turned off).

IMO that remark is misleading, as the way Emacs will create the final window configuration might be complex.
Temporary buffers and files might be created and so on. Think the final window state somehow independent from the
start configuration.

   What we want is this case is to put *Python* in the
> window that our code is not in. This generalizes to more than 2 windows
> directly by selecting the least recently used window.
>

See remark above. Such like "recently used" probably is not enough.

> (I wrote the psudo-code like python because I assume everyone
> interested in this mode can read python. )
>
>
> if py-manage-buffers-on-execute-p:

We don't need this boolean, because some management is needed in any case -
unless we want unpredicted results.

> # we want to make sure the user can see the output
> if *Python* buffer is visible:
> # we can already see *Python*, thus we are done

That's not sure user may want to see the output.
For example when running serialised stuff from a programm.

Basically the logic is:

Start window config
Unpredictable changes from point of the first
Desired final window config

Remains the question if 'switch and 'split are sufficient to describe the desired final config.

Probably not, also when thinking at use in org-babel.

> p_win = window *Python* is in
> pass
> else:
> # we need to try and make *Python* visible
> if py-split-windows-on-execute-p and count-windows < py-max-split-windows:
> # we can make a new window
> do the split and put *Python* in the new window
> p_win = new window
> else:
> if count-windows > 1:
> seleect some other window and put *Python* in it
> p_win = window *Python* was put in
> else:
> # this is the only branch where *Python* is not visible at the end
> p_win = None
> do nothing
>
> if py-switch-buffers-on-execute-p:
> if p_win:
> switch focus to p_win
> else:
> # this is the only branch that replaces the code window with the output
> switch the buffer displayed in the current window, replacing the code

the last is another possible option not implemented yet.

> else:
> # DO NOTHING
> pass
>
> To deal with the use case where the user wants to always replace
> the code window with the output (with what I think is a reasonable
> exception of *Python* being already visi...

Read more...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'python-mode.el'
2--- python-mode.el 2012-12-21 18:27:07 +0000
3+++ python-mode.el 2012-12-22 21:11:20 +0000
4@@ -710,6 +710,12 @@
5 :type 'boolean
6 :group 'python-mode)
7
8+(defcustom py-on-execute-buffer-management-p t
9+ "If emacs should attempt to manage your buffers on executing python code."
10+ :type 'boolean
11+ :group 'python-mode
12+)
13+
14 (defcustom py-switch-buffers-on-execute-p nil
15 "When non-nil switch to the Python output buffer. "
16
17@@ -8757,7 +8763,6 @@
18 (kill-buffer localname)))
19
20 (defun py-execute-buffer-file (start end pyshellname dedicated switch nostars sepchar split file)
21- (delete-other-windows)
22 (let* ((oldbuf (current-buffer))
23 (py-exception-buffer oldbuf)
24 (pyshellname (or pyshellname (py-choose-shell)))
25@@ -8804,7 +8809,6 @@
26 erg))
27
28 (defun py-execute-buffer-finally (start end &optional pyshellname dedicated switch nostars sepchar split)
29- (delete-other-windows)
30 (let* ((oldbuf (current-buffer))
31 (pyshellname (or pyshellname (py-choose-shell)))
32 (execute-directory
33@@ -10492,41 +10496,78 @@
34 "\*" ""
35 string)))
36
37+(defun py-try-make-output-buffer-visible (split py-buffer-name)
38+ "A helper function that tries to make the output buffer is visible.
39+
40+If it is already visible it return the window it is in
41+
42+If it is not visible and splitting is allowed and there are less
43+that the maximum number of windows, then it will split the code window,
44+put the output buffer in the new window and return the new window
45+
46+If there is more than one window and splitting is not allowed, then
47+put the output buffer in the least recently used window and return that window
48+
49+if there is only one window and splitting in not allowed return nil
50+"
51+ (let ((cur-py-window (get-buffer-window py-buffer-name t)))
52+ (if cur-py-window
53+ ;; There is a currently visible window with the output buffer in it use that one
54+ cur-py-window
55+ ;; if the output buffer isn't already visible, try to make it so
56+
57+ ;;we have not explicitly said not to split, we are allowed to split, and
58+ ;; there are few enough windows
59+ (if (and (not (eq split 'nosplit))
60+ py-split-windows-on-execute-p
61+ (< (count-windows) py-max-split-windows)
62+ )
63+ (let ((new-py-wind (funcall py-split-windows-on-execute-function)))
64+ (set-window-buffer new-py-wind py-buffer-name)
65+ new-py-wind
66+ )
67+
68+ (if (eq 1 (count-windows))
69+ nil
70+ ;; else make the lru window show the output buffer and return it
71+ (let ((new-py-wind (get-lru-window)))
72+ (set-window-buffer new-py-wind py-buffer-name)
73+ new-py-wind
74+ )
75+ )
76+ )
77+ )
78+ )
79+ )
80+
81 (defun py-shell-manage-windows (switch split oldbuf py-buffer-name)
82- (cond (;; split and switch
83- (and (not (eq split 'nosplit))
84- py-split-windows-on-execute-p
85- (not (eq switch 'noswitch))
86- (or (eq switch 'switch)
87- py-switch-buffers-on-execute-p))
88- (when (< (count-windows) py-max-split-windows)
89- (funcall py-split-windows-on-execute-function))
90- (pop-to-buffer py-buffer-name)
91- (display-buffer oldbuf))
92- ;; split, not switch
93- ((and
94- (not (eq split 'nosplit))
95- py-split-windows-on-execute-p
96- (or (eq switch 'noswitch)
97- (not (eq switch 'switch))))
98- (if (< (count-windows) py-max-split-windows)
99- (progn
100- (funcall py-split-windows-on-execute-function)
101- (display-buffer py-buffer-name 'display-buffer-reuse-window))
102- (display-buffer py-buffer-name 'display-buffer-reuse-window))
103- (pop-to-buffer oldbuf))
104- ;; no split, switch
105- ((or (eq switch 'switch)
106- (and (not (eq switch 'noswitch))
107- py-switch-buffers-on-execute-p))
108- (let (pop-up-windows)
109- (pop-to-buffer py-buffer-name)))
110- ;; no split, no switch
111- ((or (eq switch 'noswitch)
112- (not py-switch-buffers-on-execute-p))
113- (let (pop-up-windows)
114- (set-buffer oldbuf)
115- (switch-to-buffer (current-buffer))))))
116+ (if py-on-execute-buffer-management-p
117+ ;;if we are going to let python mode touch our buffers under any conditions
118+ (let ((cur-py-window (py-try-make-output-buffer-visible split py-buffer-name)))
119+ ;; if we are switching
120+ (when
121+ ;;this logic seems overly twisted
122+ (and
123+ (not (eq switch 'noswitch))
124+ (or (eq switch 'switch)
125+ py-switch-buffers-on-execute-p))
126+ (if cur-py-window
127+ ;; if we have a visible window with the output buffer, switch to it
128+ (select-window cur-py-window)
129+ ;; if we don't then make the current window display the output (case of 1 window, switch, nosplit)
130+ (switch-to-buffer py-buffer-name)
131+ )
132+
133+ )
134+ )
135+ ;;else, return it to the state it was in
136+ (let (pop-up-windows)
137+ (set-buffer oldbuf)
138+ (switch-to-buffer (current-buffer))
139+ )
140+ )
141+ )
142+
143
144 (defun py-report-executable (py-buffer-name)
145 (let ((erg (downcase (replace-regexp-in-string

Subscribers

People subscribed via source and target branches

to status/vote changes: