[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#10348: 24.0.92; Save and load window states

From: martin rudalics
Subject: bug#10348: 24.0.92; Save and load window states
Date: Wed, 28 Dec 2011 10:50:17 +0100
User-agent: Thunderbird (Windows/20090302)

I wrote a tentative patch to handle this.  Please have a look.

Thanks, martin

=== modified file 'doc/lispref/windows.texi'
--- doc/lispref/windows.texi    2011-12-13 13:37:48 +0000
+++ doc/lispref/windows.texi    2011-12-27 17:51:15 +0000
@@ -3104,9 +3104,24 @@
 @defun current-window-configuration &optional frame
 This function returns a new object representing @var{frame}'s current
 window configuration.  The default for @var{frame} is the selected
+frame.  This function copies the value of all window parameters listed
+by @code{window-persistent-parameters}, see below.
 @end defun
address@hidden window-persistent-parameters
+This variable lists all window parameters that shall be saved by
address@hidden, see above, and restored by
address@hidden, see below.  This means that the value
+of any parameter listed by this variable and changed within the body of
address@hidden is restored to its previous value when the
+window excursion exits.  Parameters not listed by this variable are left
+alone when the window excursion terminates.
+The parameters listed by this variable are treated in a similar manner
+by the functions @code{window-state-get} and @code{window-state-put},
+see below.
address@hidden defvar
 @defun set-window-configuration configuration
 This function restores the configuration of windows and buffers as
 specified by @var{configuration}, for the frame that @var{configuration}
@@ -3121,6 +3136,10 @@
 know how to tell whether the new configuration actually differs from the
 old one.
+This function restores the values of all window parameters listed by
address@hidden, see above, to their values saved in
 If the frame which @var{configuration} was saved from is dead, all this
 function does is restore the three variables @code{window-min-height},
 @code{window-min-width} and @code{minibuffer-scroll-window}. In this
@@ -3209,18 +3228,28 @@
 configuration on disk and read it back in another Emacs session the
 following two functions can be used.
address@hidden window-state-get &optional window markers
address@hidden window-state-get &optional window ignore
 This function returns the state of @var{window} as a Lisp object.  The
 argument @var{window} can be any window and defaults to the root window
 of the selected frame.
-The optional argument @var{markers} address@hidden means to use markers
-for sampling positions like @code{window-point} or @code{window-start}.
-This argument should be address@hidden only if the value is used for
-putting the state back in the same session since markers slow down
+If the optional argument @var{ignore} is address@hidden, this means to
+not use markers for sampling positions like @code{window-point} or
address@hidden and to not save values of parameters in the list
address@hidden, see below.  This argument should
+be address@hidden when the state shall be written on disk and read back
+in another session.
+This function copies the value of all window parameters listed by the
+variable @code{window-persistent-parameters}, see above.
 @end defun
address@hidden window-state-ignored-parameters
+This variable lists all parameters whose value must not be recorded by
+the function @code{window-state-get} when its @var{ignore} argument is
address@hidden, see above.
address@hidden defvar
 The value returned by @code{window-state-get} can be converted by using
 one of the functions defined by Desktop Save Mode (@pxref{Desktop Save
 Mode}) to an object that can be written to a file.  Such objects can be
@@ -3239,6 +3268,10 @@
 minimum window sizes and fixed size restrictions.  If @var{ignore}
 equals @code{safe}, this means windows can get as small as one line
 and/or two columns.
+This function restores the values of all window parameters listed by
address@hidden, see above, to their values in
 @end defun

=== modified file 'lisp/window.el'
--- lisp/window.el      2011-12-24 19:16:53 +0000
+++ lisp/window.el      2011-12-27 16:36:57 +0000
@@ -3568,10 +3568,12 @@
 ;;; Window states, how to get them and how to put them in a window.
-(defvar window-state-ignored-parameters '(quit-restore)
-  "List of window parameters ignored by `window-state-get'.")
+(defvar window-state-ignored-parameters '(quit-restore clone-of)
+  "Window parameters ignored by `window-state-get'.
+Parameters in this list are not saved by `window-state-get' when
+its IGNORE argument is non-nil.")
-(defun window--state-get-1 (window &optional markers)
+(defun window--state-get-1 (window &optional ignore)
   "Helper function for `window-state-get'."
   (let* ((type
@@ -3590,11 +3592,18 @@
             (combination-limit . ,(window-combination-limit window))
             ,@(let (list)
                 (dolist (parameter (window-parameters window))
-                  (unless (memq (car parameter)
-                                window-state-ignored-parameters)
-                    (setq list (cons parameter list))))
-                (unless (window-parameter window 'clone-of)
-                  ;; Make a clone-of parameter.
+                 ;; When IGNORE is nil, add a parameter only if it is
+                 ;; in `window-persistent-parameters'.  When IGNORE is
+                 ;; non-nil, add a parameter if and only if it is not
+                 ;; in `window-state-ignored-parameters'.
+                 (when (if ignore
+                           (not (memq (car parameter)
+                                      window-state-ignored-parameters))
+                         (memq (car parameter) window-persistent-parameters))
+                    (setq list (cons (cons (car parameter) (cdr parameter))
+                                    list))))
+                (unless (or ignore (window-parameter window 'clone-of))
+                  ;; Make `clone-of' parameter unless IGNORE is non-nil.
                   (setq list (cons (cons 'clone-of window) list)))
                 (when list
                   `((parameters . ,list))))
@@ -3616,30 +3625,32 @@
                        (scroll-bars . ,(window-scroll-bars window))
                        (vscroll . ,(window-vscroll window))
                        (dedicated . ,(window-dedicated-p window))
-                       (point . ,(if markers (copy-marker point) point))
-                       (start . ,(if markers (copy-marker start) start))
+                       (point . ,(if ignore point (copy-marker point)))
+                       (start . ,(if ignore start (copy-marker start)))
                        ,@(when mark
-                           `((mark . ,(if markers
-                                          (copy-marker mark) mark)))))))))))
+                           `((mark . ,(if ignore
+                                          mark (copy-marker mark))))))))))))
          (when (memq type '(vc hc))
            (let (list)
              (setq window (window-child window))
              (while window
-               (setq list (cons (window--state-get-1 window markers) list))
+               (setq list (cons (window--state-get-1 window ignore) list))
                (setq window (window-right window)))
              (nreverse list)))))
     (append head tail)))
