emacs-diffs
[Top][All Lists]
Advanced

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

[Emacs-diffs] /srv/bzr/emacs/trunk r106873: Provide persistent window pa


From: martin rudalics
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r106873: Provide persistent window parameters.
Date: Mon, 16 Jan 2012 10:34:41 +0100
User-agent: Bazaar (2.3.1)

------------------------------------------------------------
revno: 106873
committer: martin rudalics <address@hidden>
branch nick: trunk
timestamp: Mon 2012-01-16 10:34:41 +0100
message:
  Provide persistent window parameters.
  
  * window.c (Vwindow_persistent_parameters): New variable.
  (Fset_window_configuration, save_window_save): Handle persistent
  window parameters.
  
  * window.el (window-state-ignored-parameters): Remove variable.
  (window--state-get-1): Rename argument MARKERS to IGNORE.
  Handle persistent window parameters.  Make copy of clone-of
  parameter only if requested.  (Bug#10348)
  (window--state-put-2): Install a window parameter only if it has
  a non-nil value or an existing parameter shall be overwritten.
  
  * windows.texi (Window Configurations, Window Parameters):
  Describe persistent window parameters.
modified:
  doc/lispref/ChangeLog
  doc/lispref/windows.texi
  lisp/ChangeLog
  lisp/window.el
  src/ChangeLog
  src/window.c
=== modified file 'doc/lispref/ChangeLog'
--- a/doc/lispref/ChangeLog     2012-01-09 05:29:45 +0000
+++ b/doc/lispref/ChangeLog     2012-01-16 09:34:41 +0000
@@ -1,3 +1,8 @@
+2012-01-16  Martin Rudalics  <address@hidden>
+
+       * windows.texi (Window Configurations, Window Parameters):
+       Describe persistent window parameters.
+
 2011-12-27  Stefan Monnier  <address@hidden>
 
        * variables.texi (Creating Buffer-Local): Warn against misuses of

=== modified file 'doc/lispref/windows.texi'
--- a/doc/lispref/windows.texi  2012-01-05 09:46:05 +0000
+++ b/doc/lispref/windows.texi  2012-01-16 09:34:41 +0000
@@ -3104,7 +3104,9 @@
 @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.
+frame.  This function saves copies of window parameters listed by the
+variable @code{window-persistent-parameters}, see @ref{Window
+Parameters} for details.
 @end defun
 
 @defun set-window-configuration configuration
@@ -3206,24 +3208,30 @@
 
   The objects returned by @code{current-window-configuration} die
 together with the Emacs process.  In order to store a window
-configuration on disk and read it back in another Emacs session the
-following two functions can be used.
+configuration on disk and read it back in another Emacs session, the
+functions described next can be used.  These functions are also useful
+to clone the state of a frame into an arbitrary live window
+(@code{set-window-configuration} effectively clones the windows of a
+frame into the root window of that very frame only).
 
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
-processing.
+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  This argument should be address@hidden when the
+state shall be written on disk and read back in another session.
+
+The variable @code{window-persistent-parameters} specifies whether and
+which window parameters are saved by this function, see @ref{Window
+Parameters} for details.
 @end defun
 
-The value returned by @code{window-state-get} can be converted by using
+The value returned by @code{window-state-get} can be converted, 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
+Mode}), to an object that can be written to a file.  Such objects can be
 read back and converted to a Lisp object representing the state of the
 window.  That Lisp object can be used as argument for the following
 function in order to restore the state window in another window.
@@ -3268,6 +3276,51 @@
 is the selected window.
 @end defun
 
