GNU bug report logs - #32790
27.0.50; point jumps unexpectedly after delete-window

Previous Next

Package: emacs;

Reported by: Juri Linkov <juri <at> linkov.net>

Date: Thu, 20 Sep 2018 23:57:01 UTC

Severity: minor

Found in version 27.0.50

Done: Juri Linkov <juri <at> linkov.net>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 32790 in the body.
You can then email your comments to 32790 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 20 Sep 2018 23:57:01 GMT) Full text and rfc822 format available.

Acknowledgement sent to Juri Linkov <juri <at> linkov.net>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Thu, 20 Sep 2018 23:57:01 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: bug-gnu-emacs <at> gnu.org
Subject: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 21 Sep 2018 02:33:55 +0300
0. emacs -Q

1. C-h e

2. C-x o

3. C-x 2

4. C-x 0

It's expected that point will remain where it was visually on the screen,
just will relocate to the window that takes place of the deleted window,
but point jumps to an unexpected place in the opposite part of the frame.

This is not a regression, but nevertheless very annoying behavior.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Fri, 21 Sep 2018 06:35:02 GMT) Full text and rfc822 format available.

Message #8 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>, 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 21 Sep 2018 08:34:18 +0200
> 0. emacs -Q
>
> 1. C-h e
>
> 2. C-x o
>
> 3. C-x 2
>
> 4. C-x 0
>
> It's expected that point will remain where it was visually on the screen,

That screen position will not show any buffer text after C-x 0.  How
do you want the cursor (I suppose that's what "point" refers to)
remain there?

> just will relocate to the window that takes place of the deleted window,
> but point jumps to an unexpected place in the opposite part of the frame.
>
> This is not a regression, but nevertheless very annoying behavior.

What should Emacs do instead?

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Fri, 21 Sep 2018 06:57:02 GMT) Full text and rfc822 format available.

Message #11 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 21 Sep 2018 09:55:37 +0300
> From: Juri Linkov <juri <at> linkov.net>
> Date: Fri, 21 Sep 2018 02:33:55 +0300
> 
> 0. emacs -Q
> 
> 1. C-h e
> 
> 2. C-x o
> 
> 3. C-x 2
> 
> 4. C-x 0
> 
> It's expected that point will remain where it was visually on the screen,
> just will relocate to the window that takes place of the deleted window,
> but point jumps to an unexpected place in the opposite part of the frame.
> 
> This is not a regression, but nevertheless very annoying behavior.

You mean you expected that if the same buffer is displayed in another
window, Emacs should prefer that other window when it decides what
window to make the selected one?

I don't think this is guaranteed, and in any case I could think of a
scenario where the current behavior is the convenient one.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sat, 22 Sep 2018 22:43:02 GMT) Full text and rfc822 format available.

Message #14 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 23 Sep 2018 01:23:16 +0300
>> 0. emacs -Q
>>
>> 1. C-h e
>>
>> 2. C-x o
>>
>> 3. C-x 2
>>
>> 4. C-x 0
>>
>> It's expected that point will remain where it was visually on the screen,
>
> That screen position will not show any buffer text after C-x 0.  How
> do you want the cursor (I suppose that's what "point" refers to)
> remain there?

Yes, I meant the cursor, but more specifically the cursor in the
selected window (as opposed to cursor-in-non-selected-windows).

>> just will relocate to the window that takes place of the deleted window,
>> but point jumps to an unexpected place in the opposite part of the frame.
>>
>> This is not a regression, but nevertheless very annoying behavior.
>
> What should Emacs do instead?

I believe Emacs could try to select the window that takes screen space
of the deleted window.

I wonder is it possible to define a simple rule in terms of the
window tree, e.g. maybe it is the parent window of the deleted window
that should be selected?  Or it's not guaranteed that the parent
window takes the screen space of the deleted subwindow in the same
window combination?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sat, 22 Sep 2018 22:43:02 GMT) Full text and rfc822 format available.

Message #17 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 23 Sep 2018 01:34:43 +0300
>> 0. emacs -Q
>> 
>> 1. C-h e
>> 
>> 2. C-x o
>> 
>> 3. C-x 2
>> 
>> 4. C-x 0
>> 
>> It's expected that point will remain where it was visually on the screen,
>> just will relocate to the window that takes place of the deleted window,
>> but point jumps to an unexpected place in the opposite part of the frame.
>> 
>> This is not a regression, but nevertheless very annoying behavior.
>
> You mean you expected that if the same buffer is displayed in another
> window, Emacs should prefer that other window when it decides what
> window to make the selected one?

Actually it's a rare case when the same buffer is displayed
in two windows.  But I meant a more general case where all windows
display different buffers.  This is a more appropriate recipe
that avoids the same buffers:

0. emacs -Q

1. C-h e

2. C-x o

3. C-x 2

4. C-h i

5. C-x 0




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 23 Sep 2018 05:46:01 GMT) Full text and rfc822 format available.

Message #20 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Juri Linkov <juri <at> linkov.net>
Cc: rudalics <at> gmx.at, 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 23 Sep 2018 08:44:51 +0300
> From: Juri Linkov <juri <at> linkov.net>
> Date: Sun, 23 Sep 2018 01:23:16 +0300
> Cc: 32790 <at> debbugs.gnu.org
> 
> > What should Emacs do instead?
> 
> I believe Emacs could try to select the window that takes screen space
> of the deleted window.

That's what it does here: it selects *scratch*, which reclaims the
screen space that formerly belonged to one of the 2 windows displaying
*Messages*.

Isn't that what happens for you?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 23 Sep 2018 08:28:01 GMT) Full text and rfc822 format available.

Message #23 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 23 Sep 2018 10:27:33 +0200
> I believe Emacs could try to select the window that takes screen space
> of the deleted window.

By default Emacs tries to select the most recently used window.  Only
if that fails, it uses the first live window on the frame as fallback.

> I wonder is it possible to define a simple rule in terms of the
> window tree, e.g. maybe it is the parent window of the deleted window
> that should be selected?

A parent window is internal and cannot be selected.  You probably mean
one of the former siblings of the deleted window.  If we did that, we
should make it customizable somehow.

> Or it's not guaranteed that the parent
> window takes the screen space of the deleted subwindow in the same
> window combination?

When the window to be deleted has only one sibling, then that sibling
will get the space of the deleted window.  If that sibling is a parent
window, all its children will get the space proportionally.

Otherwise, when the window do be deleted has a left sibling, that one
will usualy get the space for historical reasons.  If the window has
no left sibling, the right one gets the space.  In either cae, if
'window-combination-resize' is non-nil, all windows in the same
combination may get the space proportionally.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 23 Sep 2018 08:29:02 GMT) Full text and rfc822 format available.

Message #26 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>, Eli Zaretskii <eliz <at> gnu.org>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 23 Sep 2018 10:28:13 +0200
>> You mean you expected that if the same buffer is displayed in another
>> window, Emacs should prefer that other window when it decides what
>> window to make the selected one?
>
> Actually it's a rare case when the same buffer is displayed
> in two windows.  But I meant a more general case where all windows
> display different buffers.  This is a more appropriate recipe
> that avoids the same buffers:
>
> 0. emacs -Q
>
> 1. C-h e
>
> 2. C-x o
>
> 3. C-x 2
>
> 4. C-h i
>
> 5. C-x 0

C-x 2 in step 3 does _not_ "use" the new window on *Messages*.  Hence
at the time you do C-x 0 in step 5, the most recently used window
(with exception of the one you are about to delete) is the window on
*scratch*.

Using a window means selecting it, see 'window-use-time'. Hence if,
before C-x 0, you first select the window on *Messages* and then
reselect the *Info* window, C-x 0 will select the *Messages* window
instead.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 23 Sep 2018 10:57:02 GMT) Full text and rfc822 format available.

Message #29 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 23 Sep 2018 13:56:06 +0300
> From: Juri Linkov <juri <at> linkov.net>
> Cc: 32790 <at> debbugs.gnu.org
> Date: Sun, 23 Sep 2018 01:34:43 +0300
> 
> Actually it's a rare case when the same buffer is displayed
> in two windows.  But I meant a more general case where all windows
> display different buffers.  This is a more appropriate recipe
> that avoids the same buffers:
> 
> 0. emacs -Q
> 
> 1. C-h e
> 
> 2. C-x o
> 
> 3. C-x 2
> 
> 4. C-h i
> 
> 5. C-x 0

I meanwhile understand that in your case "C-h e" splits the original
window horizontally, i.e. you get 2 windows side by side, not one
above the other.  AFAICT, this was never explicitly mentioned in your
bug report.

In any case, Martin explained the logic behind selecting another
window in this case.  FWIW, I think the existing logic, which prefers
the most recently selected window, is more sound than the one you
propose, because screen positions can be more arbitrary/random than
the MRU order.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 23 Sep 2018 21:04:02 GMT) Full text and rfc822 format available.

Message #32 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 23 Sep 2018 23:49:37 +0300
>> Actually it's a rare case when the same buffer is displayed
>> in two windows.  But I meant a more general case where all windows
>> display different buffers.  This is a more appropriate recipe
>> that avoids the same buffers:
>>
>> 0. emacs -Q
>>
>> 1. C-h e
>>
>> 2. C-x o
>>
>> 3. C-x 2
>>
>> 4. C-h i
>>
>> 5. C-x 0
>
> I meanwhile understand that in your case "C-h e" splits the original
> window horizontally, i.e. you get 2 windows side by side, not one
> above the other.  AFAICT, this was never explicitly mentioned in your
> bug report.

Sorry, I meant horizontally split windows.

> In any case, Martin explained the logic behind selecting another
> window in this case.  FWIW, I think the existing logic, which prefers
> the most recently selected window, is more sound than the one you
> propose, because screen positions can be more arbitrary/random than
> the MRU order.

This problem is quite rare since it resurfaces only when a frame has
more than 2 windows.  And every time the cursor jumps far away from
where it was before window deleting, it raises the question "Why?"

Now I understand that it jumps to the most recently selected window,
but this logic is not obvious.  Then why not to the most recently
displayed window?  Maybe we should have an option or at least hook
to define the preferred behavior.  Like there is the option
split-window-keep-point (applicable only to vertically split windows)
whose nil value provides more smooth effect (selects the window
depending on where point was before split, to avoid window scrolling).




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 23 Sep 2018 21:04:02 GMT) Full text and rfc822 format available.

Message #35 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 23 Sep 2018 23:57:35 +0300
>> I wonder is it possible to define a simple rule in terms of the
>> window tree, e.g. maybe it is the parent window of the deleted window
>> that should be selected?
>
> A parent window is internal and cannot be selected.  You probably mean
> one of the former siblings of the deleted window.  If we did that, we
> should make it customizable somehow.

Yes, I meant siblings.  Is it possible to make it customizable?
Searching for this, I see others find the current behavior annoying too, e.g.
https://github.com/wasamasa/dotemacs/blob/master/TODO.org#fix-emacs-selection-after-window-quitclose

>> Or it's not guaranteed that the parent
>> window takes the screen space of the deleted subwindow in the same
>> window combination?
>
> When the window to be deleted has only one sibling, then that sibling
> will get the space of the deleted window.  If that sibling is a parent
> window, all its children will get the space proportionally.
>
> Otherwise, when the window do be deleted has a left sibling, that one
> will usualy get the space for historical reasons.  If the window has
> no left sibling, the right one gets the space.  In either case, if
> 'window-combination-resize' is non-nil, all windows in the same
> combination may get the space proportionally.

Does this mean that a simple rule would be just to use the left sibling,
otherwise the right sibling?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 24 Sep 2018 08:24:02 GMT) Full text and rfc822 format available.

Message #38 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>, Eli Zaretskii <eliz <at> gnu.org>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 24 Sep 2018 10:23:43 +0200
>> I meanwhile understand that in your case "C-h e" splits the original
>> window horizontally, i.e. you get 2 windows side by side, not one
>> above the other.  AFAICT, this was never explicitly mentioned in your
>> bug report.
>
> Sorry, I meant horizontally split windows.

How comes that C-h e splits the window horizontally?

> Now I understand that it jumps to the most recently selected window,
> but this logic is not obvious.  Then why not to the most recently
> displayed window?

The idea to automatically select a window that has never been selected
before is not overly intuitive IMHO.

> Maybe we should have an option or at least hook
> to define the preferred behavior.  Like there is the option
> split-window-keep-point (applicable only to vertically split windows)
> whose nil value provides more smooth effect (selects the window
> depending on where point was before split, to avoid window scrolling).

The most recently displayed window might be the window that gets
deleted and so we would have to either modify the semantics of
'window-use-time' (to optionally include the case that the window has
been created without being selected) or add a new slot to the window
structure and have 'delete-window' act accordingly if set.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 24 Sep 2018 08:32:01 GMT) Full text and rfc822 format available.

Message #41 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org, juri <at> linkov.net
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 24 Sep 2018 11:30:46 +0300
> Date: Mon, 24 Sep 2018 10:23:43 +0200
> From: martin rudalics <rudalics <at> gmx.at>
> CC: 32790 <at> debbugs.gnu.org
> 
>  >> I meanwhile understand that in your case "C-h e" splits the original
>  >> window horizontally, i.e. you get 2 windows side by side, not one
>  >> above the other.  AFAICT, this was never explicitly mentioned in your
>  >> bug report.
>  >
>  > Sorry, I meant horizontally split windows.
> 
> How comes that C-h e splits the window horizontally?

It does if the initial frame is wide enough.  That's expected, I
think.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 24 Sep 2018 08:34:02 GMT) Full text and rfc822 format available.

Message #44 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 24 Sep 2018 10:33:07 +0200
>> A parent window is internal and cannot be selected.  You probably mean
>> one of the former siblings of the deleted window.  If we did that, we
>> should make it customizable somehow.
>
> Yes, I meant siblings.  Is it possible to make it customizable?

I probably still have no good understanding what precisely your
problem is with selecting the most recently selected window.  Can you
please elaborate once more?

> Searching for this, I see others find the current behavior annoying too, e.g.
> https://github.com/wasamasa/dotemacs/blob/master/TODO.org#fix-emacs-selection-after-window-quitclose

C-x 3 C-x o C-x o C-x 2 C-x 0

What's the purpose of the 'other-buffer' calls if they don't express
the user's wish to "work" in these windows?

> Does this mean that a simple rule would be just to use the left sibling,
> otherwise the right sibling?

With "use" you mean choose for giving back the space of the deleted
window?  Then we should remember from which window Emacs obtained the
space when creating a new window and return that space when deleting
the new window, provided that old window still exists.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 24 Sep 2018 12:26:02 GMT) Full text and rfc822 format available.

Message #47 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: 32790 <at> debbugs.gnu.org, juri <at> linkov.net
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 24 Sep 2018 14:25:09 +0200
>> How comes that C-h e splits the window horizontally?
>
> It does if the initial frame is wide enough.  That's expected, I
> think.

So there must be some special settings in resources or the Emacs
invocation.  Our default initial frame is not wide enough.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 24 Sep 2018 19:15:04 GMT) Full text and rfc822 format available.

Message #50 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 24 Sep 2018 21:49:53 +0300
> I probably still have no good understanding what precisely your
> problem is with selecting the most recently selected window.  Can you
> please elaborate once more?

The problem is that the cursor jumps to the distant part of the frame
too far from the current focus.  It takes additional efforts to bring
it back where the input focus was.  It's more about visual perception.

> C-x 3 C-x o C-x o C-x 2 C-x 0
>
> What's the purpose of the 'other-buffer' calls if they don't express
> the user's wish to "work" in these windows?

Just to play around in these windows, not to work or use them :-)

>> Does this mean that a simple rule would be just to use the left sibling,
>> otherwise the right sibling?
>
> With "use" you mean choose for giving back the space of the deleted
> window?  Then we should remember from which window Emacs obtained the
> space when creating a new window and return that space when deleting
> the new window, provided that old window still exists.

It seems the logic of deciding to which sibling to give the space back
is fine now.  The need is to select the same window that got the space
after C-x 0.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 24 Sep 2018 19:15:05 GMT) Full text and rfc822 format available.

Message #53 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 24 Sep 2018 21:53:04 +0300
>> Now I understand that it jumps to the most recently selected window,
>> but this logic is not obvious.  Then why not to the most recently
>> displayed window?
>
> The idea to automatically select a window that has never been selected
> before is not overly intuitive IMHO.

OTOH, the fact that the user not yet used that window could mean that
it's time to use it now, i.e. not less intuitive.

> The most recently displayed window might be the window that gets
> deleted and so we would have to either modify the semantics of
> 'window-use-time' (to optionally include the case that the window has
> been created without being selected) or add a new slot to the window
> structure and have 'delete-window' act accordingly if set.

Like we have buffer-display-time, maybe window-display-time is also
needed in addition to window-use-time.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 25 Sep 2018 07:29:02 GMT) Full text and rfc822 format available.

Message #56 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 25 Sep 2018 09:28:16 +0200
> The problem is that the cursor jumps to the distant part of the frame
> too far from the current focus.  It takes additional efforts to bring
> it back where the input focus was.  It's more about visual perception.

But then we have to care about the position of each window's point as
well.  Consider the case of a vertical combination of three windows
with all windows' points at their top.  Deleting the middle window
should then probably select the lower window.  With all points at
their windows' bottoms we probably should select the upper window.

>> C-x 3 C-x o C-x o C-x 2 C-x 0
>>
>> What's the purpose of the 'other-buffer' calls if they don't express
>> the user's wish to "work" in these windows?
>
> Just to play around in these windows, not to work or use them :-)

Obviously, these C-x o are needed to make the example work.  Without
them the window split off by C-x 2 would be selected.

> It seems the logic of deciding to which sibling to give the space back
> is fine now.  The need is to select the same window that got the space
> after C-x 0.

We can add an option for that.  How should we call it?

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 25 Sep 2018 07:29:03 GMT) Full text and rfc822 format available.

Message #59 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 25 Sep 2018 09:28:33 +0200
>>> Now I understand that it jumps to the most recently selected window,
>>> but this logic is not obvious.  Then why not to the most recently
>>> displayed window?
>>
>> The idea to automatically select a window that has never been selected
>> before is not overly intuitive IMHO.
>
> OTOH, the fact that the user not yet used that window could mean that
> it's time to use it now, i.e. not less intuitive.

Consider the case of a user continuously editing a buffer in one and
the same window, occasionally popping up temporary windows to display
tags, completions, matches, help or info.  Should deleting such a
temporary window really select another temporary window?  We wouldn't
get away unpunished with such a solution.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 25 Sep 2018 19:38:03 GMT) Full text and rfc822 format available.

Message #62 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 25 Sep 2018 22:28:06 +0300
>> The problem is that the cursor jumps to the distant part of the frame
>> too far from the current focus.  It takes additional efforts to bring
>> it back where the input focus was.  It's more about visual perception.
>
> But then we have to care about the position of each window's point as
> well.  Consider the case of a vertical combination of three windows
> with all windows' points at their top.  Deleting the middle window
> should then probably select the lower window.  With all points at
> their windows' bottoms we probably should select the upper window.

A good analogy is what other tabbed UI like web browsers do
on tab closing.  For example, Firefox add-on Tab Mix Plus

http://www.tabmixplus.org/support/viewtopic.php?t=3

provides an option with such values

  When closing the current tab, focus (select one):

  - First tab
  - Left tab
  - Right tab
  - Last tab
  - Last selected tab
  - Opener/Right tab (the tab containing the link that opened this tab or the tab to the right)
  - Last opened tab

The current Emacs behavior that selects the most recently used window
corresponds to "Last selected tab".  "Last opened tab" could correspond
to the most recently displayed window.  And "Left tab" could mean to
select the left sibling.

>> It seems the logic of deciding to which sibling to give the space back
>> is fine now.  The need is to select the same window that got the space
>> after C-x 0.
>
> We can add an option for that.  How should we call it?

The name depends on possible values.

If the values are 'sibling, 'mru, and possibly a user-defined function,
then a suitable name could be say, after-delete-window-select, or if this
name looks like a hook name, then simply delete-window-select.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 26 Sep 2018 08:52:02 GMT) Full text and rfc822 format available.

Message #65 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Wed, 26 Sep 2018 10:51:42 +0200
> A good analogy is what other tabbed UI like web browsers do
> on tab closing.  For example, Firefox add-on Tab Mix Plus
>
> http://www.tabmixplus.org/support/viewtopic.php?t=3
>
> provides an option with such values
>
>    When closing the current tab, focus (select one):
>
>    - First tab
>    - Left tab
>    - Right tab
>    - Last tab
>    - Last selected tab
>    - Opener/Right tab (the tab containing the link that opened this tab or the tab to the right)

The last one is the option I use, mainly for returning to the "parent"
tab.  I'd prefer "the tab containing the link that opened this tab or
the last selected tab" but that's not available.

>    - Last opened tab
>
> The current Emacs behavior that selects the most recently used window
> corresponds to "Last selected tab".  "Last opened tab" could correspond
> to the most recently displayed window.  And "Left tab" could mean to
> select the left sibling.

Make a complete list with the desired names, please.

> If the values are 'sibling, 'mru, and possibly a user-defined function,
> then a suitable name could be say, after-delete-window-select, or if this
> name looks like a hook name, then simply delete-window-select.

Let's reconsider after you made the list with the value names ("sibling"
is probably too internal, IIRC even you used "parent" instead).

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 27 Sep 2018 00:05:01 GMT) Full text and rfc822 format available.

Message #68 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Thu, 27 Sep 2018 02:05:17 +0300
> Make a complete list with the desired names, please.

I think we need exactly the same customization as we created for
compare-windows-get-window-function, but instead of finding a window to
compare, we need to find a window to select after deleting the
selected window.

  (defcustom compare-windows-get-window-function
    'compare-windows-get-recent-window
    "Function that provides the window to compare with."
    :type '(choice
            (function-item :tag "Most recently used window"
                           compare-windows-get-recent-window)
            (function-item :tag "Next window"
                           compare-windows-get-next-window)
            (function :tag "Your function"))
    :group 'compare-windows
    :version "25.1")

I suppose that for the option "Next window" the window next to the
deleted window is its sibling that will get its space after
deletion, right?

>> If the values are 'sibling, 'mru, and possibly a user-defined function,
>> then a suitable name could be say, after-delete-window-select, or if this
>> name looks like a hook name, then simply delete-window-select.
>
> Let's reconsider after you made the list with the value names ("sibling"
> is probably too internal, IIRC even you used "parent" instead).

Regarding the name, what about select-window-after-delete-function?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 27 Sep 2018 18:45:02 GMT) Full text and rfc822 format available.

Message #71 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Thu, 27 Sep 2018 20:44:23 +0200
> I think we need exactly the same customization as we created for
> compare-windows-get-window-function, but instead of finding a window to
> compare, we need to find a window to select after deleting the
> selected window.
>
>    (defcustom compare-windows-get-window-function
>      'compare-windows-get-recent-window
>      "Function that provides the window to compare with."
>      :type '(choice
>              (function-item :tag "Most recently used window"
>                             compare-windows-get-recent-window)
>              (function-item :tag "Next window"
>                             compare-windows-get-next-window)
>              (function :tag "Your function"))
>      :group 'compare-windows
>      :version "25.1")
>
> I suppose that for the option "Next window" the window next to the
> deleted window is its sibling that will get its space after
> deletion, right?

Not usually.  'delete-window' prefers the left sibling because that's
the classic way to work with windows: The new window appears on the
right of or below the window split.  Deleting the new window "returns"
its space to the window on the left or above, if that exists.  The
"next window" of any window OTOH is preferably its right sibling, if
that exists, or something "further down" in the window tree.

So first of all we have to decide which window should get the space
when we delete a window and make that customizable, if necessary.
Note, however, that when an application or a user has bound the
non-option 'window-combination-limit' to t, each window has only one
sibling and there is nothing to customize - the space will be always
returned to that sibling.  OTOH, if 'window-combination-resize' is
non-nil, the space is returned proportionally to all windows in the
same combination and again there is nothing to customize.

