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.
This commit is contained in:
parent
97912defd3
commit
6a6ee00d12
6 changed files with 241 additions and 47 deletions
|
@ -1,3 +1,8 @@
|
|||
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
|
||||
|
|
|
@ -3104,7 +3104,9 @@ window configuration; see @ref{Frame Configurations}.
|
|||
@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 @@ configurations.
|
|||
|
||||
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.
|
||||
|
@ -3268,6 +3276,51 @@ This function sets @var{window}'s value of @var{parameter} to
|
|||
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
|
||||
|
@ -3287,7 +3340,7 @@ windows when exiting that function.
|
|||
@end defvar
|
||||
|
||||
The following parameters are currently used by the window management
|
||||
code.
|
||||
code:
|
||||
|
||||
@table @asis
|
||||
@item @code{delete-window}
|
||||
|
@ -3309,14 +3362,20 @@ This parameter affects the execution of @code{other-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
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
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.
|
||||
|
|
|
@ -3568,10 +3568,7 @@ specific buffers."
|
|||
))
|
||||
|
||||
;;; 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 @@ specific buffers."
|
|||
(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 @@ specific buffers."
|
|||
(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 @@ value can be also stored on disk and read back in a new session."
|
|||
;; 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 @@ value can be also stored on disk and read back in a new session."
|
|||
(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
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
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
|
||||
|
|
111
src/window.c
111
src/window.c
|
@ -57,7 +57,7 @@ static Lisp_Object Qreplace_buffer_in_windows, Qget_mru_window;
|
|||
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 @@ the return value is nil. Otherwise the value is t. */)
|
|||
{
|
||||
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 @@ the return value is nil. Otherwise the value is t. */)
|
|||
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 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
|
|||
{
|
||||
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 @@ save_window_save (Lisp_Object window, struct Lisp_Vector *vector, int i)
|
|||
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 @@ syms_of_window (void)
|
|||
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 @@ retrieved via the function `window-combination-limit' and altered by the
|
|||
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);
|
||||
|
|
Loading…
Add table
Reference in a new issue