unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: martin rudalics via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: Juri Linkov <juri@linkov.net>
Cc: daniel.c.mccarthy@gmail.com, Eli Zaretskii <eliz@gnu.org>,
	68235@debbugs.gnu.org
Subject: bug#68235: 29.1.90; Switching tabs stops following process output in selected window
Date: Sat, 20 Jan 2024 10:44:51 +0100	[thread overview]
Message-ID: <4bc98faf-5ebe-4c22-8c9f-04755785fde5@gmx.at> (raw)
In-Reply-To: <86v87qpow0.fsf@mail.linkov.net>

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

 > This looks promising.

I attach a patch.  Note that in my Emacs, window configurations are much
more lightweight so I cannot reliably test it.  You would have to do all
the testing yourself.

 > One thing I don't understand is how to get
 > the previously visited file name from this list of four entries?

But it's still there in the dead buffer (the only things that can get
collected as long as a window is in a tab are the previous and next
buffers shown in that window).  Try the scenario below, using some
suitable file as argument to 'find-file-noselect'.

(defun foo (frame windows)
   (while windows
     (let* ((quad (car windows))
	   (window (car quad))
	   (buffer (find-file-noselect
		    (buffer-file-name (nth 1 quad)))))
       (when buffer
	(set-window-buffer window buffer)
	(set-window-point window (nth 3 quad))
	(set-window-start window (nth 2 quad) t)))
     (setq windows (cdr windows))))

(add-hook 'post-set-window-configuration-functions 'foo)

(let ((window (selected-window))
       (buffer (pop-to-buffer
	       (find-file-noselect "...")))
       (window-1 (split-window))
       (window-2 (split-window nil nil t))
       configuration)
   (set-window-point window-1 5000)
   (set-window-point window-2 10000)
   (setq configuration (current-window-configuration))
   (y-or-n-p "Configuration saved ...")
   (delete-other-windows window)
   (kill-buffer buffer)
   (y-or-n-p "Configuration reset ...")
   (set-window-configuration configuration nil nil t)
   (message "Configuration restored"))

Note that window point and start are stored as positions and not as
markers which means that if you modify the buffer after the call of
'current-window-configuration', they may not be accurate any more.

One could try to get their last position before the buffer was deleted
but that would mean to give ‘marker-position’ an extra argument to omit
the

   if (XMARKER (marker)->buffer)

check with some "use at your own risk" caveats ('marker-buffer' at the
same time would still have to return nil).

martin

[-- Attachment #2: keep-windows.diff --]
[-- Type: text/x-patch, Size: 8862 bytes --]

diff --git a/src/keyboard.c b/src/keyboard.c
index e1d738dd6ef..b6ba3c57ff8 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -2281,7 +2281,7 @@ read_char_help_form_unwind (void)
   Lisp_Object window_config = XCAR (help_form_saved_window_configs);
   help_form_saved_window_configs = XCDR (help_form_saved_window_configs);
   if (!NILP (window_config))
-    Fset_window_configuration (window_config, Qnil, Qnil);
+    Fset_window_configuration (window_config, Qnil, Qnil, Qnil);
 }
 
 #define STOP_POLLING					\