+By default, functions saving and restoring window configurations or the
+states of windows (@xref{Window Configurations}) do not care about
+window parameters.  This means, that when you change the value of a
+parameter within the body of a @code{save-window-excursion}, the
+previous value is not restored upon exit of that macro.  It also means
+that when you clone via @code{window-state-put} a window state saved
+earlier by @code{window-state-get}, the cloned windows come up with no
+parameters at all.  The following variable allows to override the
+standard behavior.
+
address@hidden window-persistent-parameters
+This variable is an alist specifying which parameters get saved by
address@hidden and @code{window-state-get} and
+subsequently restored by @code{set-window-configuration} and
address@hidden, see @ref{Window Configurations}.
+
+The @sc{car} of each entry of this alist is the symbol specifying the
+parameter.  The @sc{cdr} must be one of the following:
+
address@hidden @asis
address@hidden @code{state}
+This value means the parameter is saved by @code{window-state-get}
+provided its @var{ignore} argument is @code{nil}.  The function
address@hidden does not save this parameter.
+
address@hidden @code{nil}
+This value specifies that the parameter is saved by
address@hidden and, provided its @var{ignore}
+argument is @code{nil}, by @code{window-state-get}.
+
address@hidden @code{t}
+This means that the parameter is saved unconditionally by both
address@hidden and @code{window-state-get}.  This
+value should not be used for parameters whose values do not have a read
+syntax.  Otherwise, invoking @code{window-state-put} in another session
+may fail with an @code{invalid-read-syntax} error.
address@hidden table
+
+Parameters that have been saved are restored to their previous values by
address@hidden respectively are installed by
address@hidden  Parameters that have not been saved are left
+alone by @code{set-window-configuration} respectively are not installed
+by @code{window-state-put}.
address@hidden defvar
+
 Some functions, notably @code{delete-window},
 @code{delete-other-windows} and @code{split-window} may behave specially
 when their @var{window} argument has a parameter set.  You can override
@@ -3287,7 +3340,7 @@
 @end defvar
 
 The following parameters are currently used by the window management
-code.
+code:
 
 @table @asis
 @item @code{delete-window}
@@ -3309,14 +3362,20 @@
 @item @code{no-other-window}
 This parameter marks the window as not selectable by @code{other-window}
 (@pxref{Cyclic Window Ordering}).
+
address@hidden @code{clone-of}
+This parameter specifies the window this one has been cloned from and is
+installed by @code{window-state-get}, see @ref{Window Configurations}.
+
address@hidden @code{quit-restore}
+This parameter tells how to proceed with a window when the buffer it
+shows is no more needed.  It is installed by the buffer display
+functions (@pxref{Choosing Window}) and consulted by the function
address@hidden (@pxref{Quitting Windows}).
 @end table
 
 In addition, the parameters @code{window-atom} and @code{window-side}
-are reserved and should not be used by applications.  The
address@hidden parameter tells how to proceed with a window when
-the buffer it shows is no more needed.  This parameter is installed by
-the buffer display functions (@pxref{Choosing Window}) and consulted by
-the function @code{quit-window} (@pxref{Quitting Windows}).
+are reserved and should not be used by applications.
 
 
 @node Window Hooks

=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2012-01-15 16:03:30 +0000
+++ b/lisp/ChangeLog    2012-01-16 09:34:41 +0000
@@ -1,3 +1,12 @@
+2012-01-16  Martin Rudalics  <address@hidden>
+
+       * window.el (window-state-ignored-parameters): Remove variable.
+       (window--state-get-1): Rename argument MARKERS to IGNORE.
+       Handle persistent window parameters.  Make copy of clone-of
+       parameter only if requested.  (Bug#10348)
+       (window--state-put-2): Install a window parameter only if it has
+       a non-nil value or an existing parameter shall be overwritten.
+
 2012-01-15  Michael Albinus  <address@hidden>
 
        * net/tramp-sh.el (tramp-remote-path): Set tramp-autoload cookie.

=== modified file 'lisp/window.el'
--- a/lisp/window.el    2012-01-05 09:46:05 +0000
+++ b/lisp/window.el    2012-01-16 09:34:41 +0000
@@ -3568,10 +3568,7 @@
     ))
 
 ;;; 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'.")