-(defun window-state-get (&optional window markers)
+(defun window-state-get (&optional window ignore)
   "Return state of WINDOW as a Lisp object.
 WINDOW can be any window and defaults to the root window of the
 selected frame.
-Optional argument MARKERS non-nil means use markers for sampling
-positions like `window-point' or `window-start'.  MARKERS should
-be non-nil only if the value is used for putting the state back
-in the same session (note that markers slow down processing).
+Optional argument IGNORE non-nil means do not use markers for
+sampling positions like `window-point' or `window-start' and do
+not record ignored window parameters as specified by
+`window-state-ignored-parameters'.  IGNORE should be non-nil when
+the return value shall be written to a file and read back in
+another session.
 The return value can be used as argument for `window-state-put'
 to put the state recorded here into an arbitrary window.  The
@@ -3665,7 +3676,7 @@
      ;; These are probably not needed.
      ,@(when (window-size-fixed-p window) `((fixed-height . t)))
      ,@(when (window-size-fixed-p window t) `((fixed-width . t))))
-   (window--state-get-1 window markers)))
+   (window--state-get-1 window ignore)))
 (defvar window-state-put-list nil
   "Helper variable for `window-state-put'.")
@@ -3744,6 +3755,10 @@
          (state (cdr (assq 'buffer item))))
       (when combination-limit
        (set-window-combination-limit window combination-limit))
+      ;; nil out values of parameters in `window-persistent-parameters'.
+      (dolist (parameter (window-parameters window))
+       (when (memq (car parameter) window-persistent-parameters)
+         (set-window-parameter window (car parameter) nil)))
       ;; Process parameters.
       (when parameters
        (dolist (parameter parameters)

=== modified file 'src/window.c'
--- src/window.c        2011-12-13 13:58:20 +0000
+++ src/window.c        2011-12-27 09:37:03 +0000
@@ -5349,6 +5349,7 @@
   (Lisp_Object configuration)
   register struct save_window_data *data;
+  register Lisp_Object tem, car;
   struct Lisp_Vector *saved_windows;
   Lisp_Object new_current_buffer;
   Lisp_Object frame;
@@ -5543,7 +5544,25 @@
          w->vertical_scroll_bar_type = p->vertical_scroll_bar_type;
          w->dedicated = p->dedicated;
          w->combination_limit = p->combination_limit;
-         w->window_parameters = p->window_parameters;
+         /* nil out values of persistent window parameters.  */
+         if (!NILP (w->window_parameters))
+           for (tem = w->window_parameters; CONSP (tem); tem = XCDR (tem))
+             {
+               car = XCAR (tem);
+               if (CONSP (car)
+                   && !NILP (Fmemq (XCAR (car), 
+                 Fsetcdr (car, Qnil);
+             }
+         /* Restore persistent window parameters.  */
+         if (!NILP (p->window_parameters))
+           for (tem = p->window_parameters; CONSP (tem); tem = XCDR (tem))
+             {
+               car = XCAR (tem);
+               if (CONSP (car))
+                 Fset_window_parameter (window, XCAR (car), XCDR (car));
+             }
          XSETFASTINT (w->last_modified, 0);
          XSETFASTINT (w->last_overlay_modified, 0);
@@ -5810,7 +5829,7 @@
   register struct saved_window *p;
   register struct window *w;
-  register Lisp_Object tem;
+  register Lisp_Object tem, car;
   for (;!NILP (window); window = w->next)
@@ -5838,7 +5857,18 @@
       p->vertical_scroll_bar_type = w->vertical_scroll_bar_type;
       p->dedicated = w->dedicated;
       p->combination_limit = w->combination_limit;
-      p->window_parameters = w->window_parameters;
+      p->window_parameters = Qnil;
+      /* Store copies of persistent window parameters.  */
+      if (!NILP (w->window_parameters))
+       for (tem = w->window_parameters; CONSP (tem); tem = XCDR (tem))
+         {
+           car = XCAR (tem);
+           if (CONSP (car)
+               && !NILP (Fmemq (XCAR (car), Vwindow_persistent_parameters)))
+             p->window_parameters = Fcons (Fcons (XCAR (car), XCDR (car)),
+                                           p->window_parameters);
+         }
       if (!NILP (w->buffer))
          /* Save w's value of point in the window configuration.
@@ -6542,6 +6572,13 @@
 function `set-window-combination-limit'.  */);
   Vwindow_combination_limit = Qnil;
+  DEFVAR_LISP ("window-persistent-parameters", Vwindow_persistent_parameters,
+              doc: /* List of persistent window parameters.
+The parameters in this list are saved by `current-window-configuration'
+and `window-state-get' and restored by `set-window-configuration' and
+`window-state-put'.  */);
+  Vwindow_persistent_parameters = Qnil;
   defsubr (&Sselected_window);
   defsubr (&Sminibuffer_window);
   defsubr (&Swindow_minibuffer_p);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]