* 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.
+2012-01-16 Martin Rudalics <rudalics@gmx.at>
+
+ * windows.texi (Window Configurations, Window Parameters):
+ Describe persistent window parameters.
+
2011-12-27 Stefan Monnier <monnier@iro.umontreal.ca>
* variables.texi (Creating Buffer-Local): Warn against misuses of
@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
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).
-@defun window-state-get &optional window markers
+@defun 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} non-@code{nil} means to use markers
-for sampling positions like @code{window-point} or @code{window-start}.
-This argument should be non-@code{nil} 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 non-@code{nil}, this means to
+not use markers for sampling positions like @code{window-point} or
+@code{window-start}. This argument should be non-@code{nil} 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.
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.
+
+@defvar window-persistent-parameters
+This variable is an alist specifying which parameters get saved by
+@code{current-window-configuration} and @code{window-state-get} and
+subsequently restored by @code{set-window-configuration} and
+@code{window-state-put}, 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:
+
+@table @asis
+@item @code{state}
+This value means the parameter is saved by @code{window-state-get}
+provided its @var{ignore} argument is @code{nil}. The function
+@code{current-window-configuration} does not save this parameter.
+
+@item @code{nil}
+This value specifies that the parameter is saved by
+@code{current-window-configuration} and, provided its @var{ignore}
+argument is @code{nil}, by @code{window-state-get}.
+
+@item @code{t}
+This means that the parameter is saved unconditionally by both
+@code{current-window-configuration} 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.
+@end table
+
+Parameters that have been saved are restored to their previous values by
+@code{set-window-configuration} respectively are installed by
+@code{window-state-put}. Parameters that have not been saved are left
+alone by @code{set-window-configuration} respectively are not installed
+by @code{window-state-put}.
+@end 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
@end defvar
The following parameters are currently used by the window management
-code.
+code:
@table @asis
@item @code{delete-window}
@item @code{no-other-window}
This parameter marks the window as not selectable by @code{other-window}
(@pxref{Cyclic Window Ordering}).
+
+@item @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}.
+
+@item @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
+@code{quit-window} (@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
-@code{quit-restore} 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
+2012-01-16 Martin Rudalics <rudalics@gmx.at>
+
+ * 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 <michael.albinus@gmx.de>
* net/tramp-sh.el (tramp-remote-path): Set tramp-autoload cookie.
))
;;; 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
(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))))
(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
;; 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'.")
(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
+2012-01-16 Martin Rudalics <rudalics@gmx.at>
+
+ * window.c (Vwindow_persistent_parameters): New variable.
+ (Fset_window_configuration, save_window_save): Handle persistent
+ window parameters.
+
2012-01-14 Eli Zaretskii <eliz@gnu.org>
* w32fns.c (signal_user_input): Don't do a QUIT, to avoid
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);
{
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;
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);
{
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)
{
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 ();
DEFSYM (Qabove, "above");
DEFSYM (Qbelow, "below");
DEFSYM (Qauto_buffer_name, "auto-buffer-name");
+ DEFSYM (Qclone_of, "clone-of");
+ DEFSYM (Qstate, "state");
staticpro (&Vwindow_list);
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);