-
-(defun window--state-get-1 (window &optional markers)
+(defun window--state-get-1 (window &optional ignore)
   "Helper function for `window-state-get'."
   (let* ((type
          (cond
@@ -3589,12 +3586,27 @@
             (normal-width . ,(window-normal-size window t))
             (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.
+               ;; Make copies of persistent window parameters whose cdr
+               ;; is either t or, when IGNORE is non-nil, is either nil
+               ;; or `state'.
+                (dolist (pers window-persistent-parameters)
+                 (when (and (consp pers)
+                            (or (eq (cdr pers) t)
+                                (and (memq (cdr pers) '(state nil))
+                                     (not ignore))))
+                   (let ((par (assq (car pers) (window-parameters window))))
+                     (setq list (cons (cons (car pers) (when par (cdr par)))
+                                      list)))))
+               ;; Save `clone-of' parameter unless IGNORE or
+               ;; `window-persistent-parameters' prevail.
+                (when (and (not (assq 'clone-of (window-parameters window)))
+                          (let ((clone-of
+                                 (assq 'clone-of
+                                       window-persistent-parameters)))
+                            (when clone-of
+                              (if ignore
+                                  (eq (cdr clone-of) t)
+                                (memq (cdr clone-of) '(state nil))))))
                   (setq list (cons (cons 'clone-of window) list)))
                 (when list
                   `((parameters . ,list))))
@@ -3616,30 +3628,31 @@
                        (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))))))))))))
         (tail
          (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 parameters unless `window-persistent-parameters'
+requests it.  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 +3678,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,10 +3757,15 @@
          (state (cdr (assq 'buffer item))))
       (when combination-limit
        (set-window-combination-limit window combination-limit))
-      ;; Process parameters.
+      ;; Assign saved window parameters.  If a parameter's value is nil,
+      ;; don't assign it unless the new window has it set already (which
+      ;; shouldn't happen unless some `window-configuration-change-hook'
+      ;; function installed it).
       (when parameters
        (dolist (parameter parameters)
-         (set-window-parameter window (car parameter) (cdr parameter))))
+         (when (or (cdr parameter)
+                   (window-parameter window (car parameter)))
+           (set-window-parameter window (car parameter) (cdr parameter)))))
       ;; Process buffer related state.
       (when state
        ;; We don't want to raise an error here so we create a buffer if

=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2012-01-14 20:15:01 +0000
+++ b/src/ChangeLog     2012-01-16 09:34:41 +0000
@@ -1,3 +1,9 @@
+2012-01-16  Martin Rudalics  <address@hidden>
+
+       * window.c (Vwindow_persistent_parameters): New variable.
+       (Fset_window_configuration, save_window_save): Handle persistent
+       window parameters.
+
 2012-01-14  Eli Zaretskii  <address@hidden>
 
        * w32fns.c (signal_user_input): Don't do a QUIT, to avoid

=== modified file 'src/window.c'
--- a/src/window.c      2012-01-05 09:46:05 +0000
+++ b/src/window.c      2012-01-16 09:34:41 +0000
@@ -57,7 +57,7 @@
 static Lisp_Object Qwindow_resize_root_window, 
Qwindow_resize_root_window_vertically;
 static Lisp_Object Qscroll_up, Qscroll_down, Qscroll_command;
 static Lisp_Object Qsafe, Qabove, Qbelow;
-static Lisp_Object Qauto_buffer_name;
+static Lisp_Object Qauto_buffer_name, Qclone_of, Qstate;
 
 static int displayed_window_lines (struct window *);
 static struct window *decode_window (Lisp_Object);
@@ -5410,6 +5410,7 @@
     {
       Lisp_Object window;
       Lisp_Object dead_windows = Qnil;
+      register Lisp_Object tem, par, pers;
       register struct window *w;
       register struct saved_window *p;
       struct window *root_window;
@@ -5543,7 +5544,28 @@
          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;
+         /* Restore any window parameters that have been saved.
+            Parameters that have not been saved are left alone.  */
+         for (tem = p->window_parameters; CONSP (tem); tem = XCDR (tem))
+           {
+             pers = XCAR (tem);
+             if (CONSP (pers))
+               {
+                 if (NILP (XCDR (pers)))
+                   {
+                     par = Fassq (XCAR (pers), w->window_parameters);
+                     if (CONSP (par) && !NILP (XCDR (par)))
+                       /* Reset a parameter to nil if and only if it
+                          has a non-nil association.  Don't make new
+                          associations.  */
+                       Fsetcdr (par, Qnil);
+                   }
+                 else
+                   /* Always restore a non-nil value.  */
+                   Fset_window_parameter (window, XCAR (pers), XCDR (pers));
+               }
+           }
+
          XSETFASTINT (w->last_modified, 0);
          XSETFASTINT (w->last_overlay_modified, 0);
 
@@ -5810,7 +5832,7 @@
 {
   register struct saved_window *p;
   register struct window *w;
-  register Lisp_Object tem;
+  register Lisp_Object tem, pers, par;
 
   for (;!NILP (window); window = w->next)
     {
@@ -5838,12 +5860,60 @@
       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;
+
+      if (!NILP (Vwindow_persistent_parameters))
+       {
+         /* Run cycle detection on Vwindow_persistent_parameters.  */
+         Lisp_Object tortoise, hare;
+
+         hare = tortoise = Vwindow_persistent_parameters;
+         while (CONSP (hare))
+           {
+             hare = XCDR (hare);
+             if (!CONSP (hare))
+               break;
+
+             hare = XCDR (hare);
+             tortoise = XCDR (tortoise);
+
+             if (EQ (hare, tortoise))
+               /* Reset Vwindow_persistent_parameters to Qnil.  */
+               {
+                 Vwindow_persistent_parameters = Qnil;
+                 break;
+               }
+           }
+
+         for (tem = Vwindow_persistent_parameters; CONSP (tem);
+              tem = XCDR (tem))
+           {
+             pers = XCAR (tem);
+             /* Save values for persistent window parameters whose cdr
+                is either nil or t.  */
+             if (CONSP (pers) && (NILP (XCDR (pers)) || EQ (XCDR (pers), Qt)))
+               {
+                 par = Fassq (XCAR (pers), w->window_parameters);
+                 if (NILP (par))
+                   /* If the window has no value for the parameter,
+                      make one.  */
+                   p->window_parameters = Fcons (Fcons (XCAR (pers), Qnil),
+                                                 p->window_parameters);
+                 else
+                   /* If the window has a value for the parameter,
+                      save it.  */
+                   p->window_parameters = Fcons (Fcons (XCAR (par),
+                                                        XCDR (par)),
+                                                 p->window_parameters);
+               }
+           }
+       }
+
       if (!NILP (w->buffer))
        {
-         /* Save w's value of point in the window configuration.
-            If w is the selected window, then get the value of point
-            from the buffer; pointm is garbage in the selected window.  */
+         /* Save w's value of point in the window configuration.  If w
+            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 = Fmake_marker ();
@@ -6433,6 +6503,8 @@
   DEFSYM (Qabove, "above");
   DEFSYM (Qbelow, "below");
   DEFSYM (Qauto_buffer_name, "auto-buffer-name");
+  DEFSYM (Qclone_of, "clone-of");
+  DEFSYM (Qstate, "state");
 
   staticpro (&Vwindow_list);
 
@@ -6542,6 +6614,31 @@
 function `set-window-combination-limit'.  */);
   Vwindow_combination_limit = Qnil;
 
+  DEFVAR_LISP ("window-persistent-parameters", Vwindow_persistent_parameters,
+              doc: /* Alist of persistent window parameters.
+Parameters in this list are saved by `current-window-configuration' and
+`window-state-get' and subsequently restored to their previous values by
+`set-window-configuration' and `window-state-put'.
+
+The car of each entry of this alist is the symbol specifying the
+parameter.  The cdr is one of the following:
+
+The symbol `state' means the parameter is saved by `window-state-get'
+provided its IGNORE argument is nil.  `current-window-configuration'
+does not save this parameter.
+
+nil means the parameter is saved by `current-window-configuration' and,
+provided its IGNORE argument is nil, by `window-state-get'.
+
+t means the parameter is saved unconditionally by both
+`current-window-configuration' and `window-state-get'.  Parameters
+without read syntax (like windows or frames) should not use that.
+
+Parameters not saved by `current-window-configuration' or
+`window-state-get' are left alone by `set-window-configuration'
+respectively are not installed by `window-state-put'.  */);
+  Vwindow_persistent_parameters = list1 (Fcons (Qclone_of, Qstate));
+
   defsubr (&Sselected_window);
   defsubr (&Sminibuffer_window);
   defsubr (&Swindow_minibuffer_p);


reply via email to

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