all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#47300: delete-window to select window with same position
@ 2021-03-21 20:31 Juri Linkov
  2021-05-18 14:49 ` Lars Ingebrigtsen
  0 siblings, 1 reply; 24+ messages in thread
From: Juri Linkov @ 2021-03-21 20:31 UTC (permalink / raw)
  To: 47300

[-- Attachment #1: Type: text/plain, Size: 1311 bytes --]

People still have trouble with unpredictable behavior of 'C-x 0'
that selects an unexpected window after the current window is deleted.

This is a recent example:
https://old.reddit.com/r/emacs/comments/m8omt0/how_can_deletewindow_cx_0_be_configured_to_stay/

The previous failed attempt to fix this was in bug#32790.

I still don't understand the current logic what window is selected
after deleting the selected window with 'C-x 0'.

But maybe this could be customizable?  Tried to write an advice:

(advice-add 'delete-window :around
            (lambda (orig-fun &optional window)
              (if window
                  ;; Non-interactive call
                  (funcall orig-fun window)
                ;; Interactive call
                (let* ((pos (window-absolute-pixel-position))
                       (x (when pos (/ (car pos) (frame-char-width))))
                       (y (when pos (/ (cdr pos) (frame-char-height)))))
                  (funcall orig-fun window)
                  ;; Select window that takes space from the deleted window
                  (when (and x y)
                    (select-window (window-at x y))))))
            '((name . delete-window-keep-pos)))

Maybe something like this could be adapted to delete-window
by adding an optional interactive argument keep-pos:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: delete-window-keep-pos.patch --]
[-- Type: text/x-diff, Size: 1635 bytes --]

diff --git a/lisp/window.el b/lisp/window.el
index f27631bb86..e2029406c7 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -4177,7 +4177,7 @@ window--before-delete-windows
                (push (list buf start-m pos-m) prev-buf)
                (set-window-prev-buffers win prev-buf)))))))
 
-(defun delete-window (&optional window)
+(defun delete-window (&optional window keep-pos)
   "Delete WINDOW.
 WINDOW must be a valid window and defaults to the selected one.
 Return nil.
@@ -4194,13 +4194,16 @@ delete-window
 argument.  Signal an error if WINDOW is either the only window on
 its frame, the last non-side window, or part of an atomic window
 that is its frame's root window."
-  (interactive)
+  (interactive (list nil t))
   (when switch-to-buffer-preserve-window-point
     (window--before-delete-windows))
+  (setq keep-pos (and keep-pos (not window) (window-absolute-pixel-position)))
   (setq window (window-normalize-window window))
   (let* ((frame (window-frame window))
 	 (function (window-parameter window 'delete-window))
 	 (parent (window-parent window))
+	 (keep-pos-x (when keep-pos (/ (car keep-pos) (frame-char-width))))
+	 (keep-pos-y (when keep-pos (/ (cdr keep-pos) (frame-char-height))))
 	 atom-root)
     (window--check frame)
     (catch 'done
@@ -4259,6 +4262,8 @@ delete-window
 	  ;; `delete-window-internal' has selected a window that should
 	  ;; not be selected, fix this here.
 	  (other-window -1 frame))
+	(when (and keep-pos-x keep-pos-y (window-at keep-pos-x keep-pos-y))
+	  (select-window (window-at keep-pos-x keep-pos-y)))
 	(window--check frame)
 	;; Always return nil.
 	nil))))

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-03-21 20:31 bug#47300: delete-window to select window with same position Juri Linkov
@ 2021-05-18 14:49 ` Lars Ingebrigtsen
  2021-05-18 16:00   ` martin rudalics
  0 siblings, 1 reply; 24+ messages in thread
From: Lars Ingebrigtsen @ 2021-05-18 14:49 UTC (permalink / raw)
  To: Juri Linkov; +Cc: 47300

Juri Linkov <juri@linkov.net> writes:

> People still have trouble with unpredictable behavior of 'C-x 0'
> that selects an unexpected window after the current window is deleted.
>
> This is a recent example:
> https://old.reddit.com/r/emacs/comments/m8omt0/how_can_deletewindow_cx_0_be_configured_to_stay/
>
> The previous failed attempt to fix this was in bug#32790.
>
> I still don't understand the current logic what window is selected
> after deleting the selected window with 'C-x 0'.

`C-x 0' isn't a command I use much, so I don't really have much
intuition about how it's supposed to work.  But, indeed, playing around
with it, it seems unexpected that `C-x 0' selects a different window
(instead of remaining in the "merged" window).

> Maybe something like this could be adapted to delete-window
> by adding an optional interactive argument keep-pos:

If I'm reading that patch correctly (I haven't actually tested), that
seems more DWIM to me.  Perhaps Martin has some comments here; added to
the CCs.  (And if anybody else has an opinion here, please do chime in.)

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-05-18 14:49 ` Lars Ingebrigtsen
@ 2021-05-18 16:00   ` martin rudalics
  2021-05-18 20:17     ` Juri Linkov
  0 siblings, 1 reply; 24+ messages in thread
From: martin rudalics @ 2021-05-18 16:00 UTC (permalink / raw)
  To: Lars Ingebrigtsen, Juri Linkov; +Cc: 47300

 >> People still have trouble with unpredictable behavior of 'C-x 0'
 >> that selects an unexpected window after the current window is deleted.
 >>
 >> This is a recent example:
 >> https://old.reddit.com/r/emacs/comments/m8omt0/how_can_deletewindow_cx_0_be_configured_to_stay/
 >>
 >> The previous failed attempt to fix this was in bug#32790.
 >>
 >> I still don't understand the current logic what window is selected
 >> after deleting the selected window with 'C-x 0'.

By design it's the most recently used window (`get-mru-window') on the
same frame after the deleted window has been removed from its window
tree.

 > `C-x 0' isn't a command I use much, so I don't really have much
 > intuition about how it's supposed to work.  But, indeed, playing around
 > with it, it seems unexpected that `C-x 0' selects a different window
 > (instead of remaining in the "merged" window).
 >
 >> Maybe something like this could be adapted to delete-window
 >> by adding an optional interactive argument keep-pos:
 >
 > If I'm reading that patch correctly (I haven't actually tested), that
 > seems more DWIM to me.  Perhaps Martin has some comments here; added to
 > the CCs.  (And if anybody else has an opinion here, please do chime in.)