diff --git a/src/window.c b/src/window.c
index 3a54f7ce7b1..c33b987c24f 100644
--- a/src/window.c
+++ b/src/window.c
@@ -7037,6 +7037,7 @@ DEFUN ("move-to-window-line", Fmove_to_window_line, Smove_to_window_line,
   union vectorlike_header header;
 
   Lisp_Object window, buffer, start, pointm, old_pointm;
+  Lisp_Object start_pos, pointm_pos;
   Lisp_Object pixel_left, pixel_top, pixel_height, pixel_width;
   Lisp_Object left_col, top_line, total_cols, total_lines;
   Lisp_Object normal_cols, normal_lines;
@@ -7079,7 +7080,7 @@ DEFUN ("window-configuration-frame", Fwindow_configuration_frame, Swindow_config
 }
 
 DEFUN ("set-window-configuration", Fset_window_configuration,
-       Sset_window_configuration, 1, 3, 0,
+       Sset_window_configuration, 1, 4, 0,
        doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION.
 CONFIGURATION must be a value previously returned
 by `current-window-configuration' (which see).
@@ -7090,16 +7091,35 @@ DEFUN ("set-window-configuration", Fset_window_configuration,
 the mini-window of the frame doesn't get set to the corresponding element
 of CONFIGURATION.
 
+Normally, this function will try to delete any dead window in
+CONFIGURATION whose buffer has been deleted since CONFIGURATION was
+made.  However, if KEEP-WINDOWS is non-nil, it will preserve such a
+window in the restored layout and show another buffer in it.
+
+After restoring the frame layout, this function runs the abnormal hook
+'post-set-window-configuration-functions' with two arguments - the frame
+whose layout is has restored and, provided KEEP-WINDOWS is non-nil, a
+list of entries for each window whose buffer has been found dead when it
+tried to restore CONFIGURATION: Each entry is a list of four elements
+<window, buffer, start, point> where `window' denotes the window whose
+buffer was found dead, `buffer' denotes the dead buffer, and `start' and
+`point' denote the positions of `window-start' and `window-point' of
+that window at the time CONFIGURATION was made. Note that these
+positions are no markers and may be no more accurate if the buffer has
+been modified afterwards.  If KEEP-WINDOWS is nil, the second argument
+is nil.
+
 If CONFIGURATION was made from a frame that is now deleted,
 only frame-independent values can be restored.  In this case,
 the return value is nil.  Otherwise the value is t.  */)
   (Lisp_Object configuration, Lisp_Object dont_set_frame,
-   Lisp_Object dont_set_miniwindow)
+   Lisp_Object dont_set_miniwindow, Lisp_Object keep_windows)
 {
   register struct save_window_data *data;
   struct Lisp_Vector *saved_windows;
   Lisp_Object new_current_buffer;
   Lisp_Object frame;
+  Lisp_Object kept_windows = Qnil;
   Lisp_Object old_frame = selected_frame;
   struct frame *f;
   ptrdiff_t old_point = -1;
@@ -7340,6 +7360,10 @@ DEFUN ("set-window-configuration", Fset_window_configuration,
 		   BUF_PT (XBUFFER (w->contents)),
 		   BUF_PT_BYTE (XBUFFER (w->contents)));
 	      w->start_at_line_beg = true;
+	      if (!NILP (keep_windows))
+		kept_windows = Fcons (list4 (window, p->buffer,
+					     p->start_pos, p->pointm_pos),
+				      kept_windows);
 	    }
 	  else if (!NILP (w->start))
 	    /* Leaf window has no live buffer, get one.  */
@@ -7360,6 +7384,10 @@ DEFUN ("set-window-configuration", Fset_window_configuration,
 		dead_windows = Fcons (window, dead_windows);
 	      /* Make sure window is no more dedicated.  */
 	      wset_dedicated (w, Qnil);
+	      if (!NILP (keep_windows))
+		kept_windows = Fcons (list4 (window, p->buffer,
+					     p->start_pos, p->pointm_pos),
+				      kept_windows);
 	    }
 	}
 
@@ -7411,12 +7439,13 @@ DEFUN ("set-window-configuration", Fset_window_configuration,
       unblock_input ();
 
       /* Scan dead buffer windows.  */
-      for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
-	{
-	  window = XCAR (dead_windows);
-	  if (WINDOW_LIVE_P (window) && !EQ (window, FRAME_ROOT_WINDOW (f)))
-	    delete_deletable_window (window);
-	}
+      if (NILP (keep_windows))
+	for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows))
+	  {
+	    window = XCAR (dead_windows);
+	    if (WINDOW_LIVE_P (window) && !EQ (window, FRAME_ROOT_WINDOW (f)))
+	      delete_deletable_window (window);
+	  }
 
       /* Record the selected window's buffer here.  The window should
 	 already be the selected one from the call above.  */
@@ -7463,6 +7492,11 @@ DEFUN ("set-window-configuration", Fset_window_configuration,
   minibuf_selected_window = data->minibuf_selected_window;
 
   SAFE_FREE ();
+
+  if (!NILP (Vrun_hooks) && !NILP (Vpost_set_window_configuration_functions))
+    run_hook_with_args_2 (Qpost_set_window_configuration_functions, frame,
+			  kept_windows);
+
   return FRAME_LIVE_P (f) ? Qt : Qnil;
 }
 