When that first issue has been settled, we can easily add to the
option we talk about here a value that selects the window that has
received the space of the deleted window - with the restrictions noted
above.

> Regarding the name, what about select-window-after-delete-function?

If we make the value a function like compare-w.el does.  Note in this
context that we probably do not want to select a window on another
frame (including iconified or invisible ones) so the functions
compare-w provides are probably not very useful here.  BTW I didn't
even know about compare-w - its name is too obscure to associate it
with windows.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 15 Oct 2018 21:31:01 GMT) Full text and rfc822 format available.

Message #74 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 16 Oct 2018 00:12:27 +0300
> When that first issue has been settled, we can easily add to the
> option we talk about here a value that selects the window that has
> received the space of the deleted window - with the restrictions noted
> above.

I understand now what exactly is annoying about the current behavior:
when there is already 2 or more windows on the frame, after splitting the
selected window, you create a new window that displays the same buffer, then
you decide you need to undo the recent split, and the quickest way to do this
is to delete the selected window with 'C-x 0'.  After that, the window
configuration looks exactly as before the split, with only one difference -
the cursor jumps to an unrelated window.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 16 Oct 2018 08:47:01 GMT) Full text and rfc822 format available.

Message #77 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 16 Oct 2018 10:46:16 +0200
> I understand now what exactly is annoying about the current behavior:
> when there is already 2 or more windows on the frame, after splitting the
> selected window, you create a new window that displays the same buffer, then
> you decide you need to undo the recent split, and the quickest way to do this
> is to delete the selected window with 'C-x 0'.

Yours is a bad habit.  Deleting the old window will also delete its
old associations, like window parameters and overlays with a 'window'
property.  Here I have one key binding for selecting and one for
deleting a window on any side of the selected one.  I always use them
in such a case.

> After that, the window
> configuration looks exactly as before the split, with only one difference -
> the cursor jumps to an unrelated window.

I'll try to make this customizable, probably by adding an option like
'window-set-use-time-upon-creation'.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 16 Oct 2018 22:39:02 GMT) Full text and rfc822 format available.

Message #80 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Wed, 17 Oct 2018 01:20:10 +0300
> Here I have one key binding for selecting and one for deleting
> a window on any side of the selected one.  I always use them in such
> a case.

For window selection I use (windmove-default-keybindings 'hyper),
so e.g. '<H-left>' selects the left window.  Could you recommend
a command to bind to e.g. 'C-x <H-left>' that will delete the left
window?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 17 Oct 2018 07:32:02 GMT) Full text and rfc822 format available.