Personally I don't care but people used to the current behavior might
get confused.  So an option should be the provided and could be "ON" by
default.

martin





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-05-18 16:00   ` martin rudalics
@ 2021-05-18 20:17     ` Juri Linkov
  2021-05-19  7:42       ` martin rudalics
  0 siblings, 1 reply; 24+ messages in thread
From: Juri Linkov @ 2021-05-18 20:17 UTC (permalink / raw)
  To: martin rudalics; +Cc: Lars Ingebrigtsen, 47300

> By design it's the most recently used window (`get-mru-window') on the
> same frame after the deleted window has been removed from its window
> tree.

I can't find where `get-mru-window' is called during window deletion.

> Personally I don't care but people used to the current behavior might
> get confused.  So an option should be the provided and could be "ON" by
> default.

Maybe a new option e.g. `delete-window-select' with type not boolean,
but a predicate with the default value `get-mru-window', and another
choice `delete-window-select-underlying' to select the "merged" window.





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-05-18 20:17     ` Juri Linkov
@ 2021-05-19  7:42       ` martin rudalics
  2021-05-19 16:07         ` Juri Linkov
  0 siblings, 1 reply; 24+ messages in thread
From: martin rudalics @ 2021-05-19  7:42 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Lars Ingebrigtsen, 47300

 > I can't find where `get-mru-window' is called during window deletion.

It's here in `delete-window-internal'

	  /* Now look whether `get-mru-window' gets us something.  */
	  mru_window = call1 (Qget_mru_window, frame);

 > Maybe a new option e.g. `delete-window-select' with type not boolean,
 > but a predicate with the default value `get-mru-window', and another
 > choice `delete-window-select-underlying' to select the "merged" window.

`get-mru-window' is not a predicate.  You probably mean a function so
that someone could also use `get-lru-window' as value of that option?
The problem with such a function is that it has to be called with some
predefined sort of FRAME or ALL-FRAMES argument so some explanatory
footwork would be required.

martin





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-05-19  7:42       ` martin rudalics
@ 2021-05-19 16:07         ` Juri Linkov
  2021-05-19 17:41           ` martin rudalics
  0 siblings, 1 reply; 24+ messages in thread
From: Juri Linkov @ 2021-05-19 16:07 UTC (permalink / raw)
  To: martin rudalics; +Cc: Lars Ingebrigtsen, 47300

>> I can't find where `get-mru-window' is called during window deletion.
>
> It's here in `delete-window-internal'
>
> 	  /* Now look whether `get-mru-window' gets us something.  */
> 	  mru_window = call1 (Qget_mru_window, frame);

Thanks, I missed it because I searched with 'C-x p g get-mru-window'
instead of 'C-x p g get.mru.window'.

>> Maybe a new option e.g. `delete-window-select' with type not boolean,
>> but a predicate with the default value `get-mru-window', and another
>> choice `delete-window-select-underlying' to select the "merged" window.
>
> `get-mru-window' is not a predicate.  You probably mean a function so
> that someone could also use `get-lru-window' as value of that option?

Yes, a function to get a window to select after window deletion.

> The problem with such a function is that it has to be called with some
> predefined sort of FRAME or ALL-FRAMES argument so some explanatory
> footwork would be required.

It's fine to call it with a FRAME argument.  The problem is
how to write such a function that will find the window that
gets the screen space previously owned by the deleted window.
Could you recommend the right direction?  Maybe this window that
gets the screen space is just the parent of the deleted window?





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-05-19 16:07         ` Juri Linkov
@ 2021-05-19 17:41           ` martin rudalics
  2021-05-22  8:05             ` martin rudalics
  0 siblings, 1 reply; 24+ messages in thread
From: martin rudalics @ 2021-05-19 17:41 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Lars Ingebrigtsen, 47300

 > It's fine to call it with a FRAME argument.  The problem is
 > how to write such a function that will find the window that
 > gets the screen space previously owned by the deleted window.
 > Could you recommend the right direction?  Maybe this window that
 > gets the screen space is just the parent of the deleted window?

No.  You probably have to save the old position of the deleted window's
point in frame coordinates and have the function that selects the new
window use the window that is now at that frame position.  The function
would be called instead of the currently hard-coded

	  mru_window = call1 (Qget_mru_window, frame);

and the call is fairly safe because the frame's first window has been
already selected at that time.

martin





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-05-19 17:41           ` martin rudalics
@ 2021-05-22  8:05             ` martin rudalics
  2021-05-22 21:25               ` Juri Linkov
  0 siblings, 1 reply; 24+ messages in thread
From: martin rudalics @ 2021-05-22  8:05 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Lars Ingebrigtsen, 47300

[-- Attachment #1: Type: text/plain, Size: 471 bytes --]

 > No.  You probably have to save the old position of the deleted window's
 > point in frame coordinates and have the function that selects the new
 > window use the window that is now at that frame position.

Just to explain what I meant above look at the attached patch.  I think
we should then move the `get-mru-window' call to `delete-window' too and
combine them all with the 'no-other-window' check so we never select a
window with NORECORD nil twice here.

martin

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: window.el.diff --]
[-- Type: text/x-patch; name="window.el.diff", Size: 1827 bytes --]

diff --git a/lisp/window.el b/lisp/window.el
index a403daf10b..32742f07c5 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -4800,6 +4800,8 @@ window--in-subtree-p
 		(throw 'done t)
 	      (setq parent (window-parent parent))))))))