@@ -7472,12 +7506,12 @@ restore_window_configuration (Lisp_Object configuration)
   if (CONSP (configuration))
     Fset_window_configuration (XCAR (configuration),
 			       Fcar_safe (XCDR (configuration)),
-			       Fcar_safe (Fcdr_safe (XCDR (configuration))));
+			       Fcar_safe (Fcdr_safe (XCDR (configuration))),
+			       Qnil);
   else
-    Fset_window_configuration (configuration, Qnil, Qnil);
+    Fset_window_configuration (configuration, Qnil, Qnil, Qnil);
 }
 
-
 /* If WINDOW is an internal window, recursively delete all child windows
    reachable via the next and contents slots of WINDOW.  Otherwise setup
    WINDOW to not show any buffer.  */
@@ -7685,16 +7719,24 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, ptrdiff_t i)
 	     is the selected window, then get the value of point from
 	     the buffer; pointm is garbage in the selected window.  */
 	  if (EQ (window, selected_window))
-	    p->pointm = build_marker (XBUFFER (w->contents),
-				      BUF_PT (XBUFFER (w->contents)),
-				      BUF_PT_BYTE (XBUFFER (w->contents)));
+	    {
+	      p->pointm = build_marker (XBUFFER (w->contents),
+					BUF_PT (XBUFFER (w->contents)),
+					BUF_PT_BYTE (XBUFFER (w->contents)));
+	      p->pointm_pos = make_fixnum (BUF_PT (XBUFFER (w->contents)));
+	    }
 	  else
-	    p->pointm = Fcopy_marker (w->pointm, Qnil);
+	    {
+	      p->pointm = Fcopy_marker (w->pointm, Qnil);
+	      p->pointm_pos = make_fixnum (marker_position (w->pointm));
+	    }
+
 	  p->old_pointm = Fcopy_marker (w->old_pointm, Qnil);
 	  XMARKER (p->pointm)->insertion_type = window_point_insertion_type;
 	  XMARKER (p->old_pointm)->insertion_type = window_point_insertion_type;
 
 	  p->start = Fcopy_marker (w->start, Qnil);
+	  p->start_pos = make_fixnum (marker_position (w->start));
 	  p->start_at_line_beg = w->start_at_line_beg ? Qt : Qnil;
 	}
       else
@@ -8460,6 +8502,8 @@ syms_of_window (void)
   DEFSYM (Qheader_line_format, "header-line-format");
   DEFSYM (Qtab_line_format, "tab-line-format");
   DEFSYM (Qno_other_window, "no-other-window");
+  DEFSYM (Qpost_set_window_configuration_functions,
+	  "post-set-window-configuration-functions");
 
   DEFVAR_LISP ("temp-buffer-show-function", Vtemp_buffer_show_function,
 	       doc: /* Non-nil means call as function to display a help buffer.
@@ -8617,6 +8661,21 @@ syms_of_window (void)
 call is performed with the frame temporarily selected.  */);
   Vwindow_configuration_change_hook = Qnil;
 