Message #83 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Wed, 17 Oct 2018 09:30:55 +0200
> For window selection I use (windmove-default-keybindings 'hyper),
> so e.g. '<H-left>' selects the left window.  Could you recommend
> a command to bind to e.g. 'C-x <H-left>' that will delete the left
> window?

Here <H-left> drags the character under the cursor by one character to
the left and <H-up> drags the current line up by one line.  I use
<M-S-left> for selecting the window on the left.  <C-M-S-left> either
deletes the window on the left of the selected window provided there
is one or makes a new window on the left of the selected window
provided the selected window is already on the left of the frame.  The
code for that command is below.

martin

(defun window-delete-or-split-left ()
  "If selected window has a window on left delete that window.
Otherwise split selected window horizontally and select left
window."
  (interactive)
  (unless (condition-case nil
              (save-selected-window
		(if (fboundp 'window-in-direction)
		    (let ((window (window-in-direction 'left)))
		      (when window (delete-window window) t))
		  (windmove-do-window-select 'left)
		  (delete-window) t))
            (error nil))
    (if (fboundp 'window-in-direction)
	(let ((window (split-window nil nil 'left)))
	  (select-window window))
      (split-window-horizontally))))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 17 Oct 2018 22:30:02 GMT) Full text and rfc822 format available.

Message #86 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Thu, 18 Oct 2018 00:30:40 +0300
>> For window selection I use (windmove-default-keybindings 'hyper),
>> so e.g. '<H-left>' selects the left window.  Could you recommend
>> a command to bind to e.g. 'C-x <H-left>' that will delete the left
>> window?
>
> Here <H-left> drags the character under the cursor by one character to
> the left and <H-up> drags the current line up by one line.  I use
> <M-S-left> for selecting the window on the left.  <C-M-S-left> either
> deletes the window on the left of the selected window provided there
> is one or makes a new window on the left of the selected window
> provided the selected window is already on the left of the frame.  The
> code for that command is below.

Thanks for sharing the code.  Now I have a good configuration:

  (defun my-windmove (&optional arg)
    (interactive "P")
    (let ((dir (event-basic-type (aref (this-command-keys) 0))))
      (condition-case nil
          (windmove-do-window-select dir arg)
        (error (select-window (split-window nil nil dir))))))

  (defun my-windelete (&optional arg)
    (interactive "P")
    (let ((dir (event-basic-type (aref (this-command-keys) 1))))
      (delete-window (window-in-direction dir))))

  (let ((modifiers '(hyper)))
    (dolist (key '(left right up down))
      (define-key global-map (vector (append modifiers (list key))) 'my-windmove)
      (define-key ctl-x-map  (vector (append modifiers (list key))) 'my-windelete)))

The only problem is the mismatch between key names and direction names.

Could you add aliases for 'up' and 'down' in window-in-direction?
Then we won't need such special handling in windmove.el:

  (window-in-direction
   (cond
    ((eq dir 'up) 'above)
    ((eq dir 'down) 'below)
    (t dir))
   window nil arg windmove-wrap-around t)




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 18 Oct 2018 08:06:02 GMT) Full text and rfc822 format available.

Message #89 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Thu, 18 Oct 2018 10:05:29 +0200
> Could you add aliases for 'up' and 'down' in window-in-direction?
> Then we won't need such special handling in windmove.el:
>
>    (window-in-direction
>     (cond
>      ((eq dir 'up) 'above)
>      ((eq dir 'down) 'below)
>      (t dir))
>     window nil arg windmove-wrap-around t)

Should be done now on master.  Please test.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 18 Oct 2018 22:51:01 GMT) Full text and rfc822 format available.

Message #92 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 19 Oct 2018 01:49:07 +0300
>> Could you add aliases for 'up' and 'down' in window-in-direction?
>> Then we won't need such special handling in windmove.el:
>>
>>    (window-in-direction
>>     (cond
>>      ((eq dir 'up) 'above)
>>      ((eq dir 'down) 'below)
>>      (t dir))
>>     window nil arg windmove-wrap-around t)
>
> Should be done now on master.  Please test.

Sorry, it still fails with (split-window nil nil 'up)  :-(




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Fri, 19 Oct 2018 07:40:02 GMT) Full text and rfc822 format available.

Message #95 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 19 Oct 2018 09:39:18 +0200
> Sorry, it still fails with (split-window nil nil 'up)  :-(

OK.  'split-window' handles your ups and downs too now ;-)

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sat, 20 Oct 2018 22:37:02 GMT) Full text and rfc822 format available.

Message #98 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 21 Oct 2018 00:27:23 +0300
>> Sorry, it still fails with (split-window nil nil 'up)  :-(
>
> OK.  'split-window' handles your ups and downs too now ;-)

Thank you!  I hope that now using the same logic we could solve the
long-standing annoyance in Emacs window management.  See for example
such situation: in two horizontally split windows, one window displays
a *grep* buffer (`emacs -Q  C-x 3  M-x grep ... RET').

But what to do if grep results need to be displayed in a new third
window above the *grep* buffer?  `C-x 2  C-x o  RET' will display
the source buffer in the wrong window (with the *scratch* buffer).

Using arrow keys as a prefix will allow to tell Emacs explicitly
where do you want to display the buffer, e.g.

H-up RET will display grep results in the above window after creating it

H-left C-h f will display the *Help* buffer in the left window

H-right C-x v d will display the vc-dir buffer in the right window

H-down C-x C-b will display the buffer list in the bottom window

The possibilities are limitless.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 21 Oct 2018 08:23:02 GMT) Full text and rfc822 format available.

Message #101 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 21 Oct 2018 10:22:47 +0200
> Thank you!  I hope that now using the same logic we could solve the
> long-standing annoyance in Emacs window management.  See for example
> such situation: in two horizontally split windows, one window displays
> a *grep* buffer (`emacs -Q  C-x 3  M-x grep ... RET').
>
> But what to do if grep results need to be displayed in a new third
> window above the *grep* buffer?  `C-x 2  C-x o  RET' will display
> the source buffer in the wrong window (with the *scratch* buffer).
>
> Using arrow keys as a prefix will allow to tell Emacs explicitly
> where do you want to display the buffer, e.g.
>
> H-up RET will display grep results in the above window after creating it
>
> H-left C-h f will display the *Help* buffer in the left window
>
> H-right C-x v d will display the vc-dir buffer in the right window
>
> H-down C-x C-b will display the buffer list in the bottom window
>
> The possibilities are limitless.

I fail to see the connection between hyper key bindings and the way to
display a buffer.  If at all, isn't that something Stephen Leake's
'other-frame-window' package is supposed to provide?

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 21 Oct 2018 19:20:03 GMT) Full text and rfc822 format available.

Message #104 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 21 Oct 2018 21:17:28 +0300
>> Using arrow keys as a prefix will allow to tell Emacs explicitly
>> where do you want to display the buffer, e.g.
>>
>> H-up RET will display grep results in the above window after creating it
>>
>> H-left C-h f will display the *Help* buffer in the left window
>>
>> H-right C-x v d will display the vc-dir buffer in the right window
>>
>> H-down C-x C-b will display the buffer list in the bottom window
>>
>> The possibilities are limitless.
>
> I fail to see the connection between hyper key bindings and the way to
> display a buffer.  If at all, isn't that something Stephen Leake's
> 'other-frame-window' package is supposed to provide?

other-frame-window is limited to the coarse choice, i.e. to display the
buffer in a random window on the same frame, or in another frame.

Whereas the needed feature is to allow the user to point out exactly
in which window the buffer should be displayed.  This can be achieved
with something like this:

(let ((modifiers '(hyper)))
  (dolist (key '(left right up down))
    (define-key global-map (vector (append modifiers (list key)))
                'display-buffer-directionally)))

(defun display-buffer-directionally ()
  "Specify in which direction the buffer should be displayed."
  (interactive "P")
  (let* ((dir (event-basic-type (aref (this-command-keys) 0)))
	 (win (window-in-direction dir)))
    (unless win
      (setq win (split-window nil nil dir)))
    (let ((hook (list 'lambda)))
      (setcdr hook `((window)
		     (when (eq window ,win)
		       ;; When a new buffer was displayed in that window,
		       ;; we can restore a previous value.
		       (setq display-buffer-overriding-action
			     ',display-buffer-overriding-action)
		       (remove-hook 'window-state-change-functions ',hook))))
      (add-hook 'window-state-change-functions hook))
    (setq display-buffer-overriding-action
	  `((lambda (buffer alist)
	      (window--display-buffer buffer ,win 'reuse alist))))))

Do you think conceptually this is the right direction of development?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 22 Oct 2018 09:08:01 GMT) Full text and rfc822 format available.

Message #107 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 22 Oct 2018 11:07:25 +0200
> other-frame-window is limited to the coarse choice, i.e. to display the
> buffer in a random window on the same frame, or in another frame.

It would indeed be nice to fix that there in some way.

> Whereas the needed feature is to allow the user to point out exactly
> in which window the buffer should be displayed.  This can be achieved
> with something like this:
>
> (let ((modifiers '(hyper)))
>    (dolist (key '(left right up down))
>      (define-key global-map (vector (append modifiers (list key)))
>                  'display-buffer-directionally)))
>
> (defun display-buffer-directionally ()
>    "Specify in which direction the buffer should be displayed."
>    (interactive "P")
>    (let* ((dir (event-basic-type (aref (this-command-keys) 0)))
> 	 (win (window-in-direction dir)))
>      (unless win
>        (setq win (split-window nil nil dir)))
>      (let ((hook (list 'lambda)))
>        (setcdr hook `((window)
> 		     (when (eq window ,win)
> 		       ;; When a new buffer was displayed in that window,
> 		       ;; we can restore a previous value.
> 		       (setq display-buffer-overriding-action
> 			     ',display-buffer-overriding-action)
> 		       (remove-hook 'window-state-change-functions ',hook))))
>        (add-hook 'window-state-change-functions hook))
>      (setq display-buffer-overriding-action
> 	  `((lambda (buffer alist)
> 	      (window--display-buffer buffer ,win 'reuse alist))))))
>
> Do you think conceptually this is the right direction of development?

Good idea.  But IIUC we can't use 'hyper' in Emacs because it is not
supposed to be generally present and must be bound to a key first.  So
we'd need some other mechanism.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 23 Oct 2018 21:18:02 GMT) Full text and rfc822 format available.

Message #110 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 23 Oct 2018 23:55:49 +0300
> It would indeed be nice to fix that there in some way.

There are not too many options that can be supported to make
Emacs window management more manageable.  I see at least these:

1. If the user knows beforehand in which window to display some
   particular buffer, then it's possible to customize display-buffer-alist.
   For example, instead of displaying *Backtrace* in a random window
   to make its placement more predictable:

   (custom-set-variables
    '(display-buffer-alist
      '(("\\`\\*Backtrace.*" display-buffer-below-selected))))

2. based on display-buffer-alist, implement some more declarative
   definitions of window layouts, i.e. allow the user to describe
   the used windows in which buffers should be displayed in them.

3. in some cases there is an one-off need to point out explicitly
   where to display the result of the next display-buffer command.
   If this will require only short code addition then better to have
   this feature in window.el.

> Good idea.  But IIUC we can't use 'hyper' in Emacs because it is not
> supposed to be generally present and must be bound to a key first.  So
> we'd need some other mechanism.

This is the same mechanism as already used by windmove-default-keybindings.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 24 Oct 2018 09:47:01 GMT) Full text and rfc822 format available.

Message #113 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Wed, 24 Oct 2018 11:45:49 +0200
>> It would indeed be nice to fix that there in some way.
>
> There are not too many options that can be supported to make
> Emacs window management more manageable.  I see at least these:
>
> 1. If the user knows beforehand in which window to display some
>     particular buffer, then it's possible to customize display-buffer-alist.
>     For example, instead of displaying *Backtrace* in a random window
>     to make its placement more predictable:
>
>     (custom-set-variables
>      '(display-buffer-alist
>        '(("\\`\\*Backtrace.*" display-buffer-below-selected))))

That's the status quo, I suppose.

> 2. based on display-buffer-alist, implement some more declarative
>     definitions of window layouts, i.e. allow the user to describe
>     the used windows in which buffers should be displayed in them.

I'd need to see a proposal how that can be done.  In a way it's
orthogonal to how 'window-state-put' tries to reconstruct a window
configuration and it's no entirely trivial to do that.

> 3. in some cases there is an one-off need to point out explicitly
>     where to display the result of the next display-buffer command.
>     If this will require only short code addition then better to have
>     this feature in window.el.

I think that 'display-buffer-directionally' is supposed do that.  But
this should rather go to windmove.el because directional key bindings
are already in use there.

>> Good idea.  But IIUC we can't use 'hyper' in Emacs because it is not
>> supposed to be generally present and must be bound to a key first.  So
>> we'd need some other mechanism.
>
> This is the same mechanism as already used by windmove-default-keybindings.

'windmove-default-keybindings' binds only the 'shift' modifier which
is "standard" so to say.  Binding the 'hyper' modifier is not standard
to my knowledge.  We could bind any combination of 'shift', 'control'
and 'meta' though.

But I think that putting a function on
'window-configuration-change-hook' can be dangerous when a window
showing the buffer in question already exists and gets reused.  In
such case 'window-configuration-change-hook' is not run and the
changed value of 'display-buffer-overriding-action' will persist.  So
we probably need a 'display-buffer-functions' hook to remove it
reliably.  Basically, however, I think that using an overriding action
is justified here.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 25 Oct 2018 20:58:01 GMT) Full text and rfc822 format available.

Message #116 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Thu, 25 Oct 2018 23:48:09 +0300
>> 2. based on display-buffer-alist, implement some more declarative
>>     definitions of window layouts, i.e. allow the user to describe
>>     the used windows in which buffers should be displayed in them.
>
> I'd need to see a proposal how that can be done.  In a way it's
> orthogonal to how 'window-state-put' tries to reconstruct a window
> configuration and it's no entirely trivial to do that.

I imagine it could be a structure like returned by 'window-state-get'
but instead of a buffer name specify a regexp or a list of possible
buffer names that are allowed to be displayed in the given window.
Then display-buffer could search a buffer in such template and
reconstruct the window state where the buffer will be displayed in
the place specified in the template.

> But I think that putting a function on
> 'window-configuration-change-hook' can be dangerous when a window
> showing the buffer in question already exists and gets reused.  In
> such case 'window-configuration-change-hook' is not run and the
> changed value of 'display-buffer-overriding-action' will persist.  So
> we probably need a 'display-buffer-functions' hook to remove it
> reliably.  Basically, however, I think that using an overriding action
> is justified here.

Please note that in the code posted 3 days ago I used the hook that you
proposed recently window-state-change-functions, so this code is not yet
functional :)




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Fri, 26 Oct 2018 07:42:02 GMT) Full text and rfc822 format available.

Message #119 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 26 Oct 2018 09:41:34 +0200
> I imagine it could be a structure like returned by 'window-state-get'
> but instead of a buffer name specify a regexp or a list of possible
> buffer names that are allowed to be displayed in the given window.
> Then display-buffer could search a buffer in such template and
> reconstruct the window state where the buffer will be displayed in
> the place specified in the template.

I see what you mean.  But it will take us some time till we get there.
Alone specifying such a thing would be a quite challenging endeavour.

> Please note that in the code posted 3 days ago I used the hook that you
> proposed recently window-state-change-functions, so this code is not yet
> functional :)

Ahh.. That hook has not been written yet and I'm not sure whether I'll
be able to ever do that.  In either case: The window state will not
change when a window gets just reused by 'display-buffer' and no
selection takes place.  So can't you simply use 'post-command-hook'
for your purpose?

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sat, 27 Oct 2018 20:21:02 GMT) Full text and rfc822 format available.

Message #122 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sat, 27 Oct 2018 22:51:05 +0300
[Message part 1 (text/plain, inline)]
>> Please note that in the code posted 3 days ago I used the hook that you
>> proposed recently window-state-change-functions, so this code is not yet
>> functional :)
>
> Ahh.. That hook has not been written yet and I'm not sure whether I'll
> be able to ever do that.  In either case: The window state will not
> change when a window gets just reused by 'display-buffer' and no
> selection takes place.  So can't you simply use 'post-command-hook'
> for your purpose?

The implementation of window-state-change-functions posted to bug#32672
uses post-command-hook.  It makes possible display-buffer-directionally,
e.g. S-M-up ffap RET will open a file link in the upper window, etc.

[display-buffer-directionally.2.el (application/emacs-lisp, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 28 Oct 2018 09:01:02 GMT) Full text and rfc822 format available.

Message #125 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 28 Oct 2018 09:59:57 +0100
> The implementation of window-state-change-functions posted to bug#32672
> uses post-command-hook.  It makes possible display-buffer-directionally,
> e.g. S-M-up ffap RET will open a file link in the upper window, etc.

Yes.  But as I said in the thread for Bug#32672 running
'window-state-change-functions' only after a command gets executed may
miss a number of important cases where the hook should be run as well.

Once more: What could go posibly wrong if you added 'hook' to
'post-command-hook' and unconditionally (that is completely
disregarding whether a buffer display action succeeded or not) removed
the overriding action there.  If you are paranoiac about this, you can
even restore the old value of 'display-buffer-overriding-action' if
and only if the new value (when running 'post-command-hook') is the
one you wrote there ealier and leave any other value alone (because it
was probably put there by the command executed).

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 28 Oct 2018 19:41:02 GMT) Full text and rfc822 format available.

Message #128 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 28 Oct 2018 21:36:54 +0200
> Once more: What could go posibly wrong if you added 'hook' to
> 'post-command-hook' and unconditionally (that is completely
> disregarding whether a buffer display action succeeded or not) removed
> the overriding action there.

Please note that for example S-M-up M-x ffap RET RET involves
the minibuffer before a buffer-displaying command is executed.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 29 Oct 2018 08:46:01 GMT) Full text and rfc822 format available.

Message #131 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 29 Oct 2018 09:44:53 +0100
>> Once more: What could go posibly wrong if you added 'hook' to
>> 'post-command-hook' and unconditionally (that is completely
>> disregarding whether a buffer display action succeeded or not) removed
>> the overriding action there.
>
> Please note that for example S-M-up M-x ffap RET RET involves
> the minibuffer before a buffer-displaying command is executed.

One more argument against using 'window-state-change-functions' or the
like.  Selecting the minibuffer window would count as a state change
and immediately reinstall the previous overriding action.

Rather, the function on 'post-command-hook' would have to be more
intelligent - check whether the minibuffer-window is selected and
leave the overriding action untouched in that case.  Moreover, using
'post-command-hook' would automatically fix any problems when quitting
an S-M-up action.  I see no way to catch quitting via a state change
of windows.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 29 Oct 2018 13:47:01 GMT) Full text and rfc822 format available.

Message #134 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 29 Oct 2018 14:45:56 +0100
> Please note that for example S-M-up M-x ffap RET RET involves
> the minibuffer before a buffer-displaying command is executed.

I forgot to ask: If that ffap pops up completions, they will appear
above the selected window.  Right?

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 29 Oct 2018 22:54:02 GMT) Full text and rfc822 format available.

Message #137 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 30 Oct 2018 00:38:08 +0200
> Rather, the function on 'post-command-hook' would have to be more
> intelligent - check whether the minibuffer-window is selected and
> leave the overriding action untouched in that case.

It's possible to implement it with post-command-hook, but the
implementation will be more contorted - note that adding a hook
to post-command-hook by a command will run it immediately
at the end of this command and immediately remove the hook.

Whereas window-state-change-functions elegantly checks
if the window displays a new buffer.

> Moreover, using 'post-command-hook' would automatically fix any
> problems when quitting an S-M-up action.  I see no way to catch
> quitting via a state change of windows.

What do you mean by quitting an S-M-up action?  minibuffer-exit?

> I forgot to ask: If that ffap pops up completions, they will appear
> above the selected window.  Right?

Right.  Since I agree this is not an expected behavior, here is a better
version without this problem.  Instead of display-buffer-overriding-action,
it uses display-buffer-alist because only display-buffer-alist
supports a condition necessary to check for an active minibuffer.

(defun display-buffer-directionally ()
  "Specify in which direction the buffer should be displayed.
Arrows show the direction.  Mod-0 forces to display in the same window."
  (interactive)
  (let* ((dir (event-basic-type (aref (this-command-keys) 0)))
         (win (if (eq dir ?0)
		  (selected-window)
		(or (window-in-direction dir)
		    (split-window nil nil dir)))))
    (let ((hook (list 'lambda)))
      (setcdr hook `((window alist)
                     (when (and (eq window ,win)
                                (not (eq (nth 1 (assq 'buffer alist))
                                         (nth 2 (assq 'buffer alist)))))
                       (setq display-buffer-alist (cdr display-buffer-alist))
                       (remove-hook 'window-state-change-functions ',hook))))
      (add-hook 'window-state-change-functions hook))
    (setq display-buffer-alist
	  (cons `((lambda (_buffer-name _action) ; condition
		    (= (minibuffer-depth) 0))
		  (lambda (buffer alist)         ; action
		    (window--display-buffer buffer ,win 'reuse alist)))
		display-buffer-alist))))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 30 Oct 2018 09:01:01 GMT) Full text and rfc822 format available.

Message #140 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 30 Oct 2018 10:00:07 +0100
>> Rather, the function on 'post-command-hook' would have to be more
>> intelligent - check whether the minibuffer-window is selected and
>> leave the overriding action untouched in that case.
>
> It's possible to implement it with post-command-hook, but the
> implementation will be more contorted - note that adding a hook
> to post-command-hook by a command will run it immediately
> at the end of this command and immediately remove the hook.

The mechanism must be safe in the first place and safety means here to
remove the mechanism before anything bad happens.

> Whereas window-state-change-functions elegantly checks
> if the window displays a new buffer.

But it fails when a window gets reused.  In general, any outcome of
'display-buffer' is possible, even 'allow-no-window'.  As soon as
'display-buffer' returns and no change of the window state happened we
are lost.

>> Moreover, using 'post-command-hook' would automatically fix any
>> problems when quitting an S-M-up action.  I see no way to catch
>> quitting via a state change of windows.
>
> What do you mean by quitting an S-M-up action?  minibuffer-exit?

Let's say anything C-g does.  I'm not sure whether we can catch that
always via 'minibuffer-exit-hook' though.  But it should not harm to
remove the overriding action in that case as well.

>> I forgot to ask: If that ffap pops up completions, they will appear
>> above the selected window.  Right?
>
> Right.  Since I agree this is not an expected behavior, here is a better
> version without this problem.  Instead of display-buffer-overriding-action,
> it uses display-buffer-alist because only display-buffer-alist
> supports a condition necessary to check for an active minibuffer.

As a rule, code must never fiddle with 'display-buffer-alist'.  If
anything gets wrong, the user is left with a broken customization.  If
'display-buffer-overriding-action' is not capable of handling this
scenario, then it's useless and we have to provide something better
anyway.

Now 'display-buffer-overriding-action' has the same deficiencies as
'pop-up-frames' and 'pop-up-windows'.  If you bind them around a
minibuffer interaction needed to find the buffer to display, you
affect that minibuffer interaction and any recursive 'display-buffer'
call that interaction emits too.

So what we need is a mechanism that (1) specifies a display action for
a buffer whose identity has not been specified yet at the time
'display-buffer' (or one of its callers) gets called and (2) does not
affect any calls of 'display-buffer' needed to get the identity of the
buffer needed by (1).  I think we agree on that.

So we want to delay the effect of 'display-buffer-overriding-action'
until it applies to the buffer the user had in mind when activating
the key combination.  Since we don't know the name of the buffer yet
(and in the worst case the name of the buffer the user wants to
display in a specific position is that of a buffer needed to find the
name), we need some sort of workaround.  I'm afraid we have to agree
on that as well.

I'm not sure whether checking 'minibuffer-depth' within the function
put on 'display-buffer-overriding-action' is sufficient.  That is,
have the overriding action take effect iff the depth is zero.  Please
check that first (I have no idea why you didn't try that before and
went for setting 'display-buffer-alist' instead).

If it doesn't help, we could equip 'display-buffer' itself with some
sort of recursion depth and allow the S-M- combination to apply only
when the level is zero.  We'd need some sort of escape to reset that
depth when a user aborts the buffer display action.  And it obviously
would disallow recursive application of the S-M- mechanism (like the
'minibuffer-depth' check approach).  So hopefully we find something
better.

But as soon as we have found a solution, we could provide prefixes to
handle all sorts of -same-window/-other-window/-other-frame and the
default display in a similar fashion.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 30 Oct 2018 21:54:01 GMT) Full text and rfc822 format available.

Message #143 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 30 Oct 2018 23:42:07 +0200
>>> Moreover, using 'post-command-hook' would automatically fix any
>>> problems when quitting an S-M-up action.  I see no way to catch
>>> quitting via a state change of windows.
>>
>> What do you mean by quitting an S-M-up action?  minibuffer-exit?
>
> Let's say anything C-g does.  I'm not sure whether we can catch that
> always via 'minibuffer-exit-hook' though.  But it should not harm to
> remove the overriding action in that case as well.

Ok, after a small change it handles also C-g:

(defun display-buffer-directionally ()
  "Specify in which direction the buffer should be displayed.
Arrows show the direction.  Mod-0 forces to display in the same window."
  (interactive)
  (let* ((dir (event-basic-type (aref (this-command-keys) 0)))
         (win (if (eq dir ?0)
		  (selected-window)
		(or (window-in-direction dir)
		    (split-window nil nil dir)))))
    (let ((hook (list 'lambda)))
      (setcdr hook `(()
                     (unless (or
			      ;; Remove the hook immediately
			      ;; after exiting the minibuffer.
			      (> (minibuffer-depth) 0)
			      ;; But don't remove immediately after
			      ;; adding the hook by the same command.
			      (eq this-command ',this-command))
                       (setq display-buffer-overriding-action
                             ',display-buffer-overriding-action)
                       (remove-hook 'post-command-hook ',hook))))
      (add-hook 'post-command-hook hook))
    (setq display-buffer-overriding-action
          `((lambda (buffer alist)
              (unless (> (minibuffer-depth) 0)
		(window--display-buffer buffer ,win 'reuse alist)))))))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 31 Oct 2018 08:13:02 GMT) Full text and rfc822 format available.

Message #146 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Wed, 31 Oct 2018 09:11:52 +0100
> Ok, after a small change it handles also C-g:

I forgot (or never learned) how to use it.  Can you please include an
example so people can try it.

> (defun display-buffer-directionally ()
>    "Specify in which direction the buffer should be displayed.
> Arrows show the direction.  Mod-0 forces to display in the same window."
>    (interactive)
>    (let* ((dir (event-basic-type (aref (this-command-keys) 0)))
>           (win (if (eq dir ?0)
> 		  (selected-window)
> 		(or (window-in-direction dir)
> 		    (split-window nil nil dir)))))
>      (let ((hook (list 'lambda)))
>        (setcdr hook `(()
>                       (unless (or
> 			      ;; Remove the hook immediately
> 			      ;; after exiting the minibuffer.
> 			      (> (minibuffer-depth) 0)
> 			      ;; But don't remove immediately after
> 			      ;; adding the hook by the same command.
> 			      (eq this-command ',this-command))

Can you give the rationale for the latter?  I don't grok it.

>                         (setq display-buffer-overriding-action
>                               ',display-buffer-overriding-action)
>                         (remove-hook 'post-command-hook ',hook))))
>        (add-hook 'post-command-hook hook))
>      (setq display-buffer-overriding-action
>            `((lambda (buffer alist)
>                (unless (> (minibuffer-depth) 0)
> 		(window--display-buffer buffer ,win 'reuse alist)))))))

'reuse' holds only for the ?0 case.  When we split, the third argument
should be 'window'.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 31 Oct 2018 21:37:03 GMT) Full text and rfc822 format available.

Message #149 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Wed, 31 Oct 2018 23:20:13 +0200
>> Ok, after a small change it handles also C-g:
>
> I forgot (or never learned) how to use it.  Can you please include an
> example so people can try it.

An example is this:

(let ((modifiers '(shift meta)))
  (dolist (key '(left right up down ?0))
    (define-key global-map (vector (append modifiers (list key)))
      'display-buffer-directionally)))

>> 			      ;; But don't remove immediately after
>> 			      ;; adding the hook by the same command.
>> 			      (eq this-command ',this-command))
>
> Can you give the rationale for the latter?  I don't grok it.

When display-buffer-directionally is called, it adds the hook
to post-command-hook, and when display-buffer-directionally finishes,
post-command-hook is called, and immediately removes itself from
post-command-hook.  This condition ensures that the hook is removed
only when post-command-hook is called after a next command finishes
(while the minibuffer is inactive).

>>                         (setq display-buffer-overriding-action
>>                               ',display-buffer-overriding-action)
>>                         (remove-hook 'post-command-hook ',hook))))
>>        (add-hook 'post-command-hook hook))
>>      (setq display-buffer-overriding-action
>>            `((lambda (buffer alist)
>>                (unless (> (minibuffer-depth) 0)
>> 		(window--display-buffer buffer ,win 'reuse alist)))))))
>
> 'reuse' holds only for the ?0 case.  When we split, the third argument
> should be 'window'.

I noticed that when replaced with

(window--display-buffer buffer ,win ',(if (eq dir ?0) 'reuse 'window) alist)

then 'window means that killing the buffer will delete its window.

Another observation is that switch-to-buffer is unaffected by this command.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 01 Nov 2018 09:04:02 GMT) Full text and rfc822 format available.

Message #152 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Thu, 01 Nov 2018 10:03:21 +0100
>> I forgot (or never learned) how to use it.  Can you please include an
>> example so people can try it.
>
> An example is this:
[...]

Yes.  But when I now try your earlier example

S-M-up M-x ffap RET RET

with emacs -Q, after the S-M-up the *scratch* window is just split.
What am I missing?

> When display-buffer-directionally is called, it adds the hook
> to post-command-hook, and when display-buffer-directionally finishes,
> post-command-hook is called, and immediately removes itself from
> post-command-hook.  This condition ensures that the hook is removed
> only when post-command-hook is called after a next command finishes
> (while the minibuffer is inactive).

Can you give an example of a sequence of events how this should work
in practice and which scenario it is supposed to avoid?  The term
"next command" is not clear to me here.

And wouldn't it be more intuitive to check the minibuffer depth
instead?  That is, let the lambda succeed to do its job iff the
current value of 'minibuffer-depth' equals the value of
'minibuffer-depth' at the time 'display-buffer-overriding-action' was
set to the lambda.

>>> 		(window--display-buffer buffer ,win 'reuse alist)))))))
>>
>> 'reuse' holds only for the ?0 case.  When we split, the third argument
>> should be 'window'.
>
> I noticed that when replaced with
>
> (window--display-buffer buffer ,win ',(if (eq dir ?0) 'reuse 'window) alist)
>
> then 'window means that killing the buffer will delete its window.

What's bad about that?  What else do you want the window to show?  If
the window got reused, it's natural to show the buffer it showed
previously.  If the window was created anew, it's the most natural
thing to delete it when its buffer gets killed.  If we want to change
that, we can add an option.  But the way you do it, you completely
mess up the semantics of the 'quit-restore' mechanism by faking its
history.

> Another observation is that switch-to-buffer is unaffected by this command.

As long as it does not end up calling 'display-buffer', yes.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 01 Nov 2018 22:47:02 GMT) Full text and rfc822 format available.

Message #155 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 02 Nov 2018 00:42:57 +0200
>>> I forgot (or never learned) how to use it.  Can you please include an
>>> example so people can try it.
>>
>> An example is this:
> [...]
>
> Yes.  But when I now try your earlier example
>
> S-M-up M-x ffap RET RET
>
> with emacs -Q, after the S-M-up the *scratch* window is just split.
> What am I missing?

This is intended behavior - the window is split, so you can see the
window where a new buffer will be displayed after you invoke
the next command (e.g. 'ffap').

>> When display-buffer-directionally is called, it adds the hook
>> to post-command-hook, and when display-buffer-directionally finishes,
>> post-command-hook is called, and immediately removes itself from
>> post-command-hook.  This condition ensures that the hook is removed
>> only when post-command-hook is called after a next command finishes
>> (while the minibuffer is inactive).
>
> Can you give an example of a sequence of events how this should work
> in practice and which scenario it is supposed to avoid?  The term
> "next command" is not clear to me here.

An example of "next command" is 'ffap' in the earlier example.

> And wouldn't it be more intuitive to check the minibuffer depth
> instead?  That is, let the lambda succeed to do its job iff the
> current value of 'minibuffer-depth' equals the value of
> 'minibuffer-depth' at the time 'display-buffer-overriding-action' was
> set to the lambda.

Yes, this will allow using S-M-up from the active minibuffer.

>>>> 		(window--display-buffer buffer ,win 'reuse alist)))))))
>>>
>>> 'reuse' holds only for the ?0 case.  When we split, the third argument
>>> should be 'window'.
>>
>> I noticed that when replaced with
>>
>> (window--display-buffer buffer ,win ',(if (eq dir ?0) 'reuse 'window) alist)
>>
>> then 'window means that killing the buffer will delete its window.
>
> What's bad about that?  What else do you want the window to show?  If
> the window got reused, it's natural to show the buffer it showed
> previously.  If the window was created anew, it's the most natural
> thing to delete it when its buffer gets killed.  If we want to change
> that, we can add an option.  But the way you do it, you completely
> mess up the semantics of the 'quit-restore' mechanism by faking its
> history.

Yes, killing the buffer without deleting its window will display
some random buffer in its place - this is bad.

>> Another observation is that switch-to-buffer is unaffected by this command.
>
> As long as it does not end up calling 'display-buffer', yes.

I'm not sure if switch-to-buffer should use pop-to-buffer-same-window,
probably not.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Fri, 02 Nov 2018 08:46:01 GMT) Full text and rfc822 format available.

Message #158 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 02 Nov 2018 09:44:49 +0100
>> S-M-up M-x ffap RET RET
>>
>> with emacs -Q, after the S-M-up the *scratch* window is just split.
>> What am I missing?
>
> This is intended behavior - the window is split, so you can see the
> window where a new buffer will be displayed after you invoke
> the next command (e.g. 'ffap').

Looks uncomfortable, unprofessional.  Do you think we can ever sell
that?

>> Can you give an example of a sequence of events how this should work
>> in practice and which scenario it is supposed to avoid?  The term
>> "next command" is not clear to me here.
>
> An example of "next command" is 'ffap' in the earlier example.

I understand now.

>> And wouldn't it be more intuitive to check the minibuffer depth
>> instead?  That is, let the lambda succeed to do its job iff the
>> current value of 'minibuffer-depth' equals the value of
>> 'minibuffer-depth' at the time 'display-buffer-overriding-action' was
>> set to the lambda.
>
> Yes, this will allow using S-M-up from the active minibuffer.

I had that in mind as a side-effect.  But we should really get rid of
this split-first-decide-what-to-put-there-afterwards approach first.

> Yes, killing the buffer without deleting its window will display
> some random buffer in its place - this is bad.

We could display a buffer that was previously shown in that window if
there is one.  But I think that such a buffer might be there just due
to a temporary excursion so I don't think it's a good idea.

> I'm not sure if switch-to-buffer should use pop-to-buffer-same-window,
> probably not.

'switch-to-buffer' obeys 'switch-to-buffer-preserve-window-point'
while 'pop-to-buffer-same-window' doesn't.  That's the main reason to
keep the present code (and one reason to replace 'switch-to-buffer'
with 'pop-to-buffer-same-window' in Lisp code).

There is also that special handling of dedicated windows but I doubt
it's ever needed in practice.  Dedicated windows are Stefan's
department and while I had to live with the ugliness of
'display-buffer-mark-dedicated' it also relieved me from caring about
specifying dedicatedness in buffer display elsewhere.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Fri, 02 Nov 2018 14:37:02 GMT) Full text and rfc822 format available.

Message #161 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Drew Adams <drew.adams <at> oracle.com>
To: martin rudalics <rudalics <at> gmx.at>, Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: RE: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 2 Nov 2018 07:36:34 -0700 (PDT)
FWIW -

I distinguish interactive use of `kill-buffer' from
programmatic use.  Interactively I want any windows
showing the buffer to disappear too.  Interactively
I substitute `kill-buffer-and-its-windows'.  I've
been doing this at least since the mid-90s.  

Dunno whether I'm alone in this preference, or would
be even if it were offered more widely.

Just for reference, here's the definition I'm still
using, but you can no doubt come up with something
better or more recent.

(defun kill-buffer-and-its-windows (buffer)
  "Kill BUFFER and delete its windows."
  (interactive (list (read-buffer "Kill buffer: "
                                  (current-buffer)
                                  'existing)))
  (setq buffer  (get-buffer buffer))
  (if (buffer-live-p buffer)
      (let ((wins  (get-buffer-window-list buffer nil t)))
        (when (kill-buffer buffer)
          (dolist (win  wins)
            (when (window-live-p win)
              (condition-case nil
                  (delete-window win)
                (error nil))))))
    (when (interactive-p)
      (error "Cannot kill buffer. Not a live buffer: `%s'"
             buffer))))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 04 Nov 2018 22:23:01 GMT) Full text and rfc822 format available.

Message #164 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 05 Nov 2018 00:01:25 +0200
>> Yes, killing the buffer without deleting its window will display
>> some random buffer in its place - this is bad.
>
> We could display a buffer that was previously shown in that window if
> there is one.  But I think that such a buffer might be there just due
> to a temporary excursion so I don't think it's a good idea.

Actually there is some problem with the third argument 'window' of
window--display-buffer:

0. emacs -Q

1. C-h e
   displays *Messages* in another window

2. in *scratch* eval:

   (window--display-buffer (get-buffer-create "test1") (next-window) 'window)

   displays "test1" in the window where *Messages* was displayed

3. C-x o
   select the window with "test1"

4. M-: (quit-window 1)
   the window is deleted.

I'd expect that it shouldn't delete the window, but should restore the
buffer previously displayed in that window, i.e. the *Messages* buffer,
because this is what quit-window does when the "test1" buffer was created
manually with e.g. 'C-x b test1'.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 04 Nov 2018 22:23:02 GMT) Full text and rfc822 format available.

Message #167 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 05 Nov 2018 00:07:35 +0200
> Here <H-left> drags the character under the cursor by one character to
> the left and <H-up> drags the current line up by one line.  I use
> <M-S-left> for selecting the window on the left.  <C-M-S-left> either
> deletes the window on the left of the selected window provided there
> is one or makes a new window on the left of the selected window
> provided the selected window is already on the left of the frame.

Making a new window is especially good idea.  So I implemented
this feature in windmove.el:

diff --git a/lisp/windmove.el b/lisp/windmove.el
index 42e10b591f..69f2a9665a 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -149,6 +149,15 @@ windmove-wrap-around
   :type 'boolean
   :group 'windmove)
 
+(defcustom windmove-create-window nil
+  "Whether movement off the edge of the frame creates a new window.
+If this variable is set to t, moving left from the leftmost window in
+a frame will create a new window on the left, and similarly for the other
+directions."
+  :type 'boolean
+  :group 'windmove
+  :version "27.1")
+
 ;; If your Emacs sometimes places an empty column between two adjacent
 ;; windows, you may wish to set this delta to 2.
 (defcustom windmove-window-distance-delta 1
@@ -471,8 +480,15 @@ windmove-find-other-window
 (defun windmove-do-window-select (dir &optional arg window)
   "Move to the window at direction DIR.
 DIR, ARG, and WINDOW are handled as by `windmove-other-window-loc'.
-If no window is at direction DIR, an error is signaled."
+If no window is at direction DIR, an error is signaled.
+If `windmove-create-window' is non-nil, instead of signalling an error
+it creates a new window at direction DIR ."
   (let ((other-window (windmove-find-other-window dir arg window)))
+    (when (and windmove-create-window
+               (or (null other-window)
+                   (and (window-minibuffer-p other-window)
+                        (not (minibuffer-window-active-p other-window)))))
+      (setq other-window (split-window window nil dir)))
     (cond ((null other-window)
            (user-error "No window %s from selected window" dir))
           ((and (window-minibuffer-p other-window)
@@ -493,7 +509,8 @@ windmove-left
 \"left\" is relative to the position of point in the window; otherwise
 it is relative to the top edge (for positive ARG) or the bottom edge
 \(for negative ARG) of the current window.
-If no window is at the desired location, an error is signaled."
+If no window is at the desired location, an error is signaled
+unless `windmove-create-window' is non-nil."
   (interactive "P")
   (windmove-do-window-select 'left arg))
 
@@ -504,7 +521,8 @@ windmove-up
 is relative to the position of point in the window; otherwise it is
 relative to the left edge (for positive ARG) or the right edge (for
 negative ARG) of the current window.
-If no window is at the desired location, an error is signaled."
+If no window is at the desired location, an error is signaled
+unless `windmove-create-window' is non-nil."
   (interactive "P")
   (windmove-do-window-select 'up arg))
 
@@ -515,7 +533,8 @@ windmove-right
 \"right\" is relative to the position of point in the window;
 otherwise it is relative to the top edge (for positive ARG) or the
 bottom edge (for negative ARG) of the current window.
-If no window is at the desired location, an error is signaled."
+If no window is at the desired location, an error is signaled
+unless `windmove-create-window' is non-nil."
   (interactive "P")
   (windmove-do-window-select 'right arg))
 
@@ -526,7 +545,8 @@ windmove-down
 \"down\" is relative to the position of point in the window; otherwise
 it is relative to the left edge (for positive ARG) or the right edge
 \(for negative ARG) of the current window.
-If no window is at the desired location, an error is signaled."
+If no window is at the desired location, an error is signaled
+unless `windmove-create-window' is non-nil."
   (interactive "P")
   (windmove-do-window-select 'down arg))
 




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 04 Nov 2018 22:23:02 GMT) Full text and rfc822 format available.

Message #170 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 05 Nov 2018 00:21:14 +0200
> I had that in mind as a side-effect.  But we should really get rid of
> this split-first-decide-what-to-put-there-afterwards approach first.

I agree split-first-decide-what-to-put-there-afterwards is too ugly.

So following your suggestion I reimplemented this feature in windmove.el
because it fits its description "directional window-selection routines":

diff --git a/lisp/windmove.el b/lisp/windmove.el
index 42e10b591f..69f2a9665a 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -1,4 +1,4 @@
-;;; windmove.el --- directional window-selection routines
+;;; windmove.el --- directional window-selection routines  -*- lexical-binding:t -*-
 ;;
 ;; Copyright (C) 1998-2018 Free Software Foundation, Inc.
 ;;
@@ -551,6 +571,86 @@ windmove-default-keybindings
   (global-set-key (vector (append modifiers '(up)))    'windmove-up)
   (global-set-key (vector (append modifiers '(down)))  'windmove-down))
 
+;;; Directional window display
+
+(defun windmove-display-in-direction (dir)
+  "Display the next buffer in the window at direction DIR.
+Create a new window if there is no window in that direction."
+  (interactive)
+  (let* ((command this-command)
+         (depth (minibuffer-depth))
+         (action display-buffer-overriding-action)
+         (clearfun (make-symbol "clear-display-buffer-overriding-action"))
+         (exitfun
+          (lambda ()
+            (setq display-buffer-overriding-action action)
+            (remove-hook 'post-command-hook clearfun))))
+    (fset clearfun
+          (lambda ()
+            (unless (or
+		     ;; Remove the hook immediately
+		     ;; after exiting the minibuffer.
+		     (> (minibuffer-depth) depth)
+		     ;; But don't remove immediately after
+		     ;; adding the hook by the same command.
+		     (eq this-command command))
+              (funcall exitfun))))
+    (add-hook 'post-command-hook clearfun)
+    (push (lambda (buffer alist)
+	    (unless (> (minibuffer-depth) depth)
+	      (let ((win (if (eq dir 'same-window)
+			     (selected-window)
+			   (or (window-in-direction dir)
+			       (split-window nil nil dir)))))
+		(window--display-buffer
+		 buffer win (if (eq dir 'same-window) 'reuse 'window) alist))))
+          display-buffer-overriding-action)
+    (message "[display-%s]" dir)))
+
+;;;###autoload
+(defun windmove-display-left (&optional _arg)
+  "Display the next buffer in window to the left of the current one."
+  (interactive "P")
+  (windmove-display-in-direction 'left))
+
+;;;###autoload
+(defun windmove-display-up (&optional _arg)
+  "Display the next buffer in window above the current one."
+  (interactive "P")
+  (windmove-display-in-direction 'up))
+
+;;;###autoload
+(defun windmove-display-right (&optional _arg)
+  "Display the next buffer in window to the right of the current one."
+  (interactive "P")
+  (windmove-display-in-direction 'right))
+
+;;;###autoload
+(defun windmove-display-down (&optional _arg)
+  "Display the next buffer in window below the current one."
+  (interactive "P")
+  (windmove-display-in-direction 'down))
+
+;;;###autoload
+(defun windmove-display-same-window (&optional _arg)
+  "Display the next buffer in window below the current one."
+  (interactive "P")
+  (windmove-display-in-direction 'same-window))
+
+;;;###autoload
+(defun windmove-display-default-keybindings (&optional modifiers)
+  "Set up keybindings for directional display.
+Keybindings are of the form MODIFIERS-{left,right,up,down},
+where MODIFIERS is either a list of modifiers or a single modifier.
+Default value of MODIFIERS is `shift-meta'."
+  (interactive)
+  (unless modifiers (setq modifiers '(shift meta)))
+  (unless (listp modifiers) (setq modifiers (list modifiers)))
+  (global-set-key (vector (append modifiers '(left)))  'windmove-display-left)
+  (global-set-key (vector (append modifiers '(right))) 'windmove-display-right)
+  (global-set-key (vector (append modifiers '(up)))    'windmove-display-up)
+  (global-set-key (vector (append modifiers '(down)))  'windmove-display-down)
+  (global-set-key (vector (append modifiers '(?0)))    'windmove-display-same-window))
 
 (provide 'windmove)
 




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 05 Nov 2018 09:36:02 GMT) Full text and rfc822 format available.

Message #173 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 05 Nov 2018 10:35:35 +0100
> Actually there is some problem with the third argument 'window' of
> window--display-buffer:
>
> 0. emacs -Q
>
> 1. C-h e
>     displays *Messages* in another window
>
> 2. in *scratch* eval:
>
>     (window--display-buffer (get-buffer-create "test1") (next-window) 'window)
>
>     displays "test1" in the window where *Messages* was displayed
>
> 3. C-x o
>     select the window with "test1"
>
> 4. M-: (quit-window 1)
>     the window is deleted.
>
> I'd expect that it shouldn't delete the window, but should restore the
> buffer previously displayed in that window, i.e. the *Messages* buffer,
> because this is what quit-window does when the "test1" buffer was created
> manually with e.g. 'C-x b test1'.

That's because you told 'window--display-buffer' a lie: You did _not_
create a new window but reused an existing one.  Try with

(window--display-buffer (get-buffer-create "test1") (next-window) 'reuse)

instead.

Ideally, 'window--display-buffer' would find out itself whether a new
window or frame was made or an existing one reused.  But for that
purpose 'display-buffer' would have to store away the identity of all
windows and frames that existed before any action function was called
so 'window--display-buffer' could compare these against the state
after display.

I earlier used such a solution in 'display-buffer-pretend' and may
revive it if that function ever gets installed.  But for normal
'display-buffer' the overhead is somehow annoying.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 05 Nov 2018 09:36:02 GMT) Full text and rfc822 format available.

Message #176 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 05 Nov 2018 10:35:49 +0100
> +(defcustom windmove-create-window nil
> +  "Whether movement off the edge of the frame creates a new window.
> +If this variable is set to t, moving left from the leftmost window in
> +a frame will create a new window on the left, and similarly for the other
> +directions."

You should say here that a non-nil values abolishes the wrap-around
behavior and in the doc-string of 'windmove-wrap-around' say that it
has no effect if 'windmove-create-window' is non-nil.

And how gracefully should we handle failures of 'split-window'?

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 05 Nov 2018 09:37:01 GMT) Full text and rfc822 format available.

Message #179 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 05 Nov 2018 10:36:18 +0100
> So following your suggestion I reimplemented this feature in windmove.el
> because it fits its description "directional window-selection routines":

Looks very good now.  This one

> +;;;###autoload
> +(defun windmove-display-default-keybindings (&optional modifiers)

should be wrapped in a 'defcustom' IMHO.  And while I think that the
prompt-like

(message "[display-%s]" dir)

is a good idea, it might fire back when the selected frame does not
have an echo area.  So I think it should be made customizable too.

IMHO we should provide l, r, u/t, d/b directional keybindings as well.

And eventually we could provide something for handling frames too---in
particular, moving to and/or popping up a new frame adjacent to the
selected one on either side.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 05 Nov 2018 22:16:02 GMT) Full text and rfc822 format available.

Message #182 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 06 Nov 2018 00:12:01 +0200
>> +(defcustom windmove-create-window nil
>> +  "Whether movement off the edge of the frame creates a new window.
>> +If this variable is set to t, moving left from the leftmost window in
>> +a frame will create a new window on the left, and similarly for the other
>> +directions."
>
> You should say here that a non-nil values abolishes the wrap-around
> behavior and in the doc-string of 'windmove-wrap-around' say that it
> has no effect if 'windmove-create-window' is non-nil.

'windmove-create-window' is very useful with non-nil value of
'windmove-wrap-around' - this is what I actually use.

This means that no more than 2 windows can be created in any direction,
and this is fine.

> And how gracefully should we handle failures of 'split-window'?

Not important for windmove-do-window-select.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 05 Nov 2018 22:17:01 GMT) Full text and rfc822 format available.

Message #185 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 06 Nov 2018 00:14:11 +0200
>> So following your suggestion I reimplemented this feature in windmove.el
>> because it fits its description "directional window-selection routines":
>
> Looks very good now.  This one
>
>> +;;;###autoload
>> +(defun windmove-display-default-keybindings (&optional modifiers)
>
> should be wrapped in a 'defcustom' IMHO.

This is a copy of the existing windmove-default-keybindings
that has no defcustom.

> And while I think that the prompt-like
>
> (message "[display-%s]" dir)
>
> is a good idea, it might fire back when the selected frame does not
> have an echo area.  So I think it should be made customizable too.

What bad will happen when the selected frame has no echo area?

> IMHO we should provide l, r, u/t, d/b directional keybindings as well.

Maybe then h/j/k/l or b/f/n/p?

> And eventually we could provide something for handling frames too---in
> particular, moving to and/or popping up a new frame adjacent to the
> selected one on either side.

I agree, this would be nice.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 06 Nov 2018 08:48:01 GMT) Full text and rfc822 format available.

Message #188 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 06 Nov 2018 09:47:08 +0100
> 'windmove-create-window' is very useful with non-nil value of
> 'windmove-wrap-around' - this is what I actually use.
>
> This means that no more than 2 windows can be created in any direction,
> and this is fine.
>
>> And how gracefully should we handle failures of 'split-window'?
>
> Not important for windmove-do-window-select.

But both answers resemble your personal preferences.  Other users
might disagree.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 06 Nov 2018 08:49:01 GMT) Full text and rfc822 format available.

Message #191 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 06 Nov 2018 09:48:18 +0100
>> Looks very good now.  This one
>>
>>> +;;;###autoload
>>> +(defun windmove-display-default-keybindings (&optional modifiers)
>>
>> should be wrapped in a 'defcustom' IMHO.
>
> This is a copy of the existing windmove-default-keybindings
> that has no defcustom.

IME the windmove user community is quite small.  Don't we expect
directional buffer display to attract more users than that?  Per se
S-M-<right> C-x 4 C-o is a pain to type.  So we could provide
attractive key bindings because windmove is pretty independent in this
regard.  And we should advertise them in the user manual.

>> And while I think that the prompt-like
>>
>> (message "[display-%s]" dir)
>>
>> is a good idea, it might fire back when the selected frame does not
>> have an echo area.  So I think it should be made customizable too.
>
> What bad will happen when the selected frame has no echo area?

I can't give you a good answer because I hardly ever work with
minibuffer-less frames.  But I could imagine that the message would
cause the respective echo-area frame to pop up even if the subsequent
step (namely that of finding out which buffer should get displayed)
does not involve the minibuffer because the buffer is already known
from the context (the line of the dired buffer where a file to be
displayed is listed, the file name around the position of point in a
grep buffer).

>> IMHO we should provide l, r, u/t, d/b directional keybindings as well.
>
> Maybe then h/j/k/l or b/f/n/p?

I intended l(eft), r(ight), u(p)/t(op) and d(own)/b(ottom).  What did
you intend?

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 06 Nov 2018 22:30:02 GMT) Full text and rfc822 format available.

Message #194 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Wed, 07 Nov 2018 00:22:29 +0200
> IME the windmove user community is quite small.  Don't we expect
> directional buffer display to attract more users than that?  Per se
> S-M-<right> C-x 4 C-o is a pain to type.  So we could provide
> attractive key bindings because windmove is pretty independent in this
> regard.  And we should advertise them in the user manual.

What key bindings are more attractive in your opinion?

>>> IMHO we should provide l, r, u/t, d/b directional keybindings as well.
>>
>> Maybe then h/j/k/l or b/f/n/p?
>
> I intended l(eft), r(ight), u(p)/t(op) and d(own)/b(ottom).  What did
> you intend?

h/j/k/l was a joke, but I really intended more Emacsy b/f/n/p as
a reference to navigation keys C-b/C-f/C-n/C-p.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 07 Nov 2018 09:25:02 GMT) Full text and rfc822 format available.

Message #197 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Wed, 07 Nov 2018 10:23:52 +0100
> What key bindings are more attractive in your opinion?

What I meant here is that if a user has typed a (customizable
directional) prefix like S-M-<right> the next key should already
supply all that's needed for the most common usages of the prefix.

Note that in its current form windmove.el is practically not needed
any more - most of its job is now done by 'window-in-direction'.  All
that remains in practice are its keybindings.  This gives us broad
opportunities to provide bindings for moving to a window in a certain
direction or create a window in that direction if, for example, no
window in that direction exists.  A new window could be made adjacent
to the selected window, full-width or full-height adjacent to a border
of the selected frame, on another frame in the indicated direction, in
a side or atomic window, on a child frame ...

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 07 Nov 2018 22:00:02 GMT) Full text and rfc822 format available.

Message #200 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Wed, 07 Nov 2018 23:44:27 +0200
>>> IME the windmove user community is quite small.  Don't we expect
>>> directional buffer display to attract more users than that?  Per se
>>> S-M-<right> C-x 4 C-o is a pain to type.  So we could provide
>>> attractive key bindings because windmove is pretty independent in this
>>> regard.  And we should advertise them in the user manual.
>>
>> What key bindings are more attractive in your opinion?
>
> What I meant here is that if a user has typed a (customizable
> directional) prefix like S-M-<right> the next key should already
> supply all that's needed for the most common usages of the prefix.

I see now how this relates to your example above ‘S-M-<right> C-x 4 C-o’.
And I agree that it's really a pain to type such long key sequences as
‘S-M-<right> C-x 4 .’

Shouldn't xref support a shorter and easier to type key sequence
‘S-M-<right> M-.’ with the following patch:

diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 6b1421a6f7..6aab174bcf 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -425,7 +425,7 @@ xref--pop-to-location
                    (xref-location-marker (xref-item-location item))))
          (buf (marker-buffer marker)))
     (cl-ecase action
-      ((nil)  (switch-to-buffer buf))
+      ((nil)  (pop-to-buffer-same-window buf))
       (window (pop-to-buffer buf t))
       (frame  (let ((pop-up-frames t)) (pop-to-buffer buf t))))
     (xref--goto-char marker))

> Note that in its current form windmove.el is practically not needed
> any more - most of its job is now done by 'window-in-direction'.  All
> that remains in practice are its keybindings.

Then maybe all unused code should be removed including
windmove-other-window-loc, windmove-reference-loc,
windmove-wrap-loc-for-movement, windmove-constrain-loc-for-movement,
etc.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 08 Nov 2018 08:54:02 GMT) Full text and rfc822 format available.

Message #203 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Thu, 08 Nov 2018 09:52:55 +0100
> Shouldn't xref support a shorter and easier to type key sequence
> ‘S-M-<right> M-.’ with the following patch:
>
> diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
> index 6b1421a6f7..6aab174bcf 100644
> --- a/lisp/progmodes/xref.el
> +++ b/lisp/progmodes/xref.el
> @@ -425,7 +425,7 @@ xref--pop-to-location
>                      (xref-location-marker (xref-item-location item))))
>            (buf (marker-buffer marker)))
>       (cl-ecase action
> -      ((nil)  (switch-to-buffer buf))
> +      ((nil)  (pop-to-buffer-same-window buf))
>         (window (pop-to-buffer buf t))
>         (frame  (let ((pop-up-frames t)) (pop-to-buffer buf t))))
>       (xref--goto-char marker))

I think so.  In particular because 'xref--goto-char' does not cohabit
well with 'switch-to-buffer-preserve-window-point' in the first place.
Dmitry should consent, though.

> Then maybe all unused code should be removed including
> windmove-other-window-loc, windmove-reference-loc,
> windmove-wrap-loc-for-movement, windmove-constrain-loc-for-movement,
> etc.

Citing from a discussion with Dmitry:

  > I thought you might go ahead and just port windmove to use
  > `window-in-direction'.

  windmove has an extra ARG to distinguish the upper left corner of a
  window and its position of point as reference points.  I can't easily
  dismiss that.

I'm not sure whether it's still relevant but if so we'd have to include
it in 'window-in-direction'.

martin





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 08 Nov 2018 21:43:02 GMT) Full text and rfc822 format available.

Message #206 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org, Dmitry Gutov <dgutov <at> yandex.ru>
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Thu, 08 Nov 2018 23:38:08 +0200
>> Shouldn't xref support a shorter and easier to type key sequence
>> ‘S-M-<right> M-.’ with the following patch:
>>
>> diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
>> index 6b1421a6f7..6aab174bcf 100644
>> --- a/lisp/progmodes/xref.el
>> +++ b/lisp/progmodes/xref.el
>> @@ -425,7 +425,7 @@ xref--pop-to-location
>>                      (xref-location-marker (xref-item-location item))))
>>            (buf (marker-buffer marker)))
>>       (cl-ecase action
>> -      ((nil)  (switch-to-buffer buf))
>> +      ((nil)  (pop-to-buffer-same-window buf))
>>         (window (pop-to-buffer buf t))
>>         (frame  (let ((pop-up-frames t)) (pop-to-buffer buf t))))
>>       (xref--goto-char marker))
>
> I think so.  In particular because 'xref--goto-char' does not cohabit
> well with 'switch-to-buffer-preserve-window-point' in the first place.
> Dmitry should consent, though.

Dmitry, do you agree this is a change for the better?

>> Then maybe all unused code should be removed including
>> windmove-other-window-loc, windmove-reference-loc,
>> windmove-wrap-loc-for-movement, windmove-constrain-loc-for-movement,
>> etc.
>
> Citing from a discussion with Dmitry:
>
>   > I thought you might go ahead and just port windmove to use
>   > `window-in-direction'.
>
>   windmove has an extra ARG to distinguish the upper left corner of a
>   window and its position of point as reference points.  I can't easily
>   dismiss that.
>
> I'm not sure whether it's still relevant but if so we'd have to include
> it in 'window-in-direction'.

I see that an extra ARG when ‘C-u’ is not interpreted as a positive arg,
and ‘M--’ is not interpreted as a negative arg.  So I propose to support
these prefix keys as well:

diff --git a/lisp/windmove.el b/lisp/windmove.el
index 598e495c7a..ea4506049b 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -512,7 +512,7 @@ windmove-left
 If no window is at the desired location, an error is signaled
 unless `windmove-create-window' is non-nil that creates a new window."
   (interactive "P")
-  (windmove-do-window-select 'left arg))
+  (windmove-do-window-select 'left (and arg (prefix-numeric-value arg))))
 
 ;;;###autoload
 (defun windmove-up (&optional arg)
@@ -524,7 +524,7 @@ windmove-up
 If no window is at the desired location, an error is signaled
 unless `windmove-create-window' is non-nil that creates a new window."
   (interactive "P")
-  (windmove-do-window-select 'up arg))
+  (windmove-do-window-select 'up (and arg (prefix-numeric-value arg))))
 
 ;;;###autoload
 (defun windmove-right (&optional arg)
@@ -536,7 +536,7 @@ windmove-right
 If no window is at the desired location, an error is signaled
 unless `windmove-create-window' is non-nil that creates a new window."
   (interactive "P")
-  (windmove-do-window-select 'right arg))
+  (windmove-do-window-select 'right (and arg (prefix-numeric-value arg))))
 
 ;;;###autoload
 (defun windmove-down (&optional arg)
@@ -548,7 +548,7 @@ windmove-down
 If no window is at the desired location, an error is signaled
 unless `windmove-create-window' is non-nil that creates a new window."
   (interactive "P")
-  (windmove-do-window-select 'down arg))
+  (windmove-do-window-select 'down (and arg (prefix-numeric-value arg))))
 
 
 ;;; set up keybindings





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 08 Nov 2018 21:58:01 GMT) Full text and rfc822 format available.

Message #209 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Thu, 08 Nov 2018 23:53:23 +0200
In bug#33258 I tried to use inhibit-select-window in
display-buffer-overriding-action, but it's better just to use
a prefix arg to determine whether the window should remain selected,
e.g. ‘C-u S-M-up’ means no-select, or ‘M-- S-M-left’ means no-select
and use the bottom egde, etc.

The only problem is that I can't decide what window to use for
window-in-direction and split-window in display-buffer-overriding-action:
an original window that was selected at the moment of ‘S-M-up’ invocation,
or a selected window that is current at the moment when
display-buffer-overriding-action is applied?  Please see
the questions in the comments of this patch:

diff --git a/lisp/windmove.el b/lisp/windmove.el
index 598e495c7a..ea4506049b 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -1,4 +1,4 @@
-;;; windmove.el --- directional window-selection routines
+;;; windmove.el --- directional window-selection routines  -*- lexical-binding:t -*-
 ;;
 ;; Copyright (C) 1998-2018 Free Software Foundation, Inc.
 ;;
@@ -571,6 +571,104 @@ windmove-default-keybindings
   (global-set-key (vector (append modifiers '(up)))    'windmove-up)
   (global-set-key (vector (append modifiers '(down)))  'windmove-down))
 
+;;; Directional window display
+
+(defun windmove-display-in-direction (dir &optional arg)
+  "Display the next buffer in the window at direction DIR.
+Create a new window if there is no window in that direction.
+If prefix ARG is `C-u' or `M--', restore the previously selected window.
+With no prefix ARG, or with prefix ARG equal to zero, a displayed window is
+relative to the position of point in the selected window; otherwise it is
+relative to the first edge (for positive ARG or `C-u') or the last edge
+(for negative ARG or `M--') of the selected window."
+  (interactive)
+  (let* ((command this-command)
+         (action display-buffer-overriding-action)
+         (minibuffer-depth (minibuffer-depth))
+         (selected-window (selected-window))
+         (restore-window (or (consp arg) (eq arg '-)))
+         (clearfun (make-symbol "clear-display-buffer-overriding-action"))
+         (exitfun
+          (lambda ()
+            (setq display-buffer-overriding-action action)
+            (when (and restore-window (window-live-p selected-window))
+              (select-window selected-window))
+            (remove-hook 'post-command-hook clearfun))))
+    (fset clearfun
+          (lambda ()
+            (unless (or
+		     ;; Remove the hook immediately
+		     ;; after exiting the minibuffer.
+		     (> (minibuffer-depth) minibuffer-depth)
+		     ;; But don't remove immediately after
+		     ;; adding the hook by the same command below.
+		     (eq this-command command))
+              (funcall exitfun))))
+    (add-hook 'post-command-hook clearfun)
+    (push (lambda (buffer alist)
+	    (unless (> (minibuffer-depth) minibuffer-depth)
+	      (let ((window (if (eq dir 'same-window)
+			        (selected-window) ;; or maybe `selected-window'?
+                              (window-in-direction
+                               dir selected-window nil ;; or `nil' instead of `selected-window'?
+                               (and arg (prefix-numeric-value arg))
+                               windmove-wrap-around)))
+                    (type 'reuse))
+                (unless window
+		  ;; maybe use `selected-window' in WINDOW arg of split-window?
+                  (setq window (split-window nil nil dir) type 'window))
+		(window--display-buffer buffer window type alist))))
+          display-buffer-overriding-action)
+    (message "[display-%s]" dir)))
+
+;;;###autoload
+(defun windmove-display-left (&optional arg)
+  "Display the next buffer in window to the left of the current one.
+With a prefix argument, restore the previously selected window."
+  (interactive "P")
+  (windmove-display-in-direction 'left arg))
+
+;;;###autoload
+(defun windmove-display-up (&optional arg)
+  "Display the next buffer in window above the current one.
+With a prefix argument, restore the previously selected window."
+  (interactive "P")
+  (windmove-display-in-direction 'up arg))
+
+;;;###autoload
+(defun windmove-display-right (&optional arg)
+  "Display the next buffer in window to the right of the current one.
+With a prefix argument, restore the previously selected window."
+  (interactive "P")
+  (windmove-display-in-direction 'right arg))
+
+;;;###autoload
+(defun windmove-display-down (&optional arg)
+  "Display the next buffer in window below the current one.
+With a prefix argument, restore the previously selected window."
+  (interactive "P")
+  (windmove-display-in-direction 'down arg))
+
+;;;###autoload
+(defun windmove-display-same-window (&optional arg)
+  "Display the next buffer in the same window."
+  (interactive "P")
+  (windmove-display-in-direction 'same-window arg))
+
+;;;###autoload
+(defun windmove-display-default-keybindings (&optional modifiers)
+  "Set up keybindings for directional display.
+Keybindings are of the form MODIFIERS-{left,right,up,down},
+where MODIFIERS is either a list of modifiers or a single modifier.
+Default value of MODIFIERS is `shift-meta'."
+  (interactive)
+  (unless modifiers (setq modifiers '(shift meta)))
+  (unless (listp modifiers) (setq modifiers (list modifiers)))
+  (global-set-key (vector (append modifiers '(left)))  'windmove-display-left)
+  (global-set-key (vector (append modifiers '(right))) 'windmove-display-right)
+  (global-set-key (vector (append modifiers '(up)))    'windmove-display-up)
+  (global-set-key (vector (append modifiers '(down)))  'windmove-display-down)
+  (global-set-key (vector (append modifiers '(?0)))    'windmove-display-same-window))
 
 (provide 'windmove)
 




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Fri, 09 Nov 2018 09:10:01 GMT) Full text and rfc822 format available.

Message #212 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org, Dmitry Gutov <dgutov <at> yandex.ru>
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 09 Nov 2018 10:08:59 +0100
>   If no window is at the desired location, an error is signaled
>   unless `windmove-create-window' is non-nil that creates a new window."

Maybe we should write "unless `windmove-create-window' is non-nil and
a new window is created." here.  Also, in 'windmove-do-window-select'
I'd write "If `windmove-create-window' is non-nil, try to create a new
window in direction DIR instead." in the doc-string.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Fri, 09 Nov 2018 09:14:01 GMT) Full text and rfc822 format available.

Message #215 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 09 Nov 2018 10:13:05 +0100
> The only problem is that I can't decide what window to use for
> window-in-direction and split-window in display-buffer-overriding-action:
> an original window that was selected at the moment of ‘S-M-up’ invocation,
> or a selected window that is current at the moment when
> display-buffer-overriding-action is applied?  Please see
> the questions in the comments of this patch:

Shouldn't (selected-window) be actually (minibuffer-selected-window)
in these cases anyway?  Otherwise, we probably should invent two
scenarios where either of the above would be preferable so we can make
a decision.

> +  "Display the next buffer in the window at direction DIR.
> +Create a new window if there is no window in that direction.
> +If prefix ARG is `C-u' or `M--', restore the previously selected window.
> +With no prefix ARG, or with prefix ARG equal to zero, a displayed window is
> +relative to the position of point in the selected window; otherwise it is
> +relative to the first edge (for positive ARG or `C-u') or the last edge
> +(for negative ARG or `M--') of the selected window."

What does "otherwise" stand for here?  (I'm afraid your prefix
arguments are slowly getting over my head.)

martin





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sat, 10 Nov 2018 22:00:02 GMT) Full text and rfc822 format available.

Message #218 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org, Dmitry Gutov <dgutov <at> yandex.ru>
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sat, 10 Nov 2018 23:25:22 +0200
>>   If no window is at the desired location, an error is signaled
>>   unless `windmove-create-window' is non-nil that creates a new window."
>
> Maybe we should write "unless `windmove-create-window' is non-nil and
> a new window is created." here.  Also, in 'windmove-do-window-select'
> I'd write "If `windmove-create-window' is non-nil, try to create a new
> window in direction DIR instead." in the doc-string.

OK, I'll fix this in the next commit.

BTW, please note a nice feature that when `windmove-create-window'
is non-nil, then the Meta-modifier is not necessary, i.e.
these key sequences should provide the equivalent result:

M-S-right M-.
  S-right M-.

because S-right will create a new window in that direction
before M-. is invoked in that manually created window
(when S-right is bound to windmove-right, and M-S-right
to windmove-display-right).




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sat, 10 Nov 2018 22:00:03 GMT) Full text and rfc822 format available.

Message #221 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sat, 10 Nov 2018 23:37:22 +0200
> Shouldn't (selected-window) be actually (minibuffer-selected-window)
> in these cases anyway?  Otherwise, we probably should invent two
> scenarios where either of the above would be preferable so we can make
> a decision.

Probably you meant (or (minibuffer-selected-window) (selected-window))

>> +  "Display the next buffer in the window at direction DIR.
>> +Create a new window if there is no window in that direction.
>> +If prefix ARG is `C-u' or `M--', restore the previously selected window.
>> +With no prefix ARG, or with prefix ARG equal to zero, a displayed window is
>> +relative to the position of point in the selected window; otherwise it is
>> +relative to the first edge (for positive ARG or `C-u') or the last edge
>> +(for negative ARG or `M--') of the selected window."
>
> What does "otherwise" stand for here?  (I'm afraid your prefix
> arguments are slowly getting over my head.)

This summarizes the prefix keys where 'default' is the default
window selection behavior, and 'window-noselect' restores a previously
selected window:

                                    default     window-noselect
relative to the position of point   no prefix   M-0
relative to the first edge          M-1         C-u
relative to the last edge           M-- 1       M--

But maybe also another choice 'window-select' should be added to
force window selection?  I mean that some commands don't select
the displayed window by default, e.g. help commands like
'C-h e', 'C-h f', 'C-h v', 'C-h k' after their invocation
don't select the window with the *Help* buffer.

Or maybe a prefix key should invert the default behavior,
e.g. 'S-M-right C-x v =' by default selects the displayed window,
so ‘C-u S-M-right C-x v =’ will not select the window.
'S-M-right C-h e' by default doesn't select the window,
so ‘C-u S-M-right C-h e’ will select the window.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 11 Nov 2018 08:53:02 GMT) Full text and rfc822 format available.

Message #224 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 11 Nov 2018 09:51:57 +0100
>> Shouldn't (selected-window) be actually (minibuffer-selected-window)
>> in these cases anyway?  Otherwise, we probably should invent two
>> scenarios where either of the above would be preferable so we can make
>> a decision.
>
> Probably you meant (or (minibuffer-selected-window) (selected-window))

Something like that, yes.

> This summarizes the prefix keys where 'default' is the default
> window selection behavior, and 'window-noselect' restores a previously
> selected window:
>
>                                      default     window-noselect
> relative to the position of point   no prefix   M-0
> relative to the first edge          M-1         C-u
> relative to the last edge           M-- 1       M--

I would drop that edge thingy, interactively.  I'm quite convinced
that nobody would ever use it.

IMHO this "relative" code is there for historical reasons - the author
wrote the simpler edges versions first, wrote the point version later
and didn't want to drop the edges versions then (maybe also because he
wasn't sure whether the point version would always work).  What I
doubt is that a user would ever make the relativity choice
interactively.  Rather people would be used to one or the other.

> But maybe also another choice 'window-select' should be added to
> force window selection?  I mean that some commands don't select
> the displayed window by default, e.g. help commands like
> 'C-h e', 'C-h f', 'C-h v', 'C-h k' after their invocation
> don't select the window with the *Help* buffer.

With 'help-window-select' non-nil they should always select the help
window.

> Or maybe a prefix key should invert the default behavior,
> e.g. 'S-M-right C-x v =' by default selects the displayed window,
> so ‘C-u S-M-right C-x v =’ will not select the window.
> 'S-M-right C-h e' by default doesn't select the window,
> so ‘C-u S-M-right C-h e’ will select the window.

That would confuse the hell out of me.  I'm not sure how you or others
feel, but personally I would prefer a fixed two layer choice like:

(1) The select/no-select choice always bound to one and the same
prefix key _regardless_ of the default behavior of the function (for
the buffer at hand), and

(2) in addition to a window relative to the selected window (above, on
the right, ... a new one always made by splitting the selected window)
optionally allow a window relative to the selected frame (on the top
full-width, on the right full-height, ... a new one always made by
splitting the frame's root window) bound to another prefix key.

Then (2) could be generalized via a global option to use/make a new
(child) frame in the indicated direction or whatever people want.

martin





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 13 Nov 2018 00:02:01 GMT) Full text and rfc822 format available.

Message #227 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 13 Nov 2018 01:24:53 +0200
>> This summarizes the prefix keys where 'default' is the default
>> window selection behavior, and 'window-noselect' restores a previously
>> selected window:
>>
>>                                      default     window-noselect
>> relative to the position of point   no prefix   M-0
>> relative to the first edge          M-1         C-u
>> relative to the last edge           M-- 1       M--
>
> I would drop that edge thingy, interactively.  I'm quite convinced
> that nobody would ever use it.
>
> IMHO this "relative" code is there for historical reasons - the author
> wrote the simpler edges versions first, wrote the point version later
> and didn't want to drop the edges versions then (maybe also because he
> wasn't sure whether the point version would always work).  What I
> doubt is that a user would ever make the relativity choice
> interactively.  Rather people would be used to one or the other.

I agree, it's too complicated, I never used edges in windmove-do-window-select.

>> But maybe also another choice 'window-select' should be added to
>> force window selection?  I mean that some commands don't select
>> the displayed window by default, e.g. help commands like
>> 'C-h e', 'C-h f', 'C-h v', 'C-h k' after their invocation
>> don't select the window with the *Help* buffer.
>
> With 'help-window-select' non-nil they should always select the help
> window.

This means that every package should provide own customization
for the select/no-select choice for its windows, instead of
a general solution like inhibit-window-select that I tried to do.

>> Or maybe a prefix key should invert the default behavior,
>> e.g. 'S-M-right C-x v =' by default selects the displayed window,
>> so ‘C-u S-M-right C-x v =’ will not select the window.
>> 'S-M-right C-h e' by default doesn't select the window,
>> so ‘C-u S-M-right C-h e’ will select the window.
>
> That would confuse the hell out of me.  I'm not sure how you or others
> feel, but personally I would prefer a fixed two layer choice like:
>
> (1) The select/no-select choice always bound to one and the same
> prefix key _regardless_ of the default behavior of the function (for
> the buffer at hand), and

This is implemented in a new version:

(defun windmove-display-in-direction (dir &optional arg)
  "Display the next buffer in the window at direction DIR.
Create a new window if there is no window in that direction.
Without a prefix arg, select the window with a displayed buffer.
If prefix ARG is `C-u', reselect a previously selected window."
  (interactive)
  (let* ((no-select (consp arg))
         (old-window (or (minibuffer-selected-window) (selected-window)))
         (new-window)
         (minibuffer-depth (minibuffer-depth))
         (action display-buffer-overriding-action)
         (command this-command)
         (clearfun (make-symbol "clear-display-buffer-overriding-action"))
         (exitfun
          (lambda ()
            (setq display-buffer-overriding-action action)
            (when (window-live-p (if no-select old-window new-window))
              (select-window (if no-select old-window new-window)))
            (remove-hook 'post-command-hook clearfun))))
    (fset clearfun
          (lambda ()
            (unless (or
		     ;; Remove the hook immediately
		     ;; after exiting the minibuffer.
		     (> (minibuffer-depth) minibuffer-depth)
		     ;; But don't remove immediately after
		     ;; adding the hook by the same command below.
		     (eq this-command command))
              (funcall exitfun))))
    (add-hook 'post-command-hook clearfun)
    (push (lambda (buffer alist)
	    (unless (> (minibuffer-depth) minibuffer-depth)
	      (let ((window (if (eq dir 'same-window)
			        (selected-window)
                              (window-in-direction
                               dir nil nil
                               (and arg (prefix-numeric-value arg))
                               windmove-wrap-around)))
                    (type 'reuse))
                (unless window
                  (setq window (split-window nil nil dir) type 'window))
		(setq new-window (window--display-buffer buffer window type alist)))))
          display-buffer-overriding-action)
    (message "[display-%s]" dir)))

> (2) in addition to a window relative to the selected window (above, on
> the right, ... a new one always made by splitting the selected window)
> optionally allow a window relative to the selected frame (on the top
> full-width, on the right full-height, ... a new one always made by
> splitting the frame's root window) bound to another prefix key.
>
> Then (2) could be generalized via a global option to use/make a new
> (child) frame in the indicated direction or whatever people want.

But does windmove support frames in the first place?
Can you use e.g. S-left to select a frame on the left?
Does window-in-direction currently return frames?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 13 Nov 2018 09:10:02 GMT) Full text and rfc822 format available.

Message #230 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 13 Nov 2018 10:08:55 +0100
>> With 'help-window-select' non-nil they should always select the help
>> window.
>
> This means that every package should provide own customization
> for the select/no-select choice for its windows, instead of
> a general solution like inhibit-window-select that I tried to do.

With help windows it was easy to do that because they never get
selected by default.

>> (1) The select/no-select choice always bound to one and the same
>> prefix key _regardless_ of the default behavior of the function (for
>> the buffer at hand), and
>
> This is implemented in a new version:
>
> (defun windmove-display-in-direction (dir &optional arg)
>    "Display the next buffer in the window at direction DIR.
> Create a new window if there is no window in that direction.
> Without a prefix arg, select the window with a displayed buffer.
> If prefix ARG is `C-u', reselect a previously selected window."

I'd invert these: The "-display-" infix implies that the buffer is
displayed and not popped to.  So with a prefix argumet I would select
the window in that direction and without it I'd leave the old window
selected.

>> Then (2) could be generalized via a global option to use/make a new
>> (child) frame in the indicated direction or whatever people want.
>
> But does windmove support frames in the first place?

No.

> Can you use e.g. S-left to select a frame on the left?
> Does window-in-direction currently return frames?

No, and it's a bit tricky to do that.  A window that is not on the
right of a frame has always exactly one window directly at its right
regardless of the position of its buffer's (window-)point.  The same
doesn't hold for a window that has a frame on the right.  If there are
two or more overlapping frames, we'd probably choose a visible one
with the highest z-order value.  If there is no frame directly on the
right of point, we'd have to choose the one geometrically nearest to
that position.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 13 Nov 2018 23:50:03 GMT) Full text and rfc822 format available.

Message #233 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Wed, 14 Nov 2018 01:20:53 +0200
>>> (1) The select/no-select choice always bound to one and the same
>>> prefix key _regardless_ of the default behavior of the function (for
>>> the buffer at hand), and
>>
>> This is implemented in a new version:
>>
>> (defun windmove-display-in-direction (dir &optional arg)
>>    "Display the next buffer in the window at direction DIR.
>> Create a new window if there is no window in that direction.
>> Without a prefix arg, select the window with a displayed buffer.
>> If prefix ARG is `C-u', reselect a previously selected window."
>
> I'd invert these: The "-display-" infix implies that the buffer is
> displayed and not popped to.

Then easier just to rename it to windmove-pop-in-direction
because most commands use pop-to-buffer, so this should be
the default.

> So with a prefix argumet I would select the window in that direction
> and without it I'd leave the old window selected.

If you prefer the inverse, then a new option could be added with a name
windmove-display-pop-up.  And ‘C-u C-u’ will invert its value like for
‘diff-jump-to-old-file’.

>> Can you use e.g. S-left to select a frame on the left?
>> Does window-in-direction currently return frames?
>
> No, and it's a bit tricky to do that.  A window that is not on the
> right of a frame has always exactly one window directly at its right
> regardless of the position of its buffer's (window-)point.  The same
> doesn't hold for a window that has a frame on the right.  If there are
> two or more overlapping frames, we'd probably choose a visible one
> with the highest z-order value.  If there is no frame directly on the
> right of point, we'd have to choose the one geometrically nearest to
> that position.

Expect more fun with wrapping head around frame-based windmove-wrap-around :)

But currently I'm more concerned about inability to use switch-to-buffer,
i.e. trying to display a buffer in another window with ‘S-M-down C-x b RET’
doesn't work.  I tried to temporarily set dedicated-p to an old window,
but switch-to-buffer removes its dedicatedness.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 14 Nov 2018 08:34:02 GMT) Full text and rfc822 format available.

Message #236 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Wed, 14 Nov 2018 09:33:15 +0100
>> I'd invert these: The "-display-" infix implies that the buffer is
>> displayed and not popped to.
>
> Then easier just to rename it to windmove-pop-in-direction
> because most commands use pop-to-buffer, so this should be
> the default.

That would be much better.

> But currently I'm more concerned about inability to use switch-to-buffer,
> i.e. trying to display a buffer in another window with ‘S-M-down C-x b RET’
> doesn't work.

You mean wherever we can't use 'pop-to-buffer-same-window' instead?
'switch-to-buffer' is different.  Reconciling 'force-same-window' and
'switch-to-buffer-in-dedicated-window' looks rather painful to me.

> I tried to temporarily set dedicated-p to an old window,
> but switch-to-buffer removes its dedicatedness.

What did you try exactly?  Naively spoken, I suppose you would have
bound the dedicated flag of the selected window to 't' to make
sure it can't get used and 'switch-to-buffer-in-dedicated-window' to
'pop' to avoid a user error.

martin





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 15 Nov 2018 00:32:01 GMT) Full text and rfc822 format available.

Message #239 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Thu, 15 Nov 2018 02:15:37 +0200
>>> I'd invert these: The "-display-" infix implies that the buffer is
>>> displayed and not popped to.
>>
>> Then easier just to rename it to windmove-pop-in-direction
>> because most commands use pop-to-buffer, so this should be
>> the default.
>
> That would be much better.

The name 'windmove-display-in-direction' is more intuitive and still
correct because it displays.  Select/no-select is a minor detail
that depends on the prefix arg and a variable that I propose to name
windmove-display-select.

>> But currently I'm more concerned about inability to use switch-to-buffer,
>> i.e. trying to display a buffer in another window with ‘S-M-down C-x b RET’
>> doesn't work.
>
> You mean wherever we can't use 'pop-to-buffer-same-window' instead?

Yes, and 'switch-to-buffer' should not use 'pop-to-buffer-same-window'.

> 'switch-to-buffer' is different.  Reconciling 'force-same-window' and
> 'switch-to-buffer-in-dedicated-window' looks rather painful to me.
>
>> I tried to temporarily set dedicated-p to an old window,
>> but switch-to-buffer removes its dedicatedness.
>
> What did you try exactly?  Naively spoken, I suppose you would have
> bound the dedicated flag of the selected window to 't' to make
> sure it can't get used and 'switch-to-buffer-in-dedicated-window' to
> 'pop' to avoid a user error.

I tried to set switch-to-buffer-in-dedicated-window to t instead of 'pop'.
But I see now it's not worth the trouble to handle dedicatedness in
'windmove-display-in-direction' because it's not a general solution.

Maybe simpler to rebind 'C-x b' from 'switch-to-buffer' to the command
'pop-to-buffer'?  Is 'pop-to-buffer' equivalent to 'switch-to-buffer'
as a command with only difference in select/no-select behavior?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 15 Nov 2018 09:14:02 GMT) Full text and rfc822 format available.

Message #242 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Thu, 15 Nov 2018 10:13:10 +0100
>>>> I'd invert these: The "-display-" infix implies that the buffer is
>>>> displayed and not popped to.
>>>
>>> Then easier just to rename it to windmove-pop-in-direction
>>> because most commands use pop-to-buffer, so this should be
>>> the default.
>>
>> That would be much better.
>
> The name 'windmove-display-in-direction' is more intuitive and still
> correct because it displays.  Select/no-select is a minor detail
> that depends on the prefix arg and a variable that I propose to name
> windmove-display-select.

OK.  We can easily add the "other" one later if there's a need.

>>> But currently I'm more concerned about inability to use switch-to-buffer,
>>> i.e. trying to display a buffer in another window with ‘S-M-down C-x b RET’
>>> doesn't work.
>>
>> You mean wherever we can't use 'pop-to-buffer-same-window' instead?
>
> Yes, and 'switch-to-buffer' should not use 'pop-to-buffer-same-window'.

You mean uses of 'switch-to-buffer' in code that we cannot (or are too
lazy to) replace with 'pop-to-buffer-same-window'.  Right?  Because
ideally code should not use 'switch-to-buffer' - we had quite a number
of reports that the point restoring mechanism conflicted with the
purpose to show a preselected buffer position in the selected window.

> I tried to set switch-to-buffer-in-dedicated-window to t instead of 'pop'.

I miss you here: Above you say that you want to display the buffer in
another window.  But setting 'switch-to-buffer-in-dedicated-window' to
t is useful only when you insisit on using the selected window.

> But I see now it's not worth the trouble to handle dedicatedness in
> 'windmove-display-in-direction' because it's not a general solution.

Windows have been often made dedicated so they get auto-deleted as
soon as their buffer gets buried or killed.  This use-case should now
be handled by the 'quit-restore' parameter.  I have no idea whether
windows are made dedicated for any other reason.  Do you?

In either case we can easily add an action alist entry telling
'display-buffer' whether to reuse an arbitrary dedicated window.

> Maybe simpler to rebind 'C-x b' from 'switch-to-buffer' to the command
> 'pop-to-buffer'?  Is 'pop-to-buffer' equivalent to 'switch-to-buffer'
> as a command with only difference in select/no-select behavior?

'pop-to-buffer' does not try to restore the previous position of point
in the chosen window.

martin





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 15 Nov 2018 23:08:02 GMT) Full text and rfc822 format available.

Message #245 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 16 Nov 2018 00:59:59 +0200
>>>> But currently I'm more concerned about inability to use switch-to-buffer,
>>>> i.e. trying to display a buffer in another window with ‘S-M-down C-x b RET’
>>>> doesn't work.
>>>
>>> You mean wherever we can't use 'pop-to-buffer-same-window' instead?
>>
>> Yes, and 'switch-to-buffer' should not use 'pop-to-buffer-same-window'.
>
> You mean uses of 'switch-to-buffer' in code that we cannot (or are too
> lazy to) replace with 'pop-to-buffer-same-window'.  Right?  Because
> ideally code should not use 'switch-to-buffer' - we had quite a number
> of reports that the point restoring mechanism conflicted with the
> purpose to show a preselected buffer position in the selected window.

Whereas I meant mostly switch-to-buffer as a command bound to 'C-x b',
non-interactive calls of 'switch-to-buffer' have the same problem, and
maybe some of them could be replaced with 'pop-to-buffer-same-window'
without side effects.  One example is 'C-h C-n' (view-emacs-news) that
uses switch-to-buffer, and can't be forced into another window.

I solved this general problem for myself with such advice:

(advice-add 'switch-to-buffer :around
            (lambda (orig-fun &rest args)
              (let ((buffer (apply orig-fun args))
                    (window (selected-window)))
                (switch-to-prev-buffer window)
                (pop-to-buffer-same-window buffer))))

Then 'S-M-right C-h C-n' shows it in the right window.

Do you think it's possible to add a corresponding customizable option
that would provide the same behavior?

>> I tried to set switch-to-buffer-in-dedicated-window to t instead of 'pop'.
>
> I miss you here: Above you say that you want to display the buffer in
> another window.  But setting 'switch-to-buffer-in-dedicated-window' to
> t is useful only when you insisit on using the selected window.

I tried t mistakenly.  I intended to try 'pop' that works ok.

>> But I see now it's not worth the trouble to handle dedicatedness in
>> 'windmove-display-in-direction' because it's not a general solution.
>
> Windows have been often made dedicated so they get auto-deleted as
> soon as their buffer gets buried or killed.  This use-case should now
> be handled by the 'quit-restore' parameter.  I have no idea whether
> windows are made dedicated for any other reason.  Do you?

Another reason would be to force pop-up from switch-buffer, but
it's not the right thing to do.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Fri, 16 Nov 2018 08:55:02 GMT) Full text and rfc822 format available.

Message #248 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 16 Nov 2018 09:53:57 +0100
> Whereas I meant mostly switch-to-buffer as a command bound to 'C-x b',
> non-interactive calls of 'switch-to-buffer' have the same problem, and
> maybe some of them could be replaced with 'pop-to-buffer-same-window'
> without side effects.  One example is 'C-h C-n' (view-emacs-news) that
> uses switch-to-buffer, and can't be forced into another window.
>
> I solved this general problem for myself with such advice:
>
> (advice-add 'switch-to-buffer :around
>              (lambda (orig-fun &rest args)
>                (let ((buffer (apply orig-fun args))
>                      (window (selected-window)))
>                  (switch-to-prev-buffer window)
>                  (pop-to-buffer-same-window buffer))))
>
> Then 'S-M-right C-h C-n' shows it in the right window.

I don't grok it yet.  What's the 'switch-to-prev-buffer' call for?

> Do you think it's possible to add a corresponding customizable option
> that would provide the same behavior?

I would have to understand the "behavior" first.  One approach would
be to move the user-error and 'switch-to-buffer-preserve-window-point'
handling into the interactive specification handling and for the rest
do what 'pop-to-buffer-same-window' does.

>> Windows have been often made dedicated so they get auto-deleted as
>> soon as their buffer gets buried or killed.  This use-case should now
>> be handled by the 'quit-restore' parameter.  I have no idea whether
>> windows are made dedicated for any other reason.  Do you?
>
> Another reason would be to force pop-up from switch-buffer, but
> it's not the right thing to do.

Something like "I never want to show another buffer in this window,
please remind me if I accidentally try to do that".

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sat, 17 Nov 2018 22:36:02 GMT) Full text and rfc822 format available.

Message #251 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 18 Nov 2018 00:18:17 +0200
>> Whereas I meant mostly switch-to-buffer as a command bound to 'C-x b',
>> non-interactive calls of 'switch-to-buffer' have the same problem, and
>> maybe some of them could be replaced with 'pop-to-buffer-same-window'
>> without side effects.  One example is 'C-h C-n' (view-emacs-news) that
>> uses switch-to-buffer, and can't be forced into another window.
>>
>> I solved this general problem for myself with such advice:
>>
>> (advice-add 'switch-to-buffer :around
>>              (lambda (orig-fun &rest args)
>>                (let ((buffer (apply orig-fun args))
>>                      (window (selected-window)))
>>                  (switch-to-prev-buffer window)
>>                  (pop-to-buffer-same-window buffer))))
>>
>> Then 'S-M-right C-h C-n' shows it in the right window.
>
> I don't grok it yet.  What's the 'switch-to-prev-buffer' call for?

switch-to-buffer switches the buffer in the selected window.
switch-to-prev-buffer undoes this, and displays the same buffer
in another window instead.

>> Do you think it's possible to add a corresponding customizable option
>> that would provide the same behavior?
>
> I would have to understand the "behavior" first.  One approach would
> be to move the user-error and 'switch-to-buffer-preserve-window-point'
> handling into the interactive specification handling and for the rest
> do what 'pop-to-buffer-same-window' does.

Or maybe to add a new option that will allow switch-to-buffer
to use pop-to-buffer-same-window.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 18 Nov 2018 09:25:02 GMT) Full text and rfc822 format available.

Message #254 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 18 Nov 2018 10:24:06 +0100
>>> I solved this general problem for myself with such advice:
>>>
>>> (advice-add 'switch-to-buffer :around
>>>               (lambda (orig-fun &rest args)
>>>                 (let ((buffer (apply orig-fun args))
>>>                       (window (selected-window)))
>>>                   (switch-to-prev-buffer window)
>>>                   (pop-to-buffer-same-window buffer))))
>>>
>>> Then 'S-M-right C-h C-n' shows it in the right window.
>>
>> I don't grok it yet.  What's the 'switch-to-prev-buffer' call for?
>
> switch-to-buffer switches the buffer in the selected window.
> switch-to-prev-buffer undoes this, and displays the same buffer
> in another window instead.

OK.  This is a very gross hack that relies on 'switch-to-prev-buffer'
switching back to the "right" buffer.  I can imagine now that you're
not very fond of having it skip certain buffers in the course of
action.

>> I would have to understand the "behavior" first.  One approach would
>> be to move the user-error and 'switch-to-buffer-preserve-window-point'
>> handling into the interactive specification handling and for the rest
>> do what 'pop-to-buffer-same-window' does.
>
> Or maybe to add a new option that will allow switch-to-buffer
> to use pop-to-buffer-same-window.

Allow or mandate?  Always?

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 18 Nov 2018 23:08:02 GMT) Full text and rfc822 format available.

Message #257 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 19 Nov 2018 00:52:52 +0200
>>> I would have to understand the "behavior" first.  One approach would
>>> be to move the user-error and 'switch-to-buffer-preserve-window-point'
>>> handling into the interactive specification handling and for the rest
>>> do what 'pop-to-buffer-same-window' does.
>>
>> Or maybe to add a new option that will allow switch-to-buffer
>> to use pop-to-buffer-same-window.
>
> Allow or mandate?  Always?

Like `switch-to-buffer-in-dedicated-window' has the option `pop',
another customizable variable could provide a similar non-default
option that will call pop-to-buffer-same-window from switch-to-buffer.

Or maybe simpler to create a new command e.g. switch-to-buffer-same-window
based on switch-to-buffer-other-window?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 19 Nov 2018 09:43:01 GMT) Full text and rfc822 format available.

Message #260 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 19 Nov 2018 10:42:36 +0100
> Like `switch-to-buffer-in-dedicated-window' has the option `pop',
> another customizable variable could provide a similar non-default
> option that will call pop-to-buffer-same-window from switch-to-buffer.

OK.  But would that option's value apply to C-x b as well?

> Or maybe simpler to create a new command e.g. switch-to-buffer-same-window
> based on switch-to-buffer-other-window?

You mean C-h k C-x b would tell me that

C-x b runs the command switch-to-buffer-same-window (found in
global-map), which is an interactive compiled Lisp function in
‘window.el’.

martin





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 19 Nov 2018 22:53:01 GMT) Full text and rfc822 format available.

Message #263 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 20 Nov 2018 00:39:04 +0200
>> Like `switch-to-buffer-in-dedicated-window' has the option `pop',
>> another customizable variable could provide a similar non-default
>> option that will call pop-to-buffer-same-window from switch-to-buffer.
>
> OK.  But would that option's value apply to C-x b as well?

This option is needed mostly for 'C-x b' to be able to switch to the buffer
in another window.  And also for other commands that non-interactively call
'switch-to-buffer', like 'C-h C-n'.

>> Or maybe simpler to create a new command e.g. switch-to-buffer-same-window
>> based on switch-to-buffer-other-window?
>
> You mean C-h k C-x b would tell me that
>
> C-x b runs the command switch-to-buffer-same-window (found in
> global-map), which is an interactive compiled Lisp function in
> ‘window.el’.

I see now that this solution doesn't help for commands that
non-interactively call 'switch-to-buffer', like 'C-h C-t'.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 20 Nov 2018 09:30:01 GMT) Full text and rfc822 format available.

Message #266 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 20 Nov 2018 10:28:52 +0100
>>> Like `switch-to-buffer-in-dedicated-window' has the option `pop',
>>> another customizable variable could provide a similar non-default
>>> option that will call pop-to-buffer-same-window from switch-to-buffer.
>>
>> OK.  But would that option's value apply to C-x b as well?
>
> This option is needed mostly for 'C-x b' to be able to switch to the buffer
> in another window.  And also for other commands that non-interactively call
> 'switch-to-buffer', like 'C-h C-n'.

But 'pop-to-buffer-same-window' doesn't have the
'switch-to-buffer-preserve-window-point' semantics.  How would you
want to integrate them?

>>> Or maybe simpler to create a new command e.g. switch-to-buffer-same-window
>>> based on switch-to-buffer-other-window?
>>
>> You mean C-h k C-x b would tell me that
>>
>> C-x b runs the command switch-to-buffer-same-window (found in
>> global-map), which is an interactive compiled Lisp function in
>> ‘window.el’.
>
> I see now that this solution doesn't help for commands that
> non-interactively call 'switch-to-buffer', like 'C-h C-t'.

So please propose a name for the option like say
'switch-to-buffer-pop-to-buffer' and tell me whether and how what we
execute then obeys 'switch-to-buffer-preserve-window-point'.

martin





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 21 Nov 2018 00:51:01 GMT) Full text and rfc822 format available.

Message #269 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Wed, 21 Nov 2018 02:12:52 +0200
> So please propose a name for the option like say
> 'switch-to-buffer-pop-to-buffer' and tell me whether and how what we
> execute then obeys 'switch-to-buffer-preserve-window-point'.

Maybe a shorter name 'switch-to-buffer-pop'?

> But 'pop-to-buffer-same-window' doesn't have the
> 'switch-to-buffer-preserve-window-point' semantics.  How would you
> want to integrate them?

Maybe just call 'pop-to-buffer-same-window' at the end of 'switch-to-buffer'
when a new option 'switch-to-buffer-pop' is non-nil?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 21 Nov 2018 08:20:01 GMT) Full text and rfc822 format available.

Message #272 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Wed, 21 Nov 2018 09:19:39 +0100
> Maybe just call 'pop-to-buffer-same-window' at the end of 'switch-to-buffer'
> when a new option 'switch-to-buffer-pop' is non-nil?

Then 'switch-to-buffer' will show the buffer in the selected window
and 'pop-to-buffer-same-window' will find it there.  Or what am I
missing?

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 21 Nov 2018 23:58:01 GMT) Full text and rfc822 format available.

Message #275 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Thu, 22 Nov 2018 01:35:00 +0200
>> 0. emacs -Q
>>
>> 1. C-h e
>>
>> 2. C-x o
>>
>> 3. C-x 2
>>
>> 4. C-x 0
>>
>> It's expected that point will remain where it was visually on the screen,
>> just will relocate to the window that takes place of the deleted window,
>> but point jumps to an unexpected place in the opposite part of the frame.
>
> What should Emacs do instead?

One possible solution is to implement directional window deletion.
The following patch allows using the prefix argument that will delete
the selected window and select the window at the given direction.

This makes possible this workflow:

0. emacs -Q -mm

1. eval: (windmove-delete-default-keybindings)

2. C-h e

3. C-x o

4. C-x 2

5. C-h i

6. C-u C-x S-down

and after deleting of the selected window, the cursor stays in the same place,
and doesn't jump to the opposite part of the frame.

diff --git a/lisp/windmove.el b/lisp/windmove.el
index 898f87e2db..9a7a2b80f2 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -678,6 +678,74 @@ windmove-display-default-keybindings
   (global-set-key (vector (append modifiers '(down)))  'windmove-display-down)
   (global-set-key (vector (append modifiers '(?0)))    'windmove-display-same-window))
 
+;;; Directional window deletion
+
+(defun windmove-delete-in-direction (dir &optional arg)
+  "Delete the window at direction DIR.
+If prefix ARG is `C-u', delete the selected window and
+select the window at direction DIR."
+  (let ((other-window (window-in-direction dir nil nil arg
+                                           windmove-wrap-around t)))
+    (cond ((null other-window)
+           (user-error "No window %s from selected window" dir))
+          ((and (window-minibuffer-p other-window)
+                (not (minibuffer-window-active-p other-window)))
+           (user-error "Minibuffer is inactive"))
+          (t
+           (if (not (consp arg))
+               (delete-window other-window)
+             (delete-window (selected-window))
+             (select-window other-window))))))
+
+;;;###autoload
+(defun windmove-delete-left (&optional arg)
+  "Delete the window to the left of the current one.
+If prefix ARG is `C-u', delete the selected window and
+select the window that was to the left of the current one."
+  (interactive "P")
+  (windmove-delete-in-direction 'left arg))
+
+;;;###autoload
+(defun windmove-delete-up (&optional arg)
+  "Delete the window above the current one.
+If prefix ARG is `C-u', delete the selected window and
+select the window that was above the current one."
+  (interactive "P")
+  (windmove-delete-in-direction 'up arg))
+
+;;;###autoload
+(defun windmove-delete-right (&optional arg)
+  "Delete the window to the right of the current one.
+If prefix ARG is `C-u', delete the selected window and
+select the window that was to the right of the current one."
+  (interactive "P")
+  (windmove-delete-in-direction 'right arg))
+
+;;;###autoload
+(defun windmove-delete-down (&optional arg)
+  "Delete the window below the current one.
+If prefix ARG is `C-u', delete the selected window and
+select the window that was below the current one."
+  (interactive "P")
+  (windmove-delete-in-direction 'down arg))
+
+;;;###autoload
+(defun windmove-delete-default-keybindings (&optional prefix modifiers)
+  "Set up keybindings for directional window deletion.
+Keys are bound to commands that delete windows in the specified
+direction.  Keybindings are of the form PREFIX MODIFIERS-{left,right,up,down},
+where PREFIX is a prefix key and MODIFIERS is either a list of modifiers or
+a single modifier.  Default value of PREFIX is `C-x' and MODIFIERS is `shift'."
+  (interactive)
+  (unless prefix (setq prefix '(?\C-x)))
+  (unless (listp prefix) (setq prefix (list prefix)))
+  (unless modifiers (setq modifiers '(shift)))
+  (unless (listp modifiers) (setq modifiers (list modifiers)))
+  (global-set-key (vector prefix (append modifiers '(left)))  'windmove-delete-left)
+  (global-set-key (vector prefix (append modifiers '(right))) 'windmove-delete-right)
+  (global-set-key (vector prefix (append modifiers '(up)))    'windmove-delete-up)
+  (global-set-key (vector prefix (append modifiers '(down)))  'windmove-delete-down))
+
 (provide 'windmove)
 
 ;;; windmove.el ends here




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 21 Nov 2018 23:58:02 GMT) Full text and rfc822 format available.

Message #278 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Thu, 22 Nov 2018 01:38:47 +0200
> Then 'switch-to-buffer' will show the buffer in the selected window
> and 'pop-to-buffer-same-window' will find it there.  Or what am I
> missing?

If a new option is non-nil, switch-to-buffer could call
pop-to-buffer-same-window, and if the selected window
remains the same, then continue doing what it normally does:
set-window-buffer, set-window-start, set-window-point, etc.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 22 Nov 2018 07:41:01 GMT) Full text and rfc822 format available.

Message #281 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Thu, 22 Nov 2018 08:40:06 +0100
>> Then 'switch-to-buffer' will show the buffer in the selected window
>> and 'pop-to-buffer-same-window' will find it there.  Or what am I
>> missing?
>
> If a new option is non-nil, switch-to-buffer could call
> pop-to-buffer-same-window, and if the selected window
> remains the same, then continue doing what it normally does:
> set-window-buffer, set-window-start, set-window-point, etc.

Then instead of what you said earlier ...

  Maybe just call 'pop-to-buffer-same-window' at the end of 'switch-to-buffer'
  when a new option 'switch-to-buffer-pop' is non-nil?

... 'switch-to-buffer' would call 'pop-to-buffer-same-window' at the
beginning when 'switch-to-buffer-pop' is non-nil.  Right?  This means,
however, that it would skip the 'switch-to-buffer-in-dedicated-window'
rigmarole.  It wouldn't make sense because 'pop-to-buffer-same-window'
would probably use a completely different window anyway.  Right?

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 22 Nov 2018 07:42:02 GMT) Full text and rfc822 format available.

Message #284 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Thu, 22 Nov 2018 08:40:47 +0100
> One possible solution is to implement directional window deletion.
> The following patch allows using the prefix argument that will delete
> the selected window and select the window at the given direction.

Delete and select - smart idea.

> +;;; Directional window deletion
> +
> +(defun windmove-delete-in-direction (dir &optional arg)
> +  "Delete the window at direction DIR.
> +If prefix ARG is `C-u', delete the selected window and
> +select the window at direction DIR."
> +  (let ((other-window (window-in-direction dir nil nil arg
> +                                           windmove-wrap-around t)))

So 'windmove-wrap-around' non-nil means that the other window could be
the selected one and we try to delete ourselves.  Right?

> +          ((and (window-minibuffer-p other-window)
> +                (not (minibuffer-window-active-p other-window)))
> +           (user-error "Minibuffer is inactive"))

Should we try to delete the active minibuffer window?

> +;;;###autoload
> +(defun windmove-delete-default-keybindings (&optional prefix modifiers)
> +  "Set up keybindings for directional window deletion.
> +Keys are bound to commands that delete windows in the specified
> +direction.  Keybindings are of the form PREFIX MODIFIERS-{left,right,up,down},
> +where PREFIX is a prefix key and MODIFIERS is either a list of modifiers or
> +a single modifier.  Default value of PREFIX is `C-x' and MODIFIERS is `shift'."
> +  (interactive)
> +  (unless prefix (setq prefix '(?\C-x)))
> +  (unless (listp prefix) (setq prefix (list prefix)))
> +  (unless modifiers (setq modifiers '(shift)))
> +  (unless (listp modifiers) (setq modifiers (list modifiers)))
> +  (global-set-key (vector prefix (append modifiers '(left)))  'windmove-delete-left)
> +  (global-set-key (vector prefix (append modifiers '(right))) 'windmove-delete-right)
> +  (global-set-key (vector prefix (append modifiers '(up)))    'windmove-delete-up)
> +  (global-set-key (vector prefix (append modifiers '(down)))  'windmove-delete-down))

Feel free to install.  But note that eventually we should document
the keybinding stuff with a few, good examples.

Thanks, martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 22 Nov 2018 22:52:06 GMT) Full text and rfc822 format available.

Message #287 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 23 Nov 2018 00:39:50 +0200
>> +;;; Directional window deletion
>> +
>> +(defun windmove-delete-in-direction (dir &optional arg)
>> +  "Delete the window at direction DIR.
>> +If prefix ARG is `C-u', delete the selected window and
>> +select the window at direction DIR."
>> +  (let ((other-window (window-in-direction dir nil nil arg
>> +                                           windmove-wrap-around t)))
>
> So 'windmove-wrap-around' non-nil means that the other window could be
> the selected one and we try to delete ourselves.  Right?

Fortunately, 'windmove-wrap-around' doesn't wrap to the same window
when there is only one window in that direction.

>> +          ((and (window-minibuffer-p other-window)
>> +                (not (minibuffer-window-active-p other-window)))
>> +           (user-error "Minibuffer is inactive"))
>
> Should we try to delete the active minibuffer window?

Interesting question.  Do you think it's worth the trouble
to implement special handling of the minibuffer:

1. when a window in the below direction is requested to be deleted
   from the bottom window, and the minibuffer is active,
   then call (abort-recursive-edit)

2. when the selected bottom window is requested to be deleted
   and selection is requested to be moved in the below direction,
   then the minibuffer's window should be selected.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 22 Nov 2018 22:53:02 GMT) Full text and rfc822 format available.

Message #290 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 23 Nov 2018 00:45:11 +0200
> ... 'switch-to-buffer' would call 'pop-to-buffer-same-window' at the
> beginning when 'switch-to-buffer-pop' is non-nil.  Right?

Yes, I think now it's better to call it at the beginning.

> This means, however, that it would skip the
> 'switch-to-buffer-in-dedicated-window' rigmarole.  It wouldn't make
> sense because 'pop-to-buffer-same-window' would probably use
> a completely different window anyway.  Right?

'switch-to-buffer-in-dedicated-window' is only used in the
interactive spec.  But anyway 'display-buffer' called from
'pop-to-buffer-same-window' will handle dedicatedness in any case.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Fri, 23 Nov 2018 07:41:02 GMT) Full text and rfc822 format available.

Message #293 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 23 Nov 2018 08:39:49 +0100
>> This means, however, that it would skip the
>> 'switch-to-buffer-in-dedicated-window' rigmarole.  It wouldn't make
>> sense because 'pop-to-buffer-same-window' would probably use
>> a completely different window anyway.  Right?
>
> 'switch-to-buffer-in-dedicated-window' is only used in the
> interactive spec.

Would we avoid that 'switch-to-buffer-pop-to' affects C-x b?

> But anyway 'display-buffer' called from
> 'pop-to-buffer-same-window' will handle dedicatedness in any case.

Not the way 'switch-to-buffer' does it.  Anyway, if you know what you
want, please write the code.  We can iron out any differences in the
doc-strings, if needed.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Fri, 23 Nov 2018 07:41:02 GMT) Full text and rfc822 format available.

Message #296 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 23 Nov 2018 08:40:35 +0100
>>> +          ((and (window-minibuffer-p other-window)
>>> +                (not (minibuffer-window-active-p other-window)))
>>> +           (user-error "Minibuffer is inactive"))
>>
>> Should we try to delete the active minibuffer window?
>
> Interesting question.  Do you think it's worth the trouble
> to implement special handling of the minibuffer:
>
> 1. when a window in the below direction is requested to be deleted
>     from the bottom window, and the minibuffer is active,
>     then call (abort-recursive-edit)

This looks counter-intuitive unless we are also able to delete the
minibuffer window.

> 2. when the selected bottom window is requested to be deleted
>     and selection is requested to be moved in the below direction,
>     then the minibuffer's window should be selected.

If it's active, presumably.  I'm not sure, but I wouldn't do that in a
first version.  BTW, if you delete the window on the right frame
border and want selection to move to the right, does it wrap around to
the window on the left?

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sat, 24 Nov 2018 23:45:03 GMT) Full text and rfc822 format available.

Message #299 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 25 Nov 2018 01:20:57 +0200
>>>> +          ((and (window-minibuffer-p other-window)
>>>> +                (not (minibuffer-window-active-p other-window)))
>>>> +           (user-error "Minibuffer is inactive"))
>>>
>>> Should we try to delete the active minibuffer window?
>>
>> Interesting question.  Do you think it's worth the trouble
>> to implement special handling of the minibuffer:
>>
>> 1. when a window in the below direction is requested to be deleted
>>     from the bottom window, and the minibuffer is active,
>>     then call (abort-recursive-edit)
>
> This looks counter-intuitive unless we are also able to delete the
> minibuffer window.

But the minibuffer window can't be deleted:

0. emacs -Q
1. M-:
2. C-x o
3. Type and eval in *scratch*: (delete-window (window-in-direction 'below))

This error is signaled: "Attempt to delete minibuffer or sole ordinary window"

>> 2. when the selected bottom window is requested to be deleted
>>     and selection is requested to be moved in the below direction,
>>     then the minibuffer's window should be selected.
>
> If it's active, presumably.  I'm not sure, but I wouldn't do that in a
> first version.  BTW, if you delete the window on the right frame
> border and want selection to move to the right, does it wrap around to
> the window on the left?

Yes, it respects windmove-wrap-around.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sat, 24 Nov 2018 23:46:02 GMT) Full text and rfc822 format available.

Message #302 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 25 Nov 2018 01:40:29 +0200
[Message part 1 (text/plain, inline)]
> Would we avoid that 'switch-to-buffer-pop-to' affects C-x b?

'C-x b' is one of main beneficiaries of this feature.

> Anyway, if you know what you want, please write the code.
> We can iron out any differences in the doc-strings, if needed.

Do you see a problem with this implementation?

[switch-to-buffer-pop-to.1.patch (text/x-diff, inline)]
diff --git a/lisp/window.el b/lisp/window.el
index 43a742b2d8..b76729e752 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -7779,6 +7787,13 @@ switch-to-buffer-in-dedicated-window
   :group 'windows
   :version "25.1")
 
+(defcustom switch-to-buffer-pop-to nil
+  "If non-nil, use `pop-to-buffer-same-window' in the selected window.
+This allows custmization of conditional actions for `display-buffer'."
+  :type 'boolean
+  :group 'windows
+  :version "27.1")
+
 (defun switch-to-buffer (buffer-or-name &optional norecord force-same-window)
   "Display buffer BUFFER-OR-NAME in the selected window.
 
@@ -7838,11 +7853,13 @@ switch-to-buffer
               (`pop nil)
               (_ (set-window-dedicated-p nil nil) 'force-same-window))))))
      (list (read-buffer-to-switch "Switch to buffer: ") nil force-same-window)))
-  (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
+  (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name))
+        (set-window-data-p t))
     (cond
      ;; Don't call set-window-buffer if it's not needed since it
      ;; might signal an error (e.g. if the window is dedicated).
-     ((eq buffer (window-buffer)))
+     ((and (eq buffer (window-buffer))
+           (not switch-to-buffer-pop-to)))
      ((window-minibuffer-p)
       (if force-same-window
           (user-error "Cannot switch buffers in minibuffer window")
@@ -7852,6 +7869,13 @@ switch-to-buffer
           (user-error "Cannot switch buffers in a dedicated window")
         (pop-to-buffer buffer norecord)))
      (t
+      (when switch-to-buffer-pop-to
+        (let ((selected-window (selected-window)))
+          (pop-to-buffer-same-window buffer norecord)
+          (unless (eq (selected-window) selected-window)
+            (setq set-window-data-p nil))))
+
+      (when set-window-data-p
         (let* ((entry (assq buffer (window-prev-buffers)))
 	       (displayed (and (eq switch-to-buffer-preserve-window-point
 				   'already-displayed)
@@ -7863,7 +7887,7 @@ switch-to-buffer
 	    ;; Try to restore start and point of buffer in the selected
 	    ;; window (Bug#4041).
 	    (set-window-start (selected-window) (nth 1 entry) t)
-	  (set-window-point nil (nth 2 entry))))))
+	    (set-window-point nil (nth 2 entry)))))))
 
     (unless norecord
       (select-window (selected-window)))

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 25 Nov 2018 08:24:02 GMT) Full text and rfc822 format available.

Message #305 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 25 Nov 2018 09:23:15 +0100
> Do you see a problem with this implementation?

If 'switch-to-buffer-pop-to' is non-nil, you nevertheless run the
'force-same-window' rigmarole although 'pop-to-buffer-same-window'
might want to select a completely different window.  Please explain
this discrepancy unless I'm missing something completely obvious.

+(defcustom switch-to-buffer-pop-to nil
+  "If non-nil, use `pop-to-buffer-same-window' in the selected window.

Something like

"If non-nil, have `switch-to-buffer' run `pop-to-buffer-same-window'."

seems better.  BTW, I'm already thinking of calling this option
'switch-to-buffer-pop' because '-to' somehow requires an object where
to pop to and I doubt that a user will supply one.  Unless we do want
to allow a window here.

+This allows custmization of conditional actions for `display-buffer'."
                 ^

This option's doc would need more text, maybe a small example.

+        (set-window-data-p t))

Here I would write

         (set-window-start-and-point (not switch-to-buffer-pop-to))

(recall also that we use a trailing -p only for functions).

-     ((eq buffer (window-buffer)))
+     ((and (eq buffer (window-buffer))
+           (not switch-to-buffer-pop-to)))

This would show the buffer twice even when it already appears in the
same window, right?  Are you sure that this is TRT?  Unconditionally?

+          (unless (eq (selected-window) selected-window)
+            (setq set-window-data-p nil))))

Here I would then write

          (when (eq (selected-window) selected-window)
            (setq set-window-start-and-point t))))

and here instead of

+      (when set-window-data-p

I would use

      (when set-window-start-and-point

BTW your patch does not apply here well due to some whitespace
mismatches.

Thanks, martin





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 25 Nov 2018 08:25:01 GMT) Full text and rfc822 format available.

Message #308 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 25 Nov 2018 09:24:13 +0100
>> This looks counter-intuitive unless we are also able to delete the
>> minibuffer window.
>
> But the minibuffer window can't be deleted:

Yours ;-)

> 0. emacs -Q
> 1. M-:
> 2. C-x o
> 3. Type and eval in *scratch*: (delete-window (window-in-direction 'below))
>
> This error is signaled: "Attempt to delete minibuffer or sole ordinary window"

That's what the text you quoted above meant to say.  Recall that we
talk about a function called 'windmove-delete-in-direction'.  If
that function doesn't delete the window but aborts a recursive edit
instead then it misses its purpose OT1H and overkills OTOH.

>> If it's active, presumably.  I'm not sure, but I wouldn't do that in a
>> first version.  BTW, if you delete the window on the right frame
>> border and want selection to move to the right, does it wrap around to
>> the window on the left?
>
> Yes, it respects windmove-wrap-around.

OK.  The doc of 'windmove-wrap-around' should say that somewhere.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 25 Nov 2018 21:11:02 GMT) Full text and rfc822 format available.

Message #311 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 25 Nov 2018 23:01:34 +0200
[Message part 1 (text/plain, inline)]
> -     ((eq buffer (window-buffer)))
> +     ((and (eq buffer (window-buffer))
> +           (not switch-to-buffer-pop-to)))
>
> This would show the buffer twice even when it already appears in the
> same window, right?  Are you sure that this is TRT?  Unconditionally?

This change is intentional.  If the user requests to display the same
buffer in another window, we have to follow user's request - it's
a normal wish to display the same buffer in two different windows.

> BTW your patch does not apply here well due to some whitespace
> mismatches.

Sorry, I created the previous patch ignoring whitespace changes, so it
would be easier for you to see differences.  But now it should apply
properly with this new patch that takes into account all your comments:

[switch-to-buffer-pop.2.patch (text/x-diff, inline)]
diff --git a/lisp/window.el b/lisp/window.el
index 43a742b2d8..60daa9f070 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -7779,6 +7779,13 @@ switch-to-buffer-in-dedicated-window
   :group 'windows
   :version "25.1")
 
+(defcustom switch-to-buffer-pop nil
+  "If non-nil, have `switch-to-buffer' run `pop-to-buffer-same-window'.
+This allows customization of actions for `display-buffer'."
+  :type 'boolean
+  :group 'windows
+  :version "27.1")
+
 (defun switch-to-buffer (buffer-or-name &optional norecord force-same-window)
   "Display buffer BUFFER-OR-NAME in the selected window.
 
@@ -7820,29 +7827,32 @@ switch-to-buffer
 Return the buffer switched to."
   (interactive
    (let ((force-same-window
-          (cond
-           ((window-minibuffer-p) nil)
-           ((not (eq (window-dedicated-p) t)) 'force-same-window)
-           ((pcase switch-to-buffer-in-dedicated-window
-              (`nil (user-error
-                     "Cannot switch buffers in a dedicated window"))
-              (`prompt
-               (if (y-or-n-p
-                    (format "Window is dedicated to %s; undedicate it"
-                            (window-buffer)))
-                   (progn
-                     (set-window-dedicated-p nil nil)
-                     'force-same-window)
-                 (user-error
-                  "Cannot switch buffers in a dedicated window")))
-              (`pop nil)
-              (_ (set-window-dedicated-p nil nil) 'force-same-window))))))
+          (unless switch-to-buffer-pop
+            (cond
+             ((window-minibuffer-p) nil)
+             ((not (eq (window-dedicated-p) t)) 'force-same-window)
+             ((pcase switch-to-buffer-in-dedicated-window
+                (`nil (user-error
+                       "Cannot switch buffers in a dedicated window"))
+                (`prompt
+                 (if (y-or-n-p
+                      (format "Window is dedicated to %s; undedicate it"
+                              (window-buffer)))
+                     (progn
+                       (set-window-dedicated-p nil nil)
+                       'force-same-window)
+                   (user-error
+                    "Cannot switch buffers in a dedicated window")))
+                (`pop nil)
+                (_ (set-window-dedicated-p nil nil) 'force-same-window)))))))
      (list (read-buffer-to-switch "Switch to buffer: ") nil force-same-window)))
-  (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
+  (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name))
+        (set-window-start-and-point (not switch-to-buffer-pop)))
     (cond
      ;; Don't call set-window-buffer if it's not needed since it
      ;; might signal an error (e.g. if the window is dedicated).
-     ((eq buffer (window-buffer)))
+     ((and (eq buffer (window-buffer))
+           (not switch-to-buffer-pop)))
      ((window-minibuffer-p)
       (if force-same-window
           (user-error "Cannot switch buffers in minibuffer window")
@@ -7852,18 +7862,25 @@ switch-to-buffer
           (user-error "Cannot switch buffers in a dedicated window")
         (pop-to-buffer buffer norecord)))
      (t
-      (let* ((entry (assq buffer (window-prev-buffers)))
-	     (displayed (and (eq switch-to-buffer-preserve-window-point
-				 'already-displayed)
-			     (get-buffer-window buffer 0))))
-	(set-window-buffer nil buffer)
-	(when (and entry
-		   (or (eq switch-to-buffer-preserve-window-point t)
-		       displayed))
-	  ;; Try to restore start and point of buffer in the selected
-	  ;; window (Bug#4041).
-	  (set-window-start (selected-window) (nth 1 entry) t)
-	  (set-window-point nil (nth 2 entry))))))
+      (when switch-to-buffer-pop
+        (let ((selected-window (selected-window)))
+          (pop-to-buffer-same-window buffer norecord)
+          (when (eq (selected-window) selected-window)
+            (setq set-window-start-and-point t))))
+
+      (when set-window-start-and-point
+        (let* ((entry (assq buffer (window-prev-buffers)))
+	       (displayed (and (eq switch-to-buffer-preserve-window-point
+				   'already-displayed)
+			       (get-buffer-window buffer 0))))
+	  (set-window-buffer nil buffer)
+	  (when (and entry
+		     (or (eq switch-to-buffer-preserve-window-point t)
+		         displayed))
+	    ;; Try to restore start and point of buffer in the selected
+	    ;; window (Bug#4041).
+	    (set-window-start (selected-window) (nth 1 entry) t)
+	    (set-window-point nil (nth 2 entry)))))))
 
     (unless norecord
       (select-window (selected-window)))

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 26 Nov 2018 09:34:02 GMT) Full text and rfc822 format available.

Message #314 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 26 Nov 2018 10:33:08 +0100
>> -     ((eq buffer (window-buffer)))
>> +     ((and (eq buffer (window-buffer))
>> +           (not switch-to-buffer-pop-to)))
>>
>> This would show the buffer twice even when it already appears in the
>> same window, right?  Are you sure that this is TRT?  Unconditionally?
>
> This change is intentional.  If the user requests to display the same
> buffer in another window, we have to follow user's request - it's
> a normal wish to display the same buffer in two different windows.

OK.  The user can still reuse the window via the buffer display
options.

> Sorry, I created the previous patch ignoring whitespace changes, so it
> would be easier for you to see differences.  But now it should apply
> properly with this new patch that takes into account all your comments:

I see no more problems so feel free to install.  A doc-string update
and proper documentation in the manual are strictly needed, though.

Thanks, martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 27 Nov 2018 00:39:03 GMT) Full text and rfc822 format available.

Message #317 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 27 Nov 2018 01:47:53 +0200
> I see no more problems so feel free to install.  A doc-string update
> and proper documentation in the manual are strictly needed, though.

But wait, maybe still 'switch-to-buffer-pop-to' would be a better name?
I think now that maybe in future it might require an object like you
already noted recently.

It could accept a list of buffer names that are allowed to be displayed
with 'pop-to-buffer-same-window' like is accepted in the customizable
variable 'same-window-buffer-names', or a list of regexps like in
'same-window-regexps'.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 27 Nov 2018 00:39:04 GMT) Full text and rfc822 format available.

Message #320 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 27 Nov 2018 01:53:42 +0200
> Feel free to install.

I realized now that maybe a new prefix arg could be useful to also
kill the buffer that was displayed in the deleted window.  Not sure,
if better to do this using the arg KILL of quit-window, or call
kill-buffer explicitly after deleting the window in the given direction.

The prefix arg could be 'C-u C-u', e.g. 'C-u C-u C-x S-down' to delete
the window below and kill the buffer that it displayed.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 27 Nov 2018 06:01:01 GMT) Full text and rfc822 format available.

Message #323 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Juri Linkov <juri <at> linkov.net>
Cc: rudalics <at> gmx.at, 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 27 Nov 2018 08:00:15 +0200
> From: Juri Linkov <juri <at> linkov.net>
> Date: Tue, 27 Nov 2018 01:47:53 +0200
> Cc: 32790 <at> debbugs.gnu.org
> 
> But wait, maybe still 'switch-to-buffer-pop-to' would be a better name?

I find this name sub-optimal, as it doesn't make sense as an English
phrase, and doesn't describe well enough what it means.

How about switch-to-buffer-use-pop-to or maybe
switch-to-buffer-obey-display-actions?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 27 Nov 2018 08:09:02 GMT) Full text and rfc822 format available.

Message #326 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 27 Nov 2018 09:08:20 +0100
> But wait, maybe still 'switch-to-buffer-pop-to' would be a better name?
> I think now that maybe in future it might require an object like you
> already noted recently.

I think what Eli says is right - it should have a proper name.

> It could accept a list of buffer names that are allowed to be displayed
> with 'pop-to-buffer-same-window' like is accepted in the customizable
> variable 'same-window-buffer-names', or a list of regexps like in
> 'same-window-regexps'.

Those variables were a continuous annoyance because applications (and
Emacs core) added their buffers to those lists at will.  I'd rather
avoid such mischief.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Tue, 27 Nov 2018 08:09:02 GMT) Full text and rfc822 format available.

Message #329 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Tue, 27 Nov 2018 09:08:28 +0100
> I realized now that maybe a new prefix arg could be useful to also
> kill the buffer that was displayed in the deleted window.  Not sure,
> if better to do this using the arg KILL of quit-window, or call
> kill-buffer explicitly after deleting the window in the given direction.
>
> The prefix arg could be 'C-u C-u', e.g. 'C-u C-u C-x S-down' to delete
> the window below and kill the buffer that it displayed.

I can't give you any suggestions here because I can't memorize such
combinations in the first place.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 28 Nov 2018 00:46:03 GMT) Full text and rfc822 format available.

Message #332 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: rudalics <at> gmx.at, 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Wed, 28 Nov 2018 01:18:13 +0200
>> But wait, maybe still 'switch-to-buffer-pop-to' would be a better name?
>
> I find this name sub-optimal, as it doesn't make sense as an English
> phrase, and doesn't describe well enough what it means.
>
> How about switch-to-buffer-use-pop-to or maybe
> switch-to-buffer-obey-display-actions?

Yes, this is a much better name because it reflects the purpose of the option
instead of the implementation details.  I also updated the docstring:

diff --git a/lisp/window.el b/lisp/window.el
index 2634955a75..4a1637ad0f 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -7779,6 +7779,16 @@ switch-to-buffer-in-dedicated-window
   :group 'windows
   :version "25.1")
 
+(defcustom switch-to-buffer-obey-display-actions nil
+  "If non-nil, have `switch-to-buffer' run `pop-to-buffer-same-window'.
+This means that when switching the buffer it respects display actions
+specified for `display-buffer'.  So `switch-to-buffer' will display the
+buffer in the window specified by the ACTION argument of `display-buffer',
+or by the rules in `display-buffer-alist' and other related variables."
+  :type 'boolean
+  :group 'windows
+  :version "27.1")
+
 (defun switch-to-buffer (buffer-or-name &optional norecord force-same-window)
   "Display buffer BUFFER-OR-NAME in the selected window.
 
@@ -7820,6 +7830,7 @@ switch-to-buffer
 Return the buffer switched to."
   (interactive
    (let ((force-same-window
+          (unless switch-to-buffer-obey-display-actions
             (cond
              ((window-minibuffer-p) nil)
              ((not (eq (window-dedicated-p) t)) 'force-same-window)
@@ -7836,13 +7847,15 @@ switch-to-buffer
                    (user-error
                     "Cannot switch buffers in a dedicated window")))
                 ('pop nil)
-              (_ (set-window-dedicated-p nil nil) 'force-same-window))))))
+                (_ (set-window-dedicated-p nil nil) 'force-same-window)))))))
      (list (read-buffer-to-switch "Switch to buffer: ") nil force-same-window)))
-  (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
+  (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name))
+        (set-window-start-and-point (not switch-to-buffer-obey-display-actions)))
     (cond
      ;; Don't call set-window-buffer if it's not needed since it
      ;; might signal an error (e.g. if the window is dedicated).
-     ((eq buffer (window-buffer)))
+     ((and (eq buffer (window-buffer))
+           (not switch-to-buffer-obey-display-actions)))
      ((window-minibuffer-p)
       (if force-same-window
           (user-error "Cannot switch buffers in minibuffer window")
@@ -7852,6 +7865,13 @@ switch-to-buffer
           (user-error "Cannot switch buffers in a dedicated window")
         (pop-to-buffer buffer norecord)))
      (t
+      (when switch-to-buffer-obey-display-actions
+        (let ((selected-window (selected-window)))
+          (pop-to-buffer-same-window buffer norecord)
+          (when (eq (selected-window) selected-window)
+            (setq set-window-start-and-point t))))
+
+      (when set-window-start-and-point
         (let* ((entry (assq buffer (window-prev-buffers)))
 	       (displayed (and (eq switch-to-buffer-preserve-window-point
 				   'already-displayed)
@@ -7863,7 +7883,7 @@ switch-to-buffer
 	    ;; Try to restore start and point of buffer in the selected
 	    ;; window (Bug#4041).
 	    (set-window-start (selected-window) (nth 1 entry) t)
-	  (set-window-point nil (nth 2 entry))))))
+	    (set-window-point nil (nth 2 entry)))))))
 
     (unless norecord
       (select-window (selected-window)))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 28 Nov 2018 00:46:03 GMT) Full text and rfc822 format available.

Message #335 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Wed, 28 Nov 2018 01:28:40 +0200
>> I realized now that maybe a new prefix arg could be useful to also
>> kill the buffer that was displayed in the deleted window.  Not sure,
>> if better to do this using the arg KILL of quit-window, or call
>> kill-buffer explicitly after deleting the window in the given direction.
>>
>> The prefix arg could be 'C-u C-u', e.g. 'C-u C-u C-x S-down' to delete
>> the window below and kill the buffer that it displayed.
>
> I can't give you any suggestions here because I can't memorize such
> combinations in the first place.

There are commands that use triple C-u, so this sequence is not too long.
I can't find a function that deletes the window together with killing its
buffer ('quit-window' with the arg KILL kills the buffer, but doesn't
always delete the window):

diff --git a/lisp/windmove.el b/lisp/windmove.el
index 6d61806a83..de3507d2d6 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -588,7 +588,9 @@ windmove-display-in-direction
 If prefix ARG is `C-u', reselect a previously selected window.
 If `windmove-display-no-select' is non-nil, this command doesn't
 select the window with a displayed buffer, and the meaning of
-the prefix argument is reversed."
+the prefix argument is reversed.
+When `switch-to-buffer-obey-display-actions' is non-nil,
+`switch-to-buffer' commands are also supported."
   (let* ((no-select (not (eq (consp arg) windmove-display-no-select))) ; xor
          (old-window (or (minibuffer-selected-window) (selected-window)))
          (new-window)
@@ -684,6 +686,7 @@ windmove-delete-in-direction
   "Delete the window at direction DIR.
 If prefix ARG is `C-u', delete the selected window and
 select the window at direction DIR.
+With two \\[universal-argument] prefixes, also kill the buffer in that window.
 When `windmove-wrap-around' is non-nil, takes the window
 from the opposite side of the frame."
   (let ((other-window (window-in-direction dir nil nil arg
@@ -691,7 +694,9 @@ windmove-delete-in-direction
     (cond ((null other-window)
            (user-error "No window %s from selected window" dir))
           (t
-           (if (not (consp arg))
+           (when (equal arg '(16))
+             (kill-buffer (window-buffer other-window)))
+           (if (not (equal arg '(4)))
                (delete-window other-window)
              (delete-window (selected-window))
              (select-window other-window))))))




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 28 Nov 2018 08:34:01 GMT) Full text and rfc822 format available.

Message #338 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>, Eli Zaretskii <eliz <at> gnu.org>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Wed, 28 Nov 2018 09:33:16 +0100
> +  "If non-nil, have `switch-to-buffer' run `pop-to-buffer-same-window'.
> +This means that when switching the buffer it respects display actions
> +specified for `display-buffer'.  So `switch-to-buffer' will display the
> +buffer in the window specified by the ACTION argument of `display-buffer',
> +or by the rules in `display-buffer-alist' and other related variables."

I don't think this is right because 'switch-to-buffer' does not have a
display action it can pass to 'display-buffer'.  The behavior is
subject to 'display-buffer-overriding-action', 'display-buffer-alist'
and other related variables alone IIUC.

Furthermore, the doc-string of 'switch-to-buffer' should be amended
like:

If the option 'switch-to-buffer-obey-display-actions' is non-nil, run
the function 'pop-to-buffer-same-window' instead.  This may display
the buffer in an arbitrary window as specified by
'display-buffer-overriding-action', 'display-buffer-alist' and other
display related variables.  If this results in displaying the buffer
in the selected window, window start and point are adjusted as
prescribed by the option `switch-to-buffer-preserve-window-point'.
Otherwise, these are left alone.

And the following part of the doc-string

  If optional argument FORCE-SAME-WINDOW is non-nil, the buffer
  must be displayed in the selected window when called
  non-interactively; if that is impossible, signal an error rather
  than calling `pop-to-buffer'.

is presumably invalid when 'switch-to-buffer-obey-display-actions' is
non-nil.  Right?

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 28 Nov 2018 08:35:02 GMT) Full text and rfc822 format available.

Message #341 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Wed, 28 Nov 2018 09:33:50 +0100
> There are commands that use triple C-u, so this sequence is not too long.
> I can't find a function that deletes the window together with killing its
> buffer

Not even in abysses like 'kill-buffer-and-window'?

('quit-window' with the arg KILL kills the buffer, but doesn't
> always delete the window):

Because 'quit-window' tries to restore an earlier state.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 28 Nov 2018 23:54:03 GMT) Full text and rfc822 format available.

Message #344 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Thu, 29 Nov 2018 01:25:18 +0200
> I don't think this is right because 'switch-to-buffer' does not have a
> display action it can pass to 'display-buffer'.  The behavior is
> subject to 'display-buffer-overriding-action', 'display-buffer-alist'
> and other related variables alone IIUC.
>
> Furthermore, the doc-string of 'switch-to-buffer' should be amended
> like:
>
> If the option 'switch-to-buffer-obey-display-actions' is non-nil, run
> the function 'pop-to-buffer-same-window' instead.  This may display
> the buffer in an arbitrary window as specified by
> 'display-buffer-overriding-action', 'display-buffer-alist' and other
> display related variables.  If this results in displaying the buffer
> in the selected window, window start and point are adjusted as
> prescribed by the option `switch-to-buffer-preserve-window-point'.
> Otherwise, these are left alone.
>
> And the following part of the doc-string
>
>   If optional argument FORCE-SAME-WINDOW is non-nil, the buffer
>   must be displayed in the selected window when called
>   non-interactively; if that is impossible, signal an error rather
>   than calling `pop-to-buffer'.
>
> is presumably invalid when 'switch-to-buffer-obey-display-actions' is
> non-nil.  Right?

Is this better?

diff --git a/lisp/window.el b/lisp/window.el
index 2634955a75..bc07300f0c 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -7779,6 +7779,16 @@ switch-to-buffer-in-dedicated-window
   :group 'windows
   :version "25.1")
 
+(defcustom switch-to-buffer-obey-display-actions nil
+  "If non-nil, have `switch-to-buffer' run `pop-to-buffer-same-window'.
+This means that when switching the buffer it respects display actions
+specified by `display-buffer-overriding-action', `display-buffer-alist'
+and other display related variables.  So `switch-to-buffer' will display
+the buffer in the window specified by the rules from these variables."
+  :type 'boolean
+  :group 'windows
+  :version "27.1")
+
 (defun switch-to-buffer (buffer-or-name &optional norecord force-same-window)
   "Display buffer BUFFER-OR-NAME in the selected window.
 
@@ -7811,15 +7821,26 @@ switch-to-buffer
 If optional argument FORCE-SAME-WINDOW is non-nil, the buffer
 must be displayed in the selected window when called
 non-interactively; if that is impossible, signal an error rather
-than calling `pop-to-buffer'.
+than calling `pop-to-buffer'.  It has no effect when the option
+`switch-to-buffer-obey-display-actions' is non-nil.
 
 The option `switch-to-buffer-preserve-window-point' can be used
 to make the buffer appear at its last position in the selected
 window.
 
+If the option `switch-to-buffer-obey-display-actions' is non-nil,
+run the function `pop-to-buffer-same-window' instead.
+This may display the buffer in another window as specified by
+`display-buffer-overriding-action', `display-buffer-alist' and
+other display related variables.  If this results in displaying
+the buffer in the selected window, window start and point are adjusted
+as prescribed by the option `switch-to-buffer-preserve-window-point'.
+Otherwise, these are left alone.
+
 Return the buffer switched to."
   (interactive
    (let ((force-same-window
+          (unless switch-to-buffer-obey-display-actions
             (cond
              ((window-minibuffer-p) nil)
              ((not (eq (window-dedicated-p) t)) 'force-same-window)
@@ -7836,13 +7857,17 @@ switch-to-buffer
                    (user-error
                     "Cannot switch buffers in a dedicated window")))
                 ('pop nil)
-              (_ (set-window-dedicated-p nil nil) 'force-same-window))))))
+                (_ (set-window-dedicated-p nil nil) 'force-same-window)))))))
      (list (read-buffer-to-switch "Switch to buffer: ") nil force-same-window)))
-  (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
+  (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name))
+        (set-window-start-and-point (not switch-to-buffer-obey-display-actions)))
     (cond
      ;; Don't call set-window-buffer if it's not needed since it
      ;; might signal an error (e.g. if the window is dedicated).
-     ((eq buffer (window-buffer)))
+     ((and (eq buffer (window-buffer))
+           ;; pop-to-buffer-same-window might decide to display
+           ;; the same buffer in another window
+           (not switch-to-buffer-obey-display-actions)))
      ((window-minibuffer-p)
       (if force-same-window
           (user-error "Cannot switch buffers in minibuffer window")
@@ -7852,6 +7877,13 @@ switch-to-buffer
           (user-error "Cannot switch buffers in a dedicated window")
         (pop-to-buffer buffer norecord)))
      (t
+      (when switch-to-buffer-obey-display-actions
+        (let ((selected-window (selected-window)))
+          (pop-to-buffer-same-window buffer norecord)
+          (when (eq (selected-window) selected-window)
+            (setq set-window-start-and-point t))))
+
+      (when set-window-start-and-point
         (let* ((entry (assq buffer (window-prev-buffers)))
 	       (displayed (and (eq switch-to-buffer-preserve-window-point
 				   'already-displayed)
@@ -7863,7 +7895,7 @@ switch-to-buffer
 	    ;; Try to restore start and point of buffer in the selected
 	    ;; window (Bug#4041).
 	    (set-window-start (selected-window) (nth 1 entry) t)
-	  (set-window-point nil (nth 2 entry))))))
+	    (set-window-point nil (nth 2 entry)))))))
 
     (unless norecord
       (select-window (selected-window)))





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 29 Nov 2018 08:32:02 GMT) Full text and rfc822 format available.

Message #347 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Thu, 29 Nov 2018 09:30:56 +0100
> Is this better?

I think so but the patch again doesn't apply for some reason.  Can you
resend it as attachment, please?

Thanks, martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 29 Nov 2018 22:56:03 GMT) Full text and rfc822 format available.

Message #350 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 30 Nov 2018 00:50:34 +0200
[Message part 1 (text/plain, inline)]
>> Is this better?
>
> I think so but the patch again doesn't apply for some reason.  Can you
> resend it as attachment, please?

Sorry, no code changes were performed, so I thought it would be better
to see just documentation changes ignoring whitespace differences.
But here it's a complete patch:

[switch-to-buffer-obey-display-actions.patch (text/x-diff, inline)]
diff --git a/lisp/window.el b/lisp/window.el
index 2634955a75..bc07300f0c 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -7779,6 +7779,16 @@ switch-to-buffer-in-dedicated-window
   :group 'windows
   :version "25.1")
 
+(defcustom switch-to-buffer-obey-display-actions nil
+  "If non-nil, have `switch-to-buffer' run `pop-to-buffer-same-window'.
+This means that when switching the buffer it respects display actions
+specified by `display-buffer-overriding-action', `display-buffer-alist'
+and other display related variables.  So `switch-to-buffer' will display
+the buffer in the window specified by the rules from these variables."
+  :type 'boolean
+  :group 'windows
+  :version "27.1")
+
 (defun switch-to-buffer (buffer-or-name &optional norecord force-same-window)
   "Display buffer BUFFER-OR-NAME in the selected window.
 
@@ -7811,38 +7821,53 @@ switch-to-buffer
 If optional argument FORCE-SAME-WINDOW is non-nil, the buffer
 must be displayed in the selected window when called
 non-interactively; if that is impossible, signal an error rather
-than calling `pop-to-buffer'.
+than calling `pop-to-buffer'.  It has no effect when the option
+`switch-to-buffer-obey-display-actions' is non-nil.
 
 The option `switch-to-buffer-preserve-window-point' can be used
 to make the buffer appear at its last position in the selected
 window.
 
+If the option `switch-to-buffer-obey-display-actions' is non-nil,
+run the function `pop-to-buffer-same-window' instead.
+This may display the buffer in another window as specified by
+`display-buffer-overriding-action', `display-buffer-alist' and
+other display related variables.  If this results in displaying
+the buffer in the selected window, window start and point are adjusted
+as prescribed by the option `switch-to-buffer-preserve-window-point'.
+Otherwise, these are left alone.
+
 Return the buffer switched to."
   (interactive
    (let ((force-same-window
-          (cond
-           ((window-minibuffer-p) nil)
-           ((not (eq (window-dedicated-p) t)) 'force-same-window)
-           ((pcase switch-to-buffer-in-dedicated-window
-              ('nil (user-error
-                     "Cannot switch buffers in a dedicated window"))
-              ('prompt
-               (if (y-or-n-p
-                    (format "Window is dedicated to %s; undedicate it"
-                            (window-buffer)))
-                   (progn
-                     (set-window-dedicated-p nil nil)
-                     'force-same-window)
-                 (user-error
-                  "Cannot switch buffers in a dedicated window")))
-              ('pop nil)
-              (_ (set-window-dedicated-p nil nil) 'force-same-window))))))
+          (unless switch-to-buffer-obey-display-actions
+            (cond
+             ((window-minibuffer-p) nil)
+             ((not (eq (window-dedicated-p) t)) 'force-same-window)
+             ((pcase switch-to-buffer-in-dedicated-window
+                ('nil (user-error
+                       "Cannot switch buffers in a dedicated window"))
+                ('prompt
+                 (if (y-or-n-p
+                      (format "Window is dedicated to %s; undedicate it"
+                              (window-buffer)))
+                     (progn
+                       (set-window-dedicated-p nil nil)
+                       'force-same-window)
+                   (user-error
+                    "Cannot switch buffers in a dedicated window")))
+                ('pop nil)
+                (_ (set-window-dedicated-p nil nil) 'force-same-window)))))))
      (list (read-buffer-to-switch "Switch to buffer: ") nil force-same-window)))
-  (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
+  (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name))
+        (set-window-start-and-point (not switch-to-buffer-obey-display-actions)))
     (cond
      ;; Don't call set-window-buffer if it's not needed since it
      ;; might signal an error (e.g. if the window is dedicated).
-     ((eq buffer (window-buffer)))
+     ((and (eq buffer (window-buffer))
+           ;; pop-to-buffer-same-window might decide to display
+           ;; the same buffer in another window
+           (not switch-to-buffer-obey-display-actions)))
      ((window-minibuffer-p)
       (if force-same-window
           (user-error "Cannot switch buffers in minibuffer window")
@@ -7852,18 +7877,25 @@ switch-to-buffer
           (user-error "Cannot switch buffers in a dedicated window")
         (pop-to-buffer buffer norecord)))
      (t
-      (let* ((entry (assq buffer (window-prev-buffers)))
-	     (displayed (and (eq switch-to-buffer-preserve-window-point
-				 'already-displayed)
-			     (get-buffer-window buffer 0))))
-	(set-window-buffer nil buffer)
-	(when (and entry
-		   (or (eq switch-to-buffer-preserve-window-point t)
-		       displayed))
-	  ;; Try to restore start and point of buffer in the selected
-	  ;; window (Bug#4041).
-	  (set-window-start (selected-window) (nth 1 entry) t)
-	  (set-window-point nil (nth 2 entry))))))
+      (when switch-to-buffer-obey-display-actions
+        (let ((selected-window (selected-window)))
+          (pop-to-buffer-same-window buffer norecord)
+          (when (eq (selected-window) selected-window)
+            (setq set-window-start-and-point t))))
+
+      (when set-window-start-and-point
+        (let* ((entry (assq buffer (window-prev-buffers)))
+	       (displayed (and (eq switch-to-buffer-preserve-window-point
+				   'already-displayed)
+			       (get-buffer-window buffer 0))))
+	  (set-window-buffer nil buffer)
+	  (when (and entry
+		     (or (eq switch-to-buffer-preserve-window-point t)
+		         displayed))
+	    ;; Try to restore start and point of buffer in the selected
+	    ;; window (Bug#4041).
+	    (set-window-start (selected-window) (nth 1 entry) t)
+	    (set-window-point nil (nth 2 entry)))))))
 
     (unless norecord
       (select-window (selected-window)))

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Fri, 30 Nov 2018 08:23:01 GMT) Full text and rfc822 format available.

Message #353 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 30 Nov 2018 09:22:14 +0100
> But here it's a complete patch:

Thanks.

> (defcustom switch-to-buffer-obey-display-actions nil
>   "If non-nil, have `switch-to-buffer' run `pop-to-buffer-same-window'.

Maybe

"If non-nil, `switch-to-buffer' runs `pop-to-buffer-same-window' instead.

is better.

>      ((window-minibuffer-p)
>       (if force-same-window
>           (user-error "Cannot switch buffers in minibuffer window")
>         (pop-to-buffer buffer norecord)))
>      ((eq (window-dedicated-p) t)
>       (if force-same-window
>           (user-error "Cannot switch buffers in a dedicated window")
>         (pop-to-buffer buffer norecord)))

These ones stupefied me when I tried to study your patch yesterday.
When 'switch-to-buffer-obey-display-actions' is non-nil you do not
reset 'force-same-window' so you can get an error when this is t and
you're either in the minibuffer or the window is strongly dedicated.
Right?

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sat, 01 Dec 2018 23:07:01 GMT) Full text and rfc822 format available.

Message #356 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 02 Dec 2018 00:43:01 +0200
>>      ((window-minibuffer-p)
>>       (if force-same-window
>>           (user-error "Cannot switch buffers in minibuffer window")
>>         (pop-to-buffer buffer norecord)))
>>      ((eq (window-dedicated-p) t)
>>       (if force-same-window
>>           (user-error "Cannot switch buffers in a dedicated window")
>>         (pop-to-buffer buffer norecord)))
>
> These ones stupefied me when I tried to study your patch yesterday.
> When 'switch-to-buffer-obey-display-actions' is non-nil you do not
> reset 'force-same-window' so you can get an error when this is t and
> you're either in the minibuffer or the window is strongly dedicated.
> Right?

I don't understand how 'force-same-window' can be non-nil if there is
a condition "unless switch-to-buffer-obey-display-actions" in the
interactive spec.  But if some code calls 'switch-to-buffer'
non-interactively with non-nil 'force-same-window', should it
signal an error when 'pop-to-buffer-same-window' displays the buffer
in another window?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 02 Dec 2018 08:35:01 GMT) Full text and rfc822 format available.

Message #359 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 02 Dec 2018 09:34:15 +0100
>> These ones stupefied me when I tried to study your patch yesterday.
>> When 'switch-to-buffer-obey-display-actions' is non-nil you do not
>> reset 'force-same-window' so you can get an error when this is t and
>> you're either in the minibuffer or the window is strongly dedicated.
>> Right?
>
> I don't understand how 'force-same-window' can be non-nil if there is
> a condition "unless switch-to-buffer-obey-display-actions" in the
> interactive spec.  But if some code calls 'switch-to-buffer'
> non-interactively with non-nil 'force-same-window', should it
> signal an error when 'pop-to-buffer-same-window' displays the buffer
> in another window?

The non-interactive case is the one I had in mind.  I think we mean to
say that FORCE-SAME-WINDOW has no impact in that case and
'switch-to-buffer' should not signal an error when the window is
dedicated or the minibuffer window but try to automatically display
the buffer in a window of its choice instead.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 03 Dec 2018 01:29:02 GMT) Full text and rfc822 format available.

Message #362 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 03 Dec 2018 02:45:35 +0200
[Message part 1 (text/plain, inline)]
>>> These ones stupefied me when I tried to study your patch yesterday.
>>> When 'switch-to-buffer-obey-display-actions' is non-nil you do not
>>> reset 'force-same-window' so you can get an error when this is t and
>>> you're either in the minibuffer or the window is strongly dedicated.
>>> Right?
>>
>> I don't understand how 'force-same-window' can be non-nil if there is
>> a condition "unless switch-to-buffer-obey-display-actions" in the
>> interactive spec.  But if some code calls 'switch-to-buffer'
>> non-interactively with non-nil 'force-same-window', should it
>> signal an error when 'pop-to-buffer-same-window' displays the buffer
>> in another window?
>
> The non-interactive case is the one I had in mind.  I think we mean to
> say that FORCE-SAME-WINDOW has no impact in that case and

We already added this to the docstring two patches ago.
This was the part of that change:

 If optional argument FORCE-SAME-WINDOW is non-nil, the buffer
 must be displayed in the selected window when called
 non-interactively; if that is impossible, signal an error rather
-than calling `pop-to-buffer'.
+than calling `pop-to-buffer'.  It has no effect when the option
+`switch-to-buffer-obey-display-actions' is non-nil.

> 'switch-to-buffer' should not signal an error when the window is
> dedicated or the minibuffer window but try to automatically display
> the buffer in a window of its choice instead.

Do you think this is right?

[switch-to-buffer-obey-display-actions.3.patch (text/x-diff, inline)]
diff --git a/lisp/window.el b/lisp/window.el
index 2634955a75..8313f71b54 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -7743,8 +7743,10 @@ switch-to-buffer-preserve-window-point
 position in the selected window.
 
 This variable is ignored if the buffer is already displayed in
-the selected window or never appeared in it before, or if
-`switch-to-buffer' calls `pop-to-buffer' to display the buffer."
+the selected window, or never appeared in it before, or if
+`switch-to-buffer' calls `pop-to-buffer' to display the buffer,
+or non-nil `switch-to-buffer-obey-display-actions' displays it
+in another window."
   :type '(choice
 	  (const :tag "Never" nil)
 	  (const :tag "If already displayed elsewhere" already-displayed)
@@ -7779,6 +7781,16 @@ switch-to-buffer-in-dedicated-window
   :group 'windows
   :version "25.1")
 
+(defcustom switch-to-buffer-obey-display-actions nil
+  "If non-nil, `switch-to-buffer' runs `pop-to-buffer-same-window' instead.
+This means that when switching the buffer it respects display actions
+specified by `display-buffer-overriding-action', `display-buffer-alist'
+and other display related variables.  So `switch-to-buffer' will display
+the buffer in the window specified by the rules from these variables."
+  :type 'boolean
+  :group 'windows
+  :version "27.1")
+
 (defun switch-to-buffer (buffer-or-name &optional norecord force-same-window)
   "Display buffer BUFFER-OR-NAME in the selected window.
 
@@ -7811,59 +7823,83 @@ switch-to-buffer
 If optional argument FORCE-SAME-WINDOW is non-nil, the buffer
 must be displayed in the selected window when called
 non-interactively; if that is impossible, signal an error rather
-than calling `pop-to-buffer'.
+than calling `pop-to-buffer'.  It has no effect when the option
+`switch-to-buffer-obey-display-actions' is non-nil.
 
 The option `switch-to-buffer-preserve-window-point' can be used
 to make the buffer appear at its last position in the selected
 window.
 
+If the option `switch-to-buffer-obey-display-actions' is non-nil,
+run the function `pop-to-buffer-same-window' instead.
+This may display the buffer in another window as specified by
+`display-buffer-overriding-action', `display-buffer-alist' and
+other display related variables.  If this results in displaying
+the buffer in the selected window, window start and point are adjusted
+as prescribed by the option `switch-to-buffer-preserve-window-point'.
+Otherwise, these are left alone.
+
 Return the buffer switched to."
   (interactive
    (let ((force-same-window
-          (cond
-           ((window-minibuffer-p) nil)
-           ((not (eq (window-dedicated-p) t)) 'force-same-window)
-           ((pcase switch-to-buffer-in-dedicated-window
-              ('nil (user-error
-                     "Cannot switch buffers in a dedicated window"))
-              ('prompt
-               (if (y-or-n-p
-                    (format "Window is dedicated to %s; undedicate it"
-                            (window-buffer)))
-                   (progn
-                     (set-window-dedicated-p nil nil)
-                     'force-same-window)
-                 (user-error
-                  "Cannot switch buffers in a dedicated window")))
-              ('pop nil)
-              (_ (set-window-dedicated-p nil nil) 'force-same-window))))))
+          (unless switch-to-buffer-obey-display-actions
+            (cond
+             ((window-minibuffer-p) nil)
+             ((not (eq (window-dedicated-p) t)) 'force-same-window)
+             ((pcase switch-to-buffer-in-dedicated-window
+                ('nil (user-error
+                       "Cannot switch buffers in a dedicated window"))
+                ('prompt
+                 (if (y-or-n-p
+                      (format "Window is dedicated to %s; undedicate it"
+                              (window-buffer)))
+                     (progn
+                       (set-window-dedicated-p nil nil)
+                       'force-same-window)
+                   (user-error
+                    "Cannot switch buffers in a dedicated window")))
+                ('pop nil)
+                (_ (set-window-dedicated-p nil nil) 'force-same-window)))))))
      (list (read-buffer-to-switch "Switch to buffer: ") nil force-same-window)))
-  (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name)))
+  (let ((buffer (window-normalize-buffer-to-switch-to buffer-or-name))
+        (set-window-start-and-point (not switch-to-buffer-obey-display-actions)))
     (cond
      ;; Don't call set-window-buffer if it's not needed since it
      ;; might signal an error (e.g. if the window is dedicated).
-     ((eq buffer (window-buffer)))
-     ((window-minibuffer-p)
+     ((and (eq buffer (window-buffer))
+           ;; pop-to-buffer-same-window might decide to display
+           ;; the same buffer in another window
+           (not switch-to-buffer-obey-display-actions)))
+     ((and (window-minibuffer-p)
+           (not switch-to-buffer-obey-display-actions))
       (if force-same-window
           (user-error "Cannot switch buffers in minibuffer window")
         (pop-to-buffer buffer norecord)))
-     ((eq (window-dedicated-p) t)
+     ((and (eq (window-dedicated-p) t)
+           (not switch-to-buffer-obey-display-actions))
       (if force-same-window
           (user-error "Cannot switch buffers in a dedicated window")
         (pop-to-buffer buffer norecord)))
      (t
-      (let* ((entry (assq buffer (window-prev-buffers)))
-	     (displayed (and (eq switch-to-buffer-preserve-window-point
-				 'already-displayed)
-			     (get-buffer-window buffer 0))))
-	(set-window-buffer nil buffer)
-	(when (and entry
-		   (or (eq switch-to-buffer-preserve-window-point t)
-		       displayed))
-	  ;; Try to restore start and point of buffer in the selected
-	  ;; window (Bug#4041).
-	  (set-window-start (selected-window) (nth 1 entry) t)
-	  (set-window-point nil (nth 2 entry))))))
+      (when switch-to-buffer-obey-display-actions
+        (let ((selected-window (selected-window)))
+          (pop-to-buffer-same-window buffer norecord)
+          (when (eq (selected-window) selected-window)
+            (setq set-window-start-and-point t))))
+
+      (when set-window-start-and-point
+        (let* ((entry (assq buffer (window-prev-buffers)))
+	       (displayed (and (eq switch-to-buffer-preserve-window-point
+				   'already-displayed)
+			       (get-buffer-window buffer 0))))
+	  (set-window-buffer nil buffer)
+	  (when (and entry
+		     (or (eq switch-to-buffer-preserve-window-point t)
+		         displayed))
+	    ;; Try to restore start and point of buffer in the selected
+	    ;; window (Bug#4041).
+	    (set-window-start (selected-window) (nth 1 entry) t)
+	    (set-window-point nil (nth 2 entry)))))))
 
     (unless norecord
       (select-window (selected-window)))

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Mon, 03 Dec 2018 07:46:01 GMT) Full text and rfc822 format available.

Message #365 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 03 Dec 2018 08:45:25 +0100
> We already added this to the docstring two patches ago.
> This was the part of that change:
>
>   If optional argument FORCE-SAME-WINDOW is non-nil, the buffer
>   must be displayed in the selected window when called
>   non-interactively; if that is impossible, signal an error rather
> -than calling `pop-to-buffer'.
> +than calling `pop-to-buffer'.  It has no effect when the option
> +`switch-to-buffer-obey-display-actions' is non-nil.

And I told you to remove it?

>> 'switch-to-buffer' should not signal an error when the window is
>> dedicated or the minibuffer window but try to automatically display
>> the buffer in a window of its choice instead.
>
> Do you think this is right?

Yes.  No more pretensions, please install.

Thanks, martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Thu, 20 Dec 2018 23:30:02 GMT) Full text and rfc822 format available.

Message #368 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 21 Dec 2018 01:28:47 +0200
>>> 'switch-to-buffer' should not signal an error when the window is
>>> dedicated or the minibuffer window but try to automatically display
>>> the buffer in a window of its choice instead.
>>
>> Do you think this is right?
>
> Yes.  No more pretensions, please install.

Installed after more testing.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Fri, 21 Dec 2018 09:16:02 GMT) Full text and rfc822 format available.

Message #371 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Fri, 21 Dec 2018 10:14:53 +0100
> Installed after more testing.

Thank you.  In the manual, before

 -- User Option: switch-to-buffer-obey-display-actions

I would add something like "Normally, the behavior of
'switch-to-buffer' cannot be customized.  The following option allows
to do that."

And the subsequent

     If this variable is non-`nil', `switch-to-buffer' respects display
     actions specified by `display-buffer-overriding-action',
     `display-buffer-alist' and other display related variables.

would profit from some sort of cross reference.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sat, 22 Dec 2018 23:47:02 GMT) Full text and rfc822 format available.

Message #374 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: martin rudalics <rudalics <at> gmx.at>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 23 Dec 2018 01:34:12 +0200
> In the manual, before
>
>  -- User Option: switch-to-buffer-obey-display-actions
>
> I would add something like "Normally, the behavior of
> 'switch-to-buffer' cannot be customized.  The following option allows
> to do that."

The text before describes the option `switch-to-buffer-preserve-window-point'.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Sun, 23 Dec 2018 09:41:02 GMT) Full text and rfc822 format available.

Message #377 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: martin rudalics <rudalics <at> gmx.at>
To: Juri Linkov <juri <at> linkov.net>
Cc: Eli Zaretskii <eliz <at> gnu.org>, 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Sun, 23 Dec 2018 10:40:33 +0100
>> In the manual, before
>>
>>   -- User Option: switch-to-buffer-obey-display-actions
>>
>> I would add something like "Normally, the behavior of
>> 'switch-to-buffer' cannot be customized.  The following option allows
>> to do that."
>
> The text before describes the option `switch-to-buffer-preserve-window-point'.

Right.  But it's exactly the introductory remark of that option

   By default, `switch-to-buffer' tries to preserve `window-point'.
This behavior can be tuned using the following option.

that should not extend over to 'switch-to-buffer-obey-display-actions'
IMO.  Maybe something like

"Normally, the behavior of 'switch-to-buffer' cannot be customized via
display actions.  The following option allows to do that."

But it's not very important.

martin




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#32790; Package emacs. (Wed, 26 Dec 2018 02:05:02 GMT) Full text and rfc822 format available.

Message #380 received at 32790 <at> debbugs.gnu.org (full text, mbox):

From: Dmitry Gutov <dgutov <at> yandex.ru>
To: Juri Linkov <juri <at> linkov.net>, martin rudalics <rudalics <at> gmx.at>
Cc: 32790 <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Wed, 26 Dec 2018 04:04:36 +0200
On 08.11.2018 23:38, Juri Linkov wrote:
>>> Shouldn't xref support a shorter and easier to type key sequence
>>> ‘S-M-<right> M-.’ with the following patch:
>>>
>>> diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
>>> index 6b1421a6f7..6aab174bcf 100644
>>> --- a/lisp/progmodes/xref.el
>>> +++ b/lisp/progmodes/xref.el
>>> @@ -425,7 +425,7 @@ xref--pop-to-location
>>>                       (xref-location-marker (xref-item-location item))))
>>>             (buf (marker-buffer marker)))
>>>        (cl-ecase action
>>> -      ((nil)  (switch-to-buffer buf))
>>> +      ((nil)  (pop-to-buffer-same-window buf))
>>>          (window (pop-to-buffer buf t))
>>>          (frame  (let ((pop-up-frames t)) (pop-to-buffer buf t))))
>>>        (xref--goto-char marker))
>>
>> I think so.  In particular because 'xref--goto-char' does not cohabit
>> well with 'switch-to-buffer-preserve-window-point' in the first place.
>> Dmitry should consent, though.
> 
> Dmitry, do you agree this is a change for the better?

It shouldn't hurt (but apparently you went with a different direction 
anyway already).

Sorry I never responded, but originally this bug had nothing to do with 
xref, and I tuned out months ago.

If somebody knows how to set up Thunderbird to somehow extra notify when 
somebody Cc's you directly, please send me a direct email.




Reply sent to Juri Linkov <juri <at> linkov.net>:
You have taken responsibility. (Tue, 26 Nov 2019 22:32:02 GMT) Full text and rfc822 format available.

Notification sent to Juri Linkov <juri <at> linkov.net>:
bug acknowledged by developer. (Tue, 26 Nov 2019 22:32:02 GMT) Full text and rfc822 format available.

Message #385 received at 32790-done <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: 32790-done <at> debbugs.gnu.org
Subject: Re: bug#32790: 27.0.50; point jumps unexpectedly after delete-window
Date: Mon, 25 Nov 2019 01:19:28 +0200
> This is not a regression, but nevertheless very annoying behavior.

I'm closing this report since now it's possible to delete windows
in the specified direction.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Wed, 25 Dec 2019 12:24:05 GMT) Full text and rfc822 format available.

This bug report was last modified 4 years and 325 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.