From: martin rudalics <rudalics@gmx.at>
To: Eli Zaretskii <eliz@gnu.org>
Cc: pranshusharma366@gmail.com, emacs-devel@gnu.org
Subject: Re: Add function to rotate/transpose all windows
Date: Fri, 27 Sep 2024 19:29:21 +0200 [thread overview]
Message-ID: <3d4546ac-70d9-4865-b42d-0dc50cb0f3a7@gmx.at> (raw)
In-Reply-To: <86o74aa41b.fsf@gnu.org>
[-- Attachment #1: Type: text/plain, Size: 831 bytes --]
> This doc string needs to be more detailed in what it means to "put the
> window object of DEAD in the place of LIVE". For example, it
> currently keeps silent about what happens to LIVE after the call.
The fact that LIVE existed at all was a misfeature. I now put the dead
window right into the new window created by 'split-window' with the help
of a new argument. Patch attached. Tested with
(let ((dead (split-window nil nil t)))
(set-window-buffer dead "*Messages*")
(message "%s" (next-window))
(sit-for 2)
(delete-window dead)
(let ((live (split-window nil nil nil nil dead)))
(message "%s" (next-window))))
> Finally, this needs to be documented in the ELisp manual and called
> out in NEWS.
Sure. I'll wait until the OP approves the concept and was able to make
use of it.
Thanks, martin
[-- Attachment #2: resurrect.diff --]
[-- Type: text/x-patch, Size: 12834 bytes --]
diff --git a/lisp/window.el b/lisp/window.el
index 07ea9584908..b96a7863a72 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -5509,7 +5509,7 @@ window--combination-resizable
(setq sibling (window-next-sibling sibling)))
(/ size (1+ number))))
-(defun split-window (&optional window size side pixelwise)
+(defun split-window (&optional window size side pixelwise refer)
"Make a new window adjacent to WINDOW.
WINDOW must be a valid window and defaults to the selected one.
Return the new window which is always a live window.
@@ -5552,11 +5552,21 @@ split-window
root of that atomic window. The new window does not become a
member of that atomic window.
-If WINDOW is live, properties of the new window like margins and
-scrollbars are inherited from WINDOW. If WINDOW is an internal
-window, these properties as well as the buffer displayed in the
-new window are inherited from the window selected on WINDOW's
-frame. The selected window is not changed by this function."
+If the optional fifth argument REFER is non-nil, it has to denote a
+dead, former live window on the same frame as OLD or an arbitrary live
+window. In the first case, REFER will become the new window with
+properties like buffer, start and point, decorations and parameters as
+to the last time when it was live. In the latter case the new window
+will inherit properties like buffer, start and point, decorations and
+parameters from REFER.
+
+If REFER is nil or omitted, then if WINDOW is live, any such properties
+are inherited from WINDOW. If, however, WINDOW is an internal window,
+the new window will inherit these properties from the window selected on
+WINDOW's frame.
+
+The selected window and the selected window on WINDOW's frame are
+not changed by this function."
(setq window (window-normalize-window window))
(let* ((side (cond
((not side) 'below)
@@ -5596,7 +5606,7 @@ split-window
((and (window-parameter window 'window-atom)
(setq atom-root (window-atom-root window))
(not (eq atom-root window)))
- (throw 'done (split-window atom-root size side pixelwise)))
+ (throw 'done (split-window atom-root size side pixelwise refer)))
;; If WINDOW is a side window or its first or last child is a
;; side window, throw an error unless `window-combination-resize'
;; equals 'side.
@@ -5635,8 +5645,8 @@ split-window
(window-combined-p window horizontal)))
;; 'old-pixel-size' is the current pixel size of WINDOW.
(old-pixel-size (window-size window horizontal t))
- ;; 'new-size' is the specified or calculated size of the
- ;; new window.
+ ;; 'new-pixel-size' is the specified or calculated size
+ ;; of the new window.
new-pixel-size new-parent new-normal)
(cond
((not pixel-size)
@@ -5757,8 +5767,9 @@ split-window
window (- (if new-parent 1.0 (window-normal-size window horizontal))
new-normal)))
- (let* ((new (split-window-internal window new-pixel-size side new-normal)))
- (window--pixel-to-total frame horizontal)
+ (let ((new (split-window-internal
+ window new-pixel-size side new-normal refer)))
+ (window--pixel-to-total frame horizontal)
;; Assign window-side parameters, if any.
(cond
((eq window-combination-resize 'side)
diff --git a/src/window.c b/src/window.c
index 34968ac824f..402bb0459e3 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5073,7 +5073,7 @@ resize_frame_windows (struct frame *f, int size, bool horflag)
}
-DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 4, 0,
+DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal, 4, 5, 0,
doc: /* Split window OLD.
Second argument PIXEL-SIZE specifies the number of pixels of the
new window. It must be a positive integer.
@@ -5088,32 +5088,30 @@ DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal,
the right side of WINDOW. SIDE `left' means the new window shall be
located on the left of WINDOW. In both cases PIXEL-SIZE specifies the
width of the new window including space reserved for fringes and the
-scrollbar or a divider column.
+scroll bar or a divider column.
Fourth argument NORMAL-SIZE specifies the normal size of the new window
-according to the SIDE argument.
+according to the SIDE argument. Optional fifth argument REFER is as for
+'split-window'.
The new pixel and normal sizes of all involved windows must have been
set correctly. See the code of `split-window' for how this is done. */)
- (Lisp_Object old, Lisp_Object pixel_size, Lisp_Object side, Lisp_Object normal_size)
+ (Lisp_Object old, Lisp_Object pixel_size, Lisp_Object side, Lisp_Object normal_size,
+ Lisp_Object refer)
{
/* OLD (*o) is the window we have to split. (*p) is either OLD's
parent window or an internal window we have to install as OLD's new
- parent. REFERENCE (*r) must denote a live window, or is set to OLD
- provided OLD is a leaf window, or to the frame's selected window.
- NEW (*n) is the new window created with some parameters taken from
- REFERENCE (*r). */
- Lisp_Object new, frame, reference;
- struct window *o, *p, *n, *r, *c;
- struct frame *f;
+ parent. NEW (*n) is the new window created or adopted with
+ properties from REFER (*r), if specified. */
+ struct window *o = decode_valid_window (old);
+ Lisp_Object frame = WINDOW_FRAME (o);
+ struct frame *f = XFRAME (frame);
+ struct window *p, *n, *r, *c;
bool horflag
/* HORFLAG is true when we split side-by-side, false otherwise. */
= EQ (side, Qt) || EQ (side, Qleft) || EQ (side, Qright);
-
- CHECK_WINDOW (old);
- o = XWINDOW (old);
- frame = WINDOW_FRAME (o);
- f = XFRAME (frame);
+ Lisp_Object new;
+ bool dead = false;
CHECK_FIXNUM (pixel_size);
EMACS_INT total_size
@@ -5131,14 +5129,38 @@ DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal,
? WINDOW_VERTICAL_COMBINATION_P (XWINDOW (o->parent))
: WINDOW_HORIZONTAL_COMBINATION_P (XWINDOW (o->parent))));
- /* We need a live reference window to initialize some parameters. */
- if (WINDOW_LIVE_P (old))
- /* OLD is live, use it as reference window. */
- reference = old;
+ /* Set up reference window. */
+ if (NILP (refer))
+ {
+ if (WINDOW_LIVE_P (old))
+ /* OLD is live, use it as reference window. */
+ refer = old;
+ else
+ /* Use the frame's selected window as reference window. */
+ refer = FRAME_SELECTED_WINDOW (f);
+
+ r = XWINDOW (refer);
+ }
else
- /* Use the frame's selected window as reference window. */
- reference = FRAME_SELECTED_WINDOW (f);
- r = XWINDOW (reference);
+ {
+ r = decode_any_window (refer);
+
+ if (NILP (r->contents))
+ /* Presumably a dead, former live window. Check whether its
+ content can be used. */
+ {
+ if (!BUFFERP (r->old_buffer))
+ error ("Dead reference window was not a live window");
+ else if (!BUFFER_LIVE_P (XBUFFER (r->old_buffer)))
+ error ("Dead reference window's old buffer is dead");
+ else if (!EQ (r->frame, frame))
+ error ("Dead referenec window was on other frame");
+
+ dead = true;
+ }
+ else if (!WINDOW_LIVE_P (refer))
+ error ("Reference window must not be internal");
+ }
/* The following bugs are caught by `split-window'. */
if (MINI_WINDOW_P (o))
@@ -5195,7 +5217,12 @@ DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal,
p = XWINDOW (o->parent);
fset_redisplay (f);
- new = make_window ();
+
+ if (dead)
+ new = refer;
+ else
+ new = make_window ();
+
n = XWINDOW (new);
wset_frame (n, frame);
wset_parent (n, o->parent);
@@ -5219,19 +5246,22 @@ DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal,
wset_next (o, new);
}
- n->window_end_valid = false;
- n->last_cursor_vpos = 0;
+ if (!dead)
+ {
+ n->window_end_valid = false;
+ n->last_cursor_vpos = 0;
- /* Get special geometry settings from reference window. */
- n->left_margin_cols = r->left_margin_cols;
- n->right_margin_cols = r->right_margin_cols;
- n->left_fringe_width = r->left_fringe_width;
- n->right_fringe_width = r->right_fringe_width;
- n->fringes_outside_margins = r->fringes_outside_margins;
- n->scroll_bar_width = r->scroll_bar_width;
- n->scroll_bar_height = r->scroll_bar_height;
- wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type);
- wset_horizontal_scroll_bar_type (n, r->horizontal_scroll_bar_type);
+ /* Get special geometry settings from reference window. */
+ n->left_margin_cols = r->left_margin_cols;
+ n->right_margin_cols = r->right_margin_cols;
+ n->left_fringe_width = r->left_fringe_width;
+ n->right_fringe_width = r->right_fringe_width;
+ n->fringes_outside_margins = r->fringes_outside_margins;
+ n->scroll_bar_width = r->scroll_bar_width;
+ n->scroll_bar_height = r->scroll_bar_height;
+ wset_vertical_scroll_bar_type (n, r->vertical_scroll_bar_type);
+ wset_horizontal_scroll_bar_type (n, r->horizontal_scroll_bar_type);
+ }
/* Directly assign orthogonal coordinates and sizes. */
if (horflag)
@@ -5267,10 +5297,44 @@ DEFUN ("split-window-internal", Fsplit_window_internal, Ssplit_window_internal,
wset_new_normal (n, normal_size);
block_input ();
+
+ if (dead)
+ {
+ /* Get dead window back its old buffer and markers. */
+ wset_buffer (n, n->old_buffer);
+ Fset_marker (n->start, make_fixnum (n->del_start), n->contents);
+ Fset_marker (n->pointm, make_fixnum (n->del_pointm), n->contents);
+ Vwindow_list = Qnil;
+ }
+ else
+ {
+ /* Note: n->contents is Qnil throughout this call, so n will be
+ neither considered a leaf nor an internal window. */
+ Lisp_Object buffer = r->contents;
+ struct buffer *b = XBUFFER (buffer);
+
+ /* Provisorially set new's buffer to that of the reference window,
+ resize the parent, reset new's buffer to nil and do the real
+ set_window_buffer. */
+ wset_buffer (n, buffer);
+ set_marker_both (n->pointm, buffer, BUF_PT (b), BUF_PT_BYTE (b));
+ set_marker_restricted
+ (n->start, make_fixnum (b->last_window_start), buffer);
+ }
+
window_resize_apply (p, horflag);
+
+ if (!dead)
+ {
+ /* Set buffer of NEW to buffer of reference window. We have to do it
+ here so the sizes of NEW are in place. But be sure to do it before
+ adjusting the frame glyphs - otherwise Emacs may inexplicably loop
+ forever. */
+ wset_buffer (n, Qnil);
+ set_window_buffer (new, r->contents, true, true);
+ }
+
adjust_frame_glyphs (f);
- /* Set buffer of NEW to buffer of reference window. */
- set_window_buffer (new, r->contents, true, true);
FRAME_WINDOW_CHANGE (f) = true;
unblock_input ();
@@ -5368,10 +5432,16 @@ DEFUN ("delete-window-internal", Fdelete_window_internal, Sdelete_window_interna
}
else
{
+ if (MARKERP (w->pointm))
+ w->del_pointm = marker_position (w->pointm);
+ if (MARKERP (w->start))
+ w->del_start = marker_position (w->start);
+
unshow_buffer (w);
unchain_marker (XMARKER (w->pointm));
unchain_marker (XMARKER (w->old_pointm));
unchain_marker (XMARKER (w->start));
+ wset_old_buffer (w, w->contents);
wset_buffer (w, Qnil);
/* Add WINDOW to table of dead windows so when killing a buffer
WINDOW mentions, all references to that buffer can be removed
@@ -7712,6 +7782,11 @@ delete_all_child_windows (Lisp_Object window)
}
else if (BUFFERP (w->contents))
{
+ if (MARKERP (w->pointm))
+ w->del_pointm = marker_position (w->pointm);
+ if (MARKERP (w->start))
+ w->del_start = marker_position (w->start);
+
unshow_buffer (w);
unchain_marker (XMARKER (w->pointm));
unchain_marker (XMARKER (w->old_pointm));
@@ -7720,6 +7795,7 @@ delete_all_child_windows (Lisp_Object window)
only, we use this slot to save the buffer for the sake of
possible resurrection in Fset_window_configuration. */
wset_combination_limit (w, w->contents);
+ wset_old_buffer (w, w->contents);
wset_buffer (w, Qnil);
/* Add WINDOW to table of dead windows so when killing a buffer
WINDOW mentions, all references to that buffer can be removed
diff --git a/src/window.h b/src/window.h
index 335e0a3453e..41ee7f6dc18 100644
--- a/src/window.h
+++ b/src/window.h
@@ -264,6 +264,10 @@ #define WINDOW_H_INCLUDED
int total_cols;
int total_lines;
+ /* Positions of pointm and start when window was deleted. */
+ ptrdiff_t del_pointm;
+ ptrdiff_t del_start;
+
/* Number of columns display within the window is scrolled to the left. */
ptrdiff_t hscroll;
next prev parent reply other threads:[~2024-09-27 17:29 UTC|newest]
Thread overview: 144+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-24 13:45 Add function to rotate/transpose all windows pranshu sharma
2024-09-24 13:53 ` Eli Zaretskii
2024-09-25 8:05 ` martin rudalics
2024-09-25 8:34 ` pranshu sharma
2024-09-25 9:31 ` martin rudalics
2024-09-25 10:50 ` pranshu sharma
2024-09-25 13:53 ` martin rudalics
2024-09-25 15:31 ` pranshu sharma
2024-09-26 14:10 ` martin rudalics
2024-09-26 14:22 ` Eli Zaretskii
2024-09-27 17:29 ` martin rudalics [this message]
2024-09-28 7:52 ` pranshu sharma
2024-09-28 9:26 ` martin rudalics
2024-09-28 10:53 ` pranshu sharma
2024-09-28 14:48 ` martin rudalics
2024-09-29 7:36 ` pranshu sharma
2024-09-29 8:40 ` martin rudalics
2024-09-29 9:23 ` pranshu sharma
2024-09-29 14:48 ` martin rudalics
2024-09-30 6:29 ` pranshu sharma
2024-09-30 8:57 ` martin rudalics
2024-10-01 9:17 ` pranshu sharma
2024-10-02 9:04 ` martin rudalics
2024-10-03 7:06 ` pranshu sharma
2024-10-03 8:17 ` martin rudalics
2024-10-03 10:09 ` pranshu sharma
2024-10-03 14:18 ` martin rudalics
2024-10-04 5:50 ` pranshu sharma
2024-10-04 8:08 ` martin rudalics
2024-10-04 15:10 ` pranshu sharma
2024-10-05 14:43 ` martin rudalics
2024-10-06 2:54 ` pranshu sharma
2024-10-06 15:02 ` martin rudalics
2024-10-06 15:52 ` pranshu sharma
2024-10-07 8:33 ` martin rudalics
2024-10-07 9:42 ` pranshu sharma
2024-10-03 15:12 ` Eli Zaretskii
2024-10-08 18:35 ` Juri Linkov
2024-10-09 6:59 ` pranshu sharma
2024-10-09 16:21 ` Juri Linkov
2024-10-10 11:49 ` pranshu sharma
2024-10-10 16:57 ` Juri Linkov
2024-10-13 5:43 ` pranshu sharma
2024-10-13 8:17 ` martin rudalics
2024-10-14 17:36 ` Juri Linkov
2024-10-15 8:34 ` pranshu sharma
2024-10-15 16:16 ` Juri Linkov
2024-10-18 14:52 ` pranshu sharma
2024-10-18 17:48 ` martin rudalics
2024-10-18 18:37 ` Eli Zaretskii
2024-10-19 1:45 ` pranshu sharma
2024-10-19 6:45 ` Eli Zaretskii
2024-10-19 18:19 ` Juri Linkov
2024-10-19 8:33 ` martin rudalics
2024-10-20 8:19 ` martin rudalics
2024-10-20 14:11 ` Pranshu Sharma
2024-10-20 17:37 ` martin rudalics
2024-10-21 5:54 ` Pranshu Sharma
2024-10-21 8:14 ` martin rudalics
2024-10-21 9:23 ` martin rudalics
2024-10-21 13:37 ` Pranshu Sharma
2024-10-22 18:12 ` martin rudalics
2024-10-24 14:38 ` Pranshu Sharma
2024-10-24 18:39 ` martin rudalics
2024-10-25 14:24 ` Pranshu Sharma
2024-10-25 17:09 ` martin rudalics
2024-10-26 9:14 ` Pranshu Sharma
2024-10-27 8:23 ` martin rudalics
2024-11-02 14:06 ` Pranshu Sharma
2024-11-05 18:01 ` martin rudalics
2024-11-08 9:23 ` Pranshu Sharma
2024-11-08 10:06 ` Pranshu Sharma
2024-11-08 15:52 ` martin rudalics
2024-11-09 2:14 ` Pranshu Sharma
2024-11-09 8:48 ` martin rudalics
2024-11-08 15:52 ` martin rudalics
2024-11-09 2:09 ` Pranshu Sharma
2024-11-09 8:48 ` martin rudalics
2024-11-09 10:55 ` Pranshu Sharma
2024-11-09 18:06 ` martin rudalics
2024-11-10 10:09 ` Pranshu Sharma
2024-11-10 16:36 ` martin rudalics
2024-11-11 14:47 ` Pranshu Sharma
2024-11-11 16:55 ` martin rudalics
2024-11-12 13:50 ` Pranshu Sharma
2024-11-12 17:46 ` martin rudalics
2024-11-16 13:36 ` Pranshu Sharma
2024-11-16 16:54 ` martin rudalics
2024-11-17 2:45 ` Pranshu Sharma
2024-11-17 10:22 ` martin rudalics
2024-11-17 15:03 ` Pranshu Sharma
2024-11-17 16:38 ` martin rudalics
2024-11-18 0:37 ` Pranshu Sharma
2024-11-18 8:55 ` martin rudalics
2024-11-19 9:34 ` Pranshu Sharma
2024-11-19 17:48 ` martin rudalics
2024-11-21 14:04 ` Pranshu Sharma
2024-11-21 17:54 ` martin rudalics
2024-11-24 13:53 ` Pranshu Sharma
2024-11-26 9:49 ` martin rudalics
2024-11-26 14:14 ` Pranshu Sharma
2024-11-27 8:29 ` Pranshu Sharma
2024-11-27 9:18 ` martin rudalics
2024-11-27 14:37 ` Pranshu Sharma
2024-11-27 17:42 ` martin rudalics
2024-11-28 2:43 ` Pranshu Sharma
2024-11-28 9:28 ` martin rudalics
2024-11-28 15:18 ` Pranshu Sharma
2024-11-30 10:07 ` martin rudalics
2024-11-30 17:41 ` Juri Linkov
2024-11-30 19:01 ` martin rudalics
2024-12-01 4:13 ` Pranshu Sharma
2024-12-03 7:30 ` Juri Linkov
2024-12-03 8:25 ` martin rudalics
2024-12-01 6:41 ` Pranshu Sharma
2024-12-01 17:20 ` martin rudalics
2024-12-02 8:06 ` Pranshu Sharma
2024-12-03 8:23 ` martin rudalics
2024-12-04 15:20 ` Pranshu Sharma
2024-12-04 17:56 ` martin rudalics
2024-12-04 19:12 ` Juri Linkov
2024-12-05 14:16 ` Pranshu Sharma
2024-12-05 17:48 ` Juri Linkov
2024-12-06 4:51 ` Pranshu Sharma
2024-12-06 7:29 ` Juri Linkov
2024-12-05 14:23 ` Pranshu Sharma
2024-12-05 15:17 ` Pranshu Sharma
2024-10-14 17:32 ` Juri Linkov
2024-09-28 7:58 ` pranshu sharma
2024-09-28 8:18 ` Eli Zaretskii
2024-09-28 9:40 ` martin rudalics
2024-09-28 11:35 ` Eli Zaretskii
2024-09-28 14:58 ` martin rudalics
2024-09-28 15:28 ` Eli Zaretskii
2024-10-07 8:33 ` martin rudalics
2024-09-28 13:22 ` pranshu sharma
2024-09-28 14:21 ` Eli Zaretskii
2024-09-28 14:49 ` martin rudalics
2024-09-27 10:06 ` pranshu sharma
2024-09-27 17:29 ` martin rudalics
2024-09-24 17:40 ` Petteri Hintsanen
2024-09-24 19:34 ` Charles Choi
2024-09-25 2:00 ` Emanuel Berg
2024-09-25 7:00 ` pranshu sharma
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3d4546ac-70d9-4865-b42d-0dc50cb0f3a7@gmx.at \
--to=rudalics@gmx.at \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
--cc=pranshusharma366@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).