+(defvar delete-window-use-posn-at-point nil)
+
 (defun delete-window (&optional window)
   "Delete WINDOW.
 WINDOW must be a valid window and defaults to the selected one.
@@ -4822,7 +4824,7 @@ delete-window
   (let* ((frame (window-frame window))
 	 (function (window-parameter window 'delete-window))
 	 (parent (window-parent window))
-	 atom-root)
+	 atom-root posn-at-point window-at-posn-at-point)
     (window--check frame)
     (catch 'done
       ;; Handle window parameters.
@@ -4871,10 +4873,20 @@ delete-window
 	 (t
 	  ;; Can't do without resizing fixed-size windows.
 	  (window--resize-siblings window (- size) horizontal t)))
+        (when delete-window-use-posn-at-point
+          ;; Remember WINDOW's position at point.
+          (setq posn-at-point (posn-at-point nil window)))
 	;; Actually delete WINDOW.
-	(delete-window-internal window)
+        (delete-window-internal window)
 	(window--pixel-to-total frame horizontal)
-	(when (and frame-selected
+        (when (and posn-at-point
+                   (setq window-at-posn-at-point
+                              (window-at (car (nth 6 posn-at-point))
+                                         (cdr (nth 6 posn-at-point))
+                                         frame)))
+          ;; Select window at WINDOW's position at point.
+          (select-window window-at-posn-at-point))
+        (when (and frame-selected
 		   (window-parameter
 		    (frame-selected-window frame) 'no-other-window))
 	  ;; `delete-window-internal' has selected a window that should

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-05-22  8:05             ` martin rudalics
@ 2021-05-22 21:25               ` Juri Linkov
  2021-05-23  8:43                 ` martin rudalics
  2021-05-25  6:50                 ` martin rudalics
  0 siblings, 2 replies; 24+ messages in thread
From: Juri Linkov @ 2021-05-22 21:25 UTC (permalink / raw)
  To: martin rudalics; +Cc: Lars Ingebrigtsen, 47300

>> No.  You probably have to save the old position of the deleted window's
>> point in frame coordinates and have the function that selects the new
>> window use the window that is now at that frame position.
>
> Just to explain what I meant above look at the attached patch.  I think
> we should then move the `get-mru-window' call to `delete-window' too and
> combine them all with the 'no-other-window' check so we never select a
> window with NORECORD nil twice here.
>
> [2. text/x-patch; window.el.diff]...

I don't know why, but sometimes `window-at' returns 'nil'.





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-05-22 21:25               ` Juri Linkov
@ 2021-05-23  8:43                 ` martin rudalics
  2021-05-25  6:50                 ` martin rudalics
  1 sibling, 0 replies; 24+ messages in thread
From: martin rudalics @ 2021-05-23  8:43 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Lars Ingebrigtsen, 47300

 > I don't know why, but sometimes `window-at' returns 'nil'.

This can happen because we are feeding it with the wrong arguments or
because there is a bug in its implementation.  I'd suggest you rewrite
`window-at' so you can easily put a breakpoint there when it returns nil
(or write your own `my-window-at' for that purpose) and wait till that
breakpoint gets hit.

Then have a look at the X, Y arguments and, if they are good, step with
GDB through coordinates_in_window to find out where and why it fails.

martin





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-05-22 21:25               ` Juri Linkov
  2021-05-23  8:43                 ` martin rudalics
@ 2021-05-25  6:50                 ` martin rudalics
  2021-05-26 21:29                   ` Juri Linkov
  1 sibling, 1 reply; 24+ messages in thread
From: martin rudalics @ 2021-05-25  6:50 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Lars Ingebrigtsen, 47300

 > I don't know why, but sometimes `window-at' returns 'nil'.

`window-at' is pretty useless anyway.  Try the below instead.

martin

(defun window-at-pos (x y &optional frame)
   "Return live window at position X, Y on specified FRAME.
X and Y are counted in pixels from the origin at 0, 0 of FRAME's
native frame.  FRAME must specify a live frame and defaults to
the selected one.  Return nil if no such window can be found."
   (setq frame (window-normalize-frame frame))
   (catch 'window
     (walk-window-tree
      (lambda (window)
        (let ((edges (window-edges window nil nil t)))
	 (when (and (>= x (nth 0 edges)) (<= x (nth 2 edges))
		    (>= y (nth 1 edges)) (<= y (nth 3 edges)))
	   (throw 'window window))))
      frame nil nil)))







^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-05-25  6:50                 ` martin rudalics
@ 2021-05-26 21:29                   ` Juri Linkov
  2021-05-27 15:20                     ` martin rudalics
  0 siblings, 1 reply; 24+ messages in thread
From: Juri Linkov @ 2021-05-26 21:29 UTC (permalink / raw)
  To: martin rudalics; +Cc: Lars Ingebrigtsen, 47300

[-- Attachment #1: Type: text/plain, Size: 267 bytes --]

>> I don't know why, but sometimes `window-at' returns 'nil'.
>
> `window-at' is pretty useless anyway.  Try the below instead.
>
> (defun window-at-pos (x y &optional frame)

Thanks.  Now after tweaking I finally found what changes would make
the workable version:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: delete-window-use-posn.patch --]
[-- Type: text/x-diff, Size: 2496 bytes --]

diff --git a/lisp/window.el b/lisp/window.el
index fd1c617d6b..81a770ff32 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -4140,6 +4140,23 @@ window--in-subtree-p
 		(throw 'done t)
 	      (setq parent (window-parent parent))))))))
 
+(defun window-at-pos (x y &optional frame)
+  "Return live window at position X, Y on specified FRAME.
+X and Y are counted in pixels from the origin at 0, 0 of FRAME's
+native frame.  FRAME must specify a live frame and defaults to
+the selected one.  Return nil if no such window can be found."
+  (setq frame (window-normalize-frame frame))
+  (catch 'window
+    (walk-window-tree
+     (lambda (window)
+       (let ((edges (window-edges window nil nil t)))
+	 (when (and (>= x (nth 0 edges)) (< x (nth 2 edges))
+		    (>= y (nth 1 edges)) (< y (nth 3 edges)))
+	   (throw 'window window))))
+     frame nil nil)))
+
+(defvar delete-window-use-posn-at-point t)
+
 (defun delete-window (&optional window)
   "Delete WINDOW.
 WINDOW must be a valid window and defaults to the selected one.
@@ -4162,7 +4179,7 @@ delete-window
   (let* ((frame (window-frame window))
 	 (function (window-parameter window 'delete-window))
 	 (parent (window-parent window))
-	 atom-root)
+	 atom-root posn-at-point-x posn-at-point-y window-at-posn-at-point)
     (window--check frame)
     (catch 'done
       ;; Handle window parameters.
@@ -4211,10 +4228,22 @@ delete-window
 	 (t
 	  ;; Can't do without resizing fixed-size windows.
 	  (window--resize-siblings window (- size) horizontal t)))
+        (when delete-window-use-posn-at-point
+          ;; Remember WINDOW's position at point.
+          (let ((edges (window-edges window nil nil t))
+                (posn-at-point (nth 2 (posn-at-point nil window))))
+            (when posn-at-point
+              (setq posn-at-point-x (+ (nth 0 edges) (car posn-at-point))
+                    posn-at-point-y (+ (nth 1 edges) (cdr posn-at-point))))))
 	;; Actually delete WINDOW.
 	(delete-window-internal window)
 	(window--pixel-to-total frame horizontal)
-	(when (and frame-selected
+        (when (and posn-at-point-x posn-at-point-y
+		   (setq window-at-posn-at-point
+			 (window-at-pos posn-at-point-x posn-at-point-y frame)))
+	  ;; Select window at WINDOW's position at point.
+	  (select-window window-at-posn-at-point))
+        (when (and frame-selected
 		   (window-parameter
 		    (frame-selected-window frame) 'no-other-window))
 	  ;; `delete-window-internal' has selected a window that should

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-05-26 21:29                   ` Juri Linkov
@ 2021-05-27 15:20                     ` martin rudalics
  2021-05-31 20:46                       ` Juri Linkov
  0 siblings, 1 reply; 24+ messages in thread
From: martin rudalics @ 2021-05-27 15:20 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Lars Ingebrigtsen, 47300

+	 (when (and (>= x (nth 0 edges)) (< x (nth 2 edges))
+		    (>= y (nth 1 edges)) (< y (nth 3 edges)))

We have to mention the "<" somewhere.  For two side-by-side windows with
the right window's point at 1, we obviously must avoid the left window's
right edge because the X, Y coordinates set by pos_visible_p are the top
left edge of the character box at that position, i.e., 0, 0.

But OTOH the "<" leaves the right edge of a frame's rightmost window
unhandled and someone might use that function for other purposes.

[...]

It would be a tad more elegant to just save `posn-at-point' here ...

+              (setq posn-at-point-x (+ (nth 0 edges) (car posn-at-point))
+                    posn-at-point-y (+ (nth 1 edges) (cdr posn-at-point))))))
  	;; Actually delete WINDOW.
  	(delete-window-internal window)
  	(window--pixel-to-total frame horizontal)
-	(when (and frame-selected

... and delay extracting its car and cdr until here.

+        (when (and posn-at-point-x posn-at-point-y
+		   (setq window-at-posn-at-point
+			 (window-at-pos posn-at-point-x posn-at-point-y frame)))

I'd still urge you to transfer the `get-mru-window' call here too, that
is, the entire

	  /* Now look whether `get-mru-window' gets us something.  */
	  mru_window = call1 (Qget_mru_window, frame);
	  if (WINDOW_LIVE_P (mru_window)
	      && EQ (XWINDOW (mru_window)->frame, frame))
	    new_selected_window = mru_window;

	  /* If all ended up well, we now promote the mru window.  */
	  if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
	    Fselect_window (new_selected_window, Qnil);
	  else
	    fset_selected_window (f, new_selected_window);

block, and to include the

         (when (and frame-selected
		   (window-parameter
		    (frame-selected-window frame) 'no-other-window))
	  ;; `delete-window-internal' has selected a window that should
	  ;; not be selected, fix this here.
	  (other-window -1 frame))

so we can avoid selecting a new window up to four times when deleting a
window (the one remaining call in `delete-window-internal' does not
record the window and has to stay there).  It's simply not nice to do
that.

martin





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-05-27 15:20                     ` martin rudalics
@ 2021-05-31 20:46                       ` Juri Linkov
  2021-06-02  9:08                         ` martin rudalics
  0 siblings, 1 reply; 24+ messages in thread
From: Juri Linkov @ 2021-05-31 20:46 UTC (permalink / raw)
  To: martin rudalics; +Cc: Lars Ingebrigtsen, 47300

> +	 (when (and (>= x (nth 0 edges)) (< x (nth 2 edges))
> +		    (>= y (nth 1 edges)) (< y (nth 3 edges)))
>
> We have to mention the "<" somewhere.  For two side-by-side windows with
> the right window's point at 1, we obviously must avoid the left window's
> right edge because the X, Y coordinates set by pos_visible_p are the top
> left edge of the character box at that position, i.e., 0, 0.
>
> But OTOH the "<" leaves the right edge of a frame's rightmost window
> unhandled and someone might use that function for other purposes.

I changed <= to < to fix only Y coordinates for top/bottom windows,
but maybe X coordinates should still use <= ?

> It would be a tad more elegant to just save `posn-at-point' here ...
>
> +              (setq posn-at-point-x (+ (nth 0 edges) (car posn-at-point))
> +                    posn-at-point-y (+ (nth 1 edges) (cdr posn-at-point))))))
>  	;; Actually delete WINDOW.
>  	(delete-window-internal window)
>  	(window--pixel-to-total frame horizontal)
> -	(when (and frame-selected
>
> ... and delay extracting its car and cdr until here.
>
> +        (when (and posn-at-point-x posn-at-point-y
> +		   (setq window-at-posn-at-point
> +			 (window-at-pos posn-at-point-x posn-at-point-y frame)))

Please note that the crucial difference is that now it uses
frame relative positions rather than window relative ones
with '(window-edges window nil nil t)' of the window to be deleted,
and window coordinates added to X and Y of posn-at-point.

> I'd still urge you to transfer the `get-mru-window' call here too, that
> is, the entire
>
> 	  /* Now look whether `get-mru-window' gets us something.  */
> 	  mru_window = call1 (Qget_mru_window, frame);
> 	  if (WINDOW_LIVE_P (mru_window)
> 	      && EQ (XWINDOW (mru_window)->frame, frame))
> 	    new_selected_window = mru_window;
>
> 	  /* If all ended up well, we now promote the mru window.  */
> 	  if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
> 	    Fselect_window (new_selected_window, Qnil);
> 	  else
> 	    fset_selected_window (f, new_selected_window);
>
> block, and to include the
>
>         (when (and frame-selected
> 		   (window-parameter
> 		    (frame-selected-window frame) 'no-other-window))
> 	  ;; `delete-window-internal' has selected a window that should
> 	  ;; not be selected, fix this here.
> 	  (other-window -1 frame))
>
> so we can avoid selecting a new window up to four times when deleting a
> window (the one remaining call in `delete-window-internal' does not
> record the window and has to stay there).  It's simply not nice to do
> that.

1. `get-mru-window' could be one possible choice of the new option.
2. `use-posn-at-point' could be another choice.
3. Selecting the first window could remain in `delete-window-internal'.
4. But what to do with this code block with '(other-window -1 frame)'?
   Should this be simply deleted?





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-05-31 20:46                       ` Juri Linkov
@ 2021-06-02  9:08                         ` martin rudalics
  2021-06-03 21:20                           ` Juri Linkov
  0 siblings, 1 reply; 24+ messages in thread
From: martin rudalics @ 2021-06-02  9:08 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Lars Ingebrigtsen, 47300

[-- Attachment #1: Type: text/plain, Size: 1385 bytes --]

 > I changed <= to < to fix only Y coordinates for top/bottom windows,
 > but maybe X coordinates should still use <= ?

The function has to treat the case where an edge is shared between two
windows separately.  A non-shared edge always belongs to the
corresponding window.

 > Please note that the crucial difference is that now it uses
 > frame relative positions rather than window relative ones
 > with '(window-edges window nil nil t)' of the window to be deleted,
 > and window coordinates added to X and Y of posn-at-point.

Right.  But the X and Y values are needed separately only at the time
`window-at-pos' is called.

 > 1. `get-mru-window' could be one possible choice of the new option.
 > 2. `use-posn-at-point' could be another choice.

I called them just 'mru' and 'pos' now.  The option is called
`selected-window-after-deletion', there might be better names.

 > 3. Selecting the first window could remain in `delete-window-internal'.

It has to stay there.

 > 4. But what to do with this code block with '(other-window -1 frame)'?
 >     Should this be simply deleted?

That `other-window' was a bug: A frame that is not selected should not
get selected because we delete a window on it.  In addition, the old
code did not record a newly selected window unless that window was
produced by `get-mru-window'.  I tried to fix those too.  Please have a
look.

martin

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: selected-window-after-deletion.diff --]
[-- Type: text/x-patch; name="selected-window-after-deletion.diff", Size: 10809 bytes --]

diff --git a/lisp/window.el b/lisp/window.el
index fd1c617d6b..20f664c6f5 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -2538,12 +2538,14 @@ get-lru-window
 	    (setq best-window window)))))
     (or best-window second-best-window)))

-(defun get-mru-window (&optional all-frames dedicated not-selected)
+(defun get-mru-window (&optional all-frames dedicated not-selected no-other)
    "Return the most recently used window on frames specified by ALL-FRAMES.
 A minibuffer window is never a candidate.  A dedicated window is
 never a candidate unless DEDICATED is non-nil, so if all windows
 are dedicated, the value is nil.  Optional argument NOT-SELECTED
-non-nil means never return the selected window.
+non-nil means never return the selected window.  Optional
+argument NO_OTHER non-nil means to never return a window whose
+'no-other-window' parameter is non-nil.

 The following non-nil values of the optional argument ALL-FRAMES
 have special meanings:
@@ -2565,7 +2567,9 @@ get-mru-window
       (setq time (window-use-time window))
       (when (and (or dedicated (not (window-dedicated-p window)))
 		 (or (not not-selected) (not (eq window (selected-window))))
-		 (or (not best-time) (> time best-time)))
+                 (or (not no-other)
+                     (not (window-parameter window 'no-other-window)))
+                 (or (not best-time) (> time best-time)))
 	(setq best-time time)
 	(setq best-window window)))
     best-window))
@@ -4130,18 +4134,53 @@ window-deletable-p
       ;; of its frame.
       t))))

-(defun window--in-subtree-p (window root)
-  "Return t if WINDOW is either ROOT or a member of ROOT's subtree."
-  (or (eq window root)
-      (let ((parent (window-parent window)))
-	(catch 'done
-	  (while parent
-	    (if (eq parent root)
-		(throw 'done t)
-	      (setq parent (window-parent parent))))))))
+(defun window-at-pos (x y &optional frame no-other)
+  "Return live window at coordinates X, Y on specified FRAME.
+X and Y are counted in pixels from an origin at 0, 0 of FRAME's
+native frame.  A coordinate on an edge shared by two windows is
+attributed to the window on the right (or below).  Return nil if
+no such window can be found.
+
+Optional argument FRAME must specify a live frame and defaults to
+the selected one.  Optional argument NO-OTHER non-nil means to
+not return a window with a non-nil 'no-other-window' parameter."
+  (setq frame (window-normalize-frame frame))
+  (let* ((root-edges (window-edges (frame-root-window frame) nil nil t))
+         (root-left (nth 2 root-edges))
+         (root-bottom (nth 3 root-edges)))
+    (catch 'window
+      (walk-window-tree
+       (lambda (window)
+         (let ((edges (window-edges window nil nil t)))
+	   (when (and (>= x (nth 0 edges))
+                      (or (< x (nth 2 edges)) (= x root-left))
+		      (>= y (nth 1 edges))
+                      (or (< y (nth 3 edges)) (= y root-bottom)))
+             (if (and no-other (window-parameter window 'no-other-window))
+                 (throw 'window nil)
+	       (throw 'window window)))))
+       frame))))
+
+(defcustom selected-window-after-deletion 'mru
+  "How to choose a frame's selected window after window deletion.
+When a frame's selected window gets deleted, Emacs has to choose
+another live window on that frame to serve as its selected
+window.  This option allows to control which window gets selected
+instead.
+
+The possible choices are 'mru' (the default) to select the most
+recently used window on that frame and 'pos' to choose the window
+at the position of point of the previously selected window.  If
+this is nil, choose the frame's first window instead.  A window
+with a non-nil 'no-other-window' parameter is never chosen."
+  :type '(choice (const :tag "Most recently used" mru)
+                 (const :tag "At position" pos)
+                 nil)
+  :group 'windows
+  :version "28.1")

 (defun delete-window (&optional window)
-  "Delete WINDOW.
+  "Delete specified WINDOW.
 WINDOW must be a valid window and defaults to the selected one.
 Return nil.

@@ -4156,7 +4195,11 @@ delete-window
 `delete-window' with the root of the atomic window as its
 argument.  Signal an error if WINDOW is either the only window on
 its frame, the last non-side window, or part of an atomic window
-that is its frame's root window."
+that is its frame's root window.
+
+If WINDOW is the selected window on its frame, choose some other
+window as that frame's selected window according to the value of
+the option `selected-window-after-deletion'."
   (interactive)
   (setq window (window-normalize-window window))
   (let* ((frame (window-frame window))
@@ -4191,11 +4234,11 @@ delete-window
              (window-combination-resize
               (or window-combination-resize
                   (window-parameter parent 'window-side)))
-	     (frame-selected
-	      (window--in-subtree-p (frame-selected-window frame) window))
+             (frame-selected-window (frame-selected-window frame))
 	     ;; Emacs 23 preferably gives WINDOW's space to its left
 	     ;; sibling.
-	     (sibling (or (window-left window) (window-right window))))
+	     (sibling (or (window-left window) (window-right window)))
+             frame-selected-window-edges frame-selected-window-pos)
 	(window--resize-reset frame horizontal)
 	(cond
 	 ((and (not (eq window-combination-resize t))
@@ -4211,15 +4254,63 @@ delete-window
 	 (t
 	  ;; Can't do without resizing fixed-size windows.
 	  (window--resize-siblings window (- size) horizontal t)))
+
+        (when (eq selected-window-after-deletion 'pos)
+          ;; Remember edges and position of point of the selected window
+          ;; of WINDOW'S frame.
+          (setq frame-selected-window-edges
+                (window-edges frame-selected-window nil nil t))
+          (setq frame-selected-window-pos
+                (nth 2 (posn-at-point nil frame-selected-window))))
+
 	;; Actually delete WINDOW.
 	(delete-window-internal window)
 	(window--pixel-to-total frame horizontal)
-	(when (and frame-selected
-		   (window-parameter
-		    (frame-selected-window frame) 'no-other-window))
-	  ;; `delete-window-internal' has selected a window that should
-	  ;; not be selected, fix this here.
-	  (other-window -1 frame))
+
+        ;; If we deleted the selected window of WINDOW's frame, choose
+        ;; another one based on `selected-window-after-deletion'.  Note
+        ;; that both `window-at-pos' and `get-mru-window' mail fail to
+        ;; produce a suitable window in which case we will fall back on
+        ;; its frame's first window, chosen by `delete-window-internal'.
+        (cond
+         ((window-live-p frame-selected-window))
+         ((and frame-selected-window-pos
+               ;; We have a recorded position of point of the previously
+               ;; selected window.  Try to find the window that is now
+               ;; at that position.
+               (let ((new-frame-selected-window
+		      (window-at-pos
+                       (+ (nth 0 frame-selected-window-edges)
+                          (car frame-selected-window-pos))
+                       (+ (nth 1 frame-selected-window-edges)
+                          (cdr frame-selected-window-pos))
+                       frame t)))
+                 (and new-frame-selected-window
+                      ;; Select window at WINDOW's position at point.
+	              (set-frame-selected-window
+                       frame new-frame-selected-window)))))
+         ((and (eq selected-window-after-deletion 'mru)
+               ;; Try to use the most recently used window.
+               (let ((mru-window (get-mru-window frame nil nil t)))
+                 (and mru-window
+	              (set-frame-selected-window frame mru-window)))))
+         ((and (window-parameter
+                (frame-selected-window frame) 'no-other-window)
+               ;; If `delete-window-internal' selected a window with a
+               ;; non-nil 'no-other-window' parameter as its frame's
+               ;; selected window, try to choose another one.
+               (catch 'found
+                 (walk-window-tree
+                  (lambda (other)
+                    (unless (window-parameter other 'no-other-window)
+                      (set-frame-selected-window frame other)
+                      (throw 'found t)))
+                  frame))))
+         (t
+          ;; Record the window chosen by `delete-window-internal'.
+          (set-frame-selected-window
+           frame (frame-selected-window frame))))
+
 	(window--check frame)
 	;; Always return nil.
 	nil))))
diff --git a/src/window.c b/src/window.c
index 2d98ae5f15..db324effcc 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5148,15 +5148,13 @@ DEFUN ("delete-window-internal", Fdelete_window_internal, Sdelete_window_interna
       adjust_frame_glyphs (f);

       if (!WINDOW_LIVE_P (FRAME_SELECTED_WINDOW (f)))
-	/* We deleted the frame's selected window.  */
+	/* We apparently deleted the frame's selected window; use the
+	   frame's first window as substitute but don't record it yet.
+	   `delete-window' may have something better up its sleeves.  */
 	{
 	  /* Use the frame's first window as fallback ...  */
 	  Lisp_Object new_selected_window = Fframe_first_window (frame);
-	  /* ... but preferably use its most recently used window.  */
-	  Lisp_Object mru_window;

-	  /* `get-mru-window' might fail for some reason so play it safe
-	  - promote the first window _without recording it_ first.  */
 	  if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
 	    Fselect_window (new_selected_window, Qt);
 	  else
@@ -5164,24 +5162,9 @@ DEFUN ("delete-window-internal", Fdelete_window_internal, Sdelete_window_interna
 	       last selected window on F was an active minibuffer, we
 	       want to return to it on a later Fselect_frame.  */
 	    fset_selected_window (f, new_selected_window);
-
-	  unblock_input ();
-
-	  /* Now look whether `get-mru-window' gets us something.  */
-	  mru_window = call1 (Qget_mru_window, frame);
-	  if (WINDOW_LIVE_P (mru_window)
-	      && EQ (XWINDOW (mru_window)->frame, frame))
-	    new_selected_window = mru_window;
-
-	  /* If all ended up well, we now promote the mru window.  */
-	  if (EQ (FRAME_SELECTED_WINDOW (f), selected_window))
-	    Fselect_window (new_selected_window, Qnil);
-	  else
-	    fset_selected_window (f, new_selected_window);
 	}
-      else
-	unblock_input ();

+      unblock_input ();
       FRAME_WINDOW_CHANGE (f) = true;
     }
   else

^ permalink raw reply related	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-06-02  9:08                         ` martin rudalics
@ 2021-06-03 21:20                           ` Juri Linkov
  2021-06-04  9:19                             ` martin rudalics
  0 siblings, 1 reply; 24+ messages in thread
From: Juri Linkov @ 2021-06-03 21:20 UTC (permalink / raw)
  To: martin rudalics; +Cc: Lars Ingebrigtsen, 47300

> I called them just 'mru' and 'pos' now.  The option is called
> `selected-window-after-deletion', there might be better names.

Maybe better with the same name prefix as `delete-window'?
For example, `delete-window-select'?  But the current is also fine.

> Please have a look.

Thanks, I tested out, and everything works nicely.
Only minor remarks:

> +(defun get-mru-window (&optional all-frames dedicated not-selected no-other)
> +non-nil means never return the selected window.  Optional
> +argument NO_OTHER non-nil means to never return a window whose

Typo:       NO-OTHER

> +(defcustom selected-window-after-deletion 'mru

Not strictly necessary now, but for future extensions
would it be possible to allow this option
to be customized to a function that selects a window?

> +  :type '(choice (const :tag "Most recently used" mru)
> +                 (const :tag "At position" pos)
> +                 nil)

This 'nil' needs to be replaced with a list like:

                    (const :tag "First window" nil)

> +        ;; If we deleted the selected window of WINDOW's frame, choose
> +        ;; another one based on `selected-window-after-deletion'.  Note
> +        ;; that both `window-at-pos' and `get-mru-window' mail fail to
                                                             =========
Typo.





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-06-03 21:20                           ` Juri Linkov
@ 2021-06-04  9:19                             ` martin rudalics
  2021-06-04 16:29                               ` Juri Linkov
  0 siblings, 1 reply; 24+ messages in thread
From: martin rudalics @ 2021-06-04  9:19 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Lars Ingebrigtsen, 47300

 >> I called them just 'mru' and 'pos' now.  The option is called
 >> `selected-window-after-deletion', there might be better names.
 >
 > Maybe better with the same name prefix as `delete-window'?
 > For example, `delete-window-select'?  But the current is also fine.

It's not about "selecting a window", it's about "setting a frame's
selected window".

 >> +(defun get-mru-window (&optional all-frames dedicated not-selected no-other)
 >> +non-nil means never return the selected window.  Optional
 >> +argument NO_OTHER non-nil means to never return a window whose
 >
 > Typo:       NO-OTHER

Indeed.

 >> +(defcustom selected-window-after-deletion 'mru
 >
 > Not strictly necessary now, but for future extensions
 > would it be possible to allow this option
 > to be customized to a function that selects a window?
 >
 >> +  :type '(choice (const :tag "Most recently used" mru)
 >> +                 (const :tag "At position" pos)
 >> +                 nil)

In general, just plugging in some existing function would usually fail
here and I would like to avoid the illusion that it could work.  Also,
as you can see with the 'pos' case, some work must be done _before_
calling `delete-window-internal' so the actual work would have to be
split among two functions at least.

 > This 'nil' needs to be replaced with a list like:
 >
 >                      (const :tag "First window" nil)
 >
 >> +        ;; If we deleted the selected window of WINDOW's frame, choose
 >> +        ;; another one based on `selected-window-after-deletion'.  Note
 >> +        ;; that both `window-at-pos' and `get-mru-window' mail fail to
 >                                                               =========
 > Typo.

But it rhymes!

martin





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-06-04  9:19                             ` martin rudalics
@ 2021-06-04 16:29                               ` Juri Linkov
  2021-06-06  7:43                                 ` martin rudalics
  0 siblings, 1 reply; 24+ messages in thread
From: Juri Linkov @ 2021-06-04 16:29 UTC (permalink / raw)
  To: martin rudalics; +Cc: Lars Ingebrigtsen, 47300

>>> I called them just 'mru' and 'pos' now.  The option is called
>>> `selected-window-after-deletion', there might be better names.
>>
>> Maybe better with the same name prefix as `delete-window'?
>> For example, `delete-window-select'?  But the current is also fine.
>
> It's not about "selecting a window", it's about "setting a frame's
> selected window".

I just tried to keep the prefix `delete-window-...'.
Then maybe `delete-window-set-selected'?

>>> +(defcustom selected-window-after-deletion 'mru
>>
>> Not strictly necessary now, but for future extensions
>> would it be possible to allow this option
>> to be customized to a function that selects a window?
>
> In general, just plugging in some existing function would usually fail
> here and I would like to avoid the illusion that it could work.  Also,
> as you can see with the 'pos' case, some work must be done _before_
> calling `delete-window-internal' so the actual work would have to be
> split among two functions at least.

The 'pos' case is an exception.  What I meant is simple cases
like customizing to 'get-lru-window'.





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-06-04 16:29                               ` Juri Linkov
@ 2021-06-06  7:43                                 ` martin rudalics
  2021-06-06 20:47                                   ` Juri Linkov
  0 siblings, 1 reply; 24+ messages in thread
From: martin rudalics @ 2021-06-06  7:43 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Lars Ingebrigtsen, 47300

 >> It's not about "selecting a window", it's about "setting a frame's
 >> selected window".
 >
 > I just tried to keep the prefix `delete-window-...'.
 > Then maybe `delete-window-set-selected'?

Not very illustrative either.

 >> In general, just plugging in some existing function would usually fail
 >> here and I would like to avoid the illusion that it could work.  Also,
 >> as you can see with the 'pos' case, some work must be done _before_
 >> calling `delete-window-internal' so the actual work would have to be
 >> split among two functions at least.
 >
 > The 'pos' case is an exception.  What I meant is simple cases
 > like customizing to 'get-lru-window'.

That one would have to handle the 'no-other-window' parameter.  And we
would have to mix functions and constants as customizable values which
looks queer in the customization interface.

martin






^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-06-06  7:43                                 ` martin rudalics
@ 2021-06-06 20:47                                   ` Juri Linkov
  2021-06-07  7:35                                     ` martin rudalics
  0 siblings, 1 reply; 24+ messages in thread
From: Juri Linkov @ 2021-06-06 20:47 UTC (permalink / raw)
  To: martin rudalics; +Cc: Lars Ingebrigtsen, 47300

>>> In general, just plugging in some existing function would usually fail
>>> here and I would like to avoid the illusion that it could work.  Also,
>>> as you can see with the 'pos' case, some work must be done _before_
>>> calling `delete-window-internal' so the actual work would have to be
>>> split among two functions at least.
>>
>> The 'pos' case is an exception.  What I meant is simple cases
>> like customizing to 'get-lru-window'.
>
> That one would have to handle the 'no-other-window' parameter.  And we
> would have to mix functions and constants as customizable values which
> looks queer in the customization interface.

The customization interface could use only functions that could be
first called before deletion, then the customized function returns
a lambda that will be called after deletion.  Then for example
all 'pos' logic could be moved to a separate function:

(defun delete-window-pos ()
  (let ((frame-selected-window-edges (window-edges frame-selected-window nil nil t))
        (frame-selected-window-pos (nth 2 (posn-at-point nil frame-selected-window))))
    (lambda ()
      (let ((new-frame-selected-window
	     (window-at-pos
              (+ (nth 0 frame-selected-window-edges)
                 (car frame-selected-window-pos))
              (+ (nth 1 frame-selected-window-edges)
                 (cdr frame-selected-window-pos))
              frame t)))
        (and new-frame-selected-window
             ;; Select window at WINDOW's position at point.
	     (set-frame-selected-window
              frame new-frame-selected-window))))))





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-06-06 20:47                                   ` Juri Linkov
@ 2021-06-07  7:35                                     ` martin rudalics
  2021-06-07 21:00                                       ` Juri Linkov
  0 siblings, 1 reply; 24+ messages in thread
From: martin rudalics @ 2021-06-07  7:35 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Lars Ingebrigtsen, 47300

 > The customization interface could use only functions that could be
 > first called before deletion, then the customized function returns
 > a lambda that will be called after deletion.

Only specialized users would be able to write such a function. And they
can use the 'delete-window' parameter for that purpose.

 > Then for example
 > all 'pos' logic could be moved to a separate function:
 >
 > (defun delete-window-pos ()
 >    (let ((frame-selected-window-edges (window-edges frame-selected-window nil nil t))
 >          (frame-selected-window-pos (nth 2 (posn-at-point nil frame-selected-window))))
 >      (lambda ()
 >        (let ((new-frame-selected-window
 > 	     (window-at-pos
 >                (+ (nth 0 frame-selected-window-edges)
 >                   (car frame-selected-window-pos))
 >                (+ (nth 1 frame-selected-window-edges)
 >                   (cdr frame-selected-window-pos))
 >                frame t)))
 >          (and new-frame-selected-window
 >               ;; Select window at WINDOW's position at point.
 > 	     (set-frame-selected-window
 >                frame new-frame-selected-window))))))

I'm completely lost with the scoping of that first `let'.  So at least
for a poor soul like me such a solution would not be feasible at all.

martin





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-06-07  7:35                                     ` martin rudalics
@ 2021-06-07 21:00                                       ` Juri Linkov
  2021-06-10  7:44                                         ` martin rudalics
  0 siblings, 1 reply; 24+ messages in thread
From: Juri Linkov @ 2021-06-07 21:00 UTC (permalink / raw)
  To: martin rudalics; +Cc: Lars Ingebrigtsen, 47300

>> The customization interface could use only functions that could be
>> first called before deletion, then the customized function returns
>> a lambda that will be called after deletion.
>
> Only specialized users would be able to write such a function. And they
> can use the 'delete-window' parameter for that purpose.

Then I'm not a specialized user because I didn't know about
the 'delete-window' parameter :-)

> I'm completely lost with the scoping of that first `let'.  So at least
> for a poor soul like me such a solution would not be feasible at all.

A lambda was just an example.  But constants like in your previous patch
are fine.  So you could just push it when you want.





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-06-07 21:00                                       ` Juri Linkov
@ 2021-06-10  7:44                                         ` martin rudalics
  2021-06-11 17:06                                           ` Juri Linkov
  0 siblings, 1 reply; 24+ messages in thread
From: martin rudalics @ 2021-06-10  7:44 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Lars Ingebrigtsen, 47300

 > A lambda was just an example.  But constants like in your previous patch
 > are fine.  So you could just push it when you want.

Pushed now.  Feel free to change it if you have better ideas.

Thanks, martin





^ permalink raw reply	[flat|nested] 24+ messages in thread

* bug#47300: delete-window to select window with same position
  2021-06-10  7:44                                         ` martin rudalics
@ 2021-06-11 17:06                                           ` Juri Linkov
  0 siblings, 0 replies; 24+ messages in thread
From: Juri Linkov @ 2021-06-11 17:06 UTC (permalink / raw)
  To: martin rudalics; +Cc: Lars Ingebrigtsen, 47300

tags 47300 fixed
close 47300 28.0.50
thanks

> Pushed now.  Feel free to change it if you have better ideas.

Thank you for implementing this useful feature.
The name proposed by Eli is also good.
So this request could be closed now.

PS: I propose one additional tiny change - maybe would be better
to add for @code{delete-window-choose-selected} a xref
or pxref from the "Change Window" node of the User Manual
to the Lisp Reference Manual (there are already many
references to elisp in emacs/windows.texi.)





^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2021-06-11 17:06 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-03-21 20:31 bug#47300: delete-window to select window with same position Juri Linkov
2021-05-18 14:49 ` Lars Ingebrigtsen
2021-05-18 16:00   ` martin rudalics
2021-05-18 20:17     ` Juri Linkov
2021-05-19  7:42       ` martin rudalics
2021-05-19 16:07         ` Juri Linkov
2021-05-19 17:41           ` martin rudalics
2021-05-22  8:05             ` martin rudalics
2021-05-22 21:25               ` Juri Linkov
2021-05-23  8:43                 ` martin rudalics
2021-05-25  6:50                 ` martin rudalics
2021-05-26 21:29                   ` Juri Linkov
2021-05-27 15:20                     ` martin rudalics
2021-05-31 20:46                       ` Juri Linkov
2021-06-02  9:08                         ` martin rudalics
2021-06-03 21:20                           ` Juri Linkov
2021-06-04  9:19                             ` martin rudalics
2021-06-04 16:29                               ` Juri Linkov
2021-06-06  7:43                                 ` martin rudalics
2021-06-06 20:47                                   ` Juri Linkov
2021-06-07  7:35                                     ` martin rudalics
2021-06-07 21:00                                       ` Juri Linkov
2021-06-10  7:44                                         ` martin rudalics
2021-06-11 17:06                                           ` Juri Linkov

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.