+  DEFVAR_LISP ("post-set-window-configuration-functions",
+	       Vpost_set_window_configuration_functions,
+	       doc: /* Functions called after restoring a window configuration.
+The value should be a list of functions that take two arguments.
+
+This function is called by `set-window-configuration' after it has
+restored the layout of a frame.  The first argument specifies the frame
+whose configuration has been restored.  The second argument, if non-nil,
+specifies a list of entries for each window whose buffer has been found
+dead at the time 'set-window-configuration' tried to restore it in that
+window.  Each entry is a list of four values - the window whose buffer
+was found dead, the dead buffer, and the positions of start and point of
+the buffer in that window.  */);
+  Vpost_set_window_configuration_functions = Qnil;
+
   DEFVAR_LISP ("recenter-redisplay", Vrecenter_redisplay,
 	       doc: /* Non-nil means `recenter' redraws entire frame.
 If this option is non-nil, then the `recenter' command with a nil

  reply	other threads:[~2024-01-20  9:44 UTC|newest]

Thread overview: 85+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-03 20:48 bug#68235: 29.1.90; Switching tabs stops following process output in selected window Dan McCarthy
2024-01-04  6:09 ` Eli Zaretskii
2024-01-04 10:23   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-01-04 10:42     ` Eli Zaretskii
2024-01-04 17:07     ` Juri Linkov
2024-01-04 17:48       ` Eli Zaretskii
2024-01-05  9:24         ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-01-06 17:36           ` Juri Linkov
2024-01-07 14:54             ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-01-07 16:45               ` Juri Linkov
2024-01-08  8:55                 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-01-09 17:23                   ` Juri Linkov
2024-01-07 16:49               ` Juri Linkov
2024-01-09 17:25                 ` Juri Linkov
2024-01-10  8:37                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-01-10 17:08                     ` Juri Linkov
2024-01-11  9:14                       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-01-12  7:37                         ` Juri Linkov
2024-01-13 10:38                           ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-01-13 15:02                             ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-01-13 18:20                               ` Juri Linkov
2024-01-14  8:13                                 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-01-14 18:53                                   ` Juri Linkov
2024-01-15 10:24                                     ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-01-15 17:53                                       ` Juri Linkov
2024-01-16 10:19                                         ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-01-16 16:30                                           ` Juri Linkov
2024-01-17 11:42                                             ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-01-17 16:36                                               ` Juri Linkov
2024-01-18 10:47                                                 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-01-18 16:50                                                   ` Juri Linkov
2024-01-20  9:44                                                     ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors [this message]
2024-01-22  7:43                                                       ` Juri Linkov
2024-01-23  9:30                                                         ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-01-24  7:54                                                           ` Juri Linkov
2024-01-25  9:39                                                             ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-01-25 17:46                                                               ` Juri Linkov
2024-01-26  9:56                                                                 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-01-27 17:58                                                                   ` Juri Linkov
2024-01-28 10:06                                                                     ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-02-05  7:17                                                       ` Juri Linkov
2024-02-06 10:34                                                         ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-02-06 18:03                                                           ` Juri Linkov
2024-02-15  7:34                                                           ` Juri Linkov
2024-02-16  9:40                                                             ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-02-18  7:35                                                               ` Juri Linkov
2024-02-19  9:42                                                                 ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-02-20 17:44                                                                   ` Juri Linkov
2024-03-04  9:40                                                                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-05 17:27                                                                     ` Juri Linkov
2024-03-05 17:45                                                                       ` Eli Zaretskii
2024-03-06 18:03                                                                         ` Juri Linkov
2024-03-09  8:35                                                                           ` Eli Zaretskii
2024-03-17 17:57                                                                             ` Juri Linkov
2024-03-05 17:37                                                                     ` Juri Linkov
2024-03-06 10:19                                                                       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-06 17:57                                                                         ` Juri Linkov
2024-03-08  9:21                                                                           ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-10 17:23                                                                             ` Juri Linkov
2024-03-11  9:13                                                                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-09  6:53                                                                                 ` Juri Linkov
2024-04-09  7:36                                                                                   ` Eli Zaretskii
2024-04-09  9:22                                                                                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-09 16:40                                                                                     ` Juri Linkov
2024-04-10  8:47                                                                                       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-10 17:35                                                                                         ` Juri Linkov
2024-04-11  9:16                                                                                           ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-12  6:30                                                                                             ` Juri Linkov
2024-04-12  8:18                                                                                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-12 16:20                                                                                                 ` Juri Linkov
2024-04-15  9:21                                                                                                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-21  6:59                                                                                                     ` Juri Linkov
2024-04-21  8:56                                                                                                       ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-04-22  6:46                                                                                                         ` Juri Linkov
2024-04-21  9:27                                                                                                       ` Eli Zaretskii
2024-04-22  6:40                                                                                                         ` Juri Linkov
2024-04-22  7:00                                                                                                           ` Eli Zaretskii
2024-04-22 16:36                                                                                                             ` Juri Linkov
2024-04-22 19:22                                                                                                               ` Eli Zaretskii
2024-03-15  9:38                                                                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-17 17:47                                                                                 ` Juri Linkov
2024-03-18 10:13                                                                                   ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-03-15 10:11                                                                             ` Andreas Schwab
2024-03-15 10:56                                                                               ` martin rudalics via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-02-04 17:27                       ` Juri Linkov

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=4bc98faf-5ebe-4c22-8c9f-04755785fde5@gmx.at \
    --to=bug-gnu-emacs@gnu.org \
    --cc=68235@debbugs.gnu.org \
    --cc=daniel.c.mccarthy@gmail.com \
    --cc=eliz@gnu.org \
    --cc=juri@linkov.net \
    --cc=rudalics@gmx.at \
    /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).