From: martin rudalics <rudalics@gmx.at>
To: Stefan Monnier <monnier@IRO.UMontreal.CA>
Cc: Michael Bach <phaebz@gmail.com>, 10348@debbugs.gnu.org
Subject: bug#10348: 24.0.92; Save and load window states
Date: Thu, 29 Dec 2011 12:39:13 +0100 [thread overview]
Message-ID: <4EFC5161.8040808@gmx.at> (raw)
In-Reply-To: <jwvaa6cti21.fsf-monnier+emacs@gnu.org>
[-- Attachment #1: Type: text/plain, Size: 759 bytes --]
> I don't understand: you first seem to say you disagree with me, but then
> what you say afterwards seems to agree with me.
Indeed.
> Indeed, but otherwise, as you pointed out, it makes the semantics rather
> tricky if window-persistent-parameters is changed between the save and
> the restore (which is something that is very likely to happen sometimes
> since the restore may happen years after the save).
I resolved the semantics by saving always all parameters unless I do
`window-state-get' with IGNORE non-nil and the parameter is in
`window-state-ignored-parameters'. When restoring parameters via
`set-window-configuration'/`window-state-put', I overwrite/install a
value only if the parameter is in `window-persistent-parameters'.
martin
[-- Attachment #2: window-parameters.diff --]
[-- Type: text/plain, Size: 11588 bytes --]
=== modified file 'doc/lispref/windows.texi'
--- doc/lispref/windows.texi 2011-12-13 13:37:48 +0000
+++ doc/lispref/windows.texi 2011-12-29 10:34:38 +0000
@@ -3104,7 +3104,7 @@
@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 copies the value of all window parameters.
@end defun
@defun set-window-configuration configuration
@@ -3121,6 +3121,9 @@
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
+@code{window-persistent-parameters}, see below.
+
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
@@ -3140,6 +3143,18 @@
@end example
@end defun
+@defvar window-persistent-parameters
+This variable lists all window parameters that are restored by
+@code{set-window-configuration}, see above. This means that the value
+of any parameter listed by this variable and changed within the body of
+@code{save-window-excursion} 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.
+
+Parameters not listed by this variable are effectively not installed by
+the function @code{window-state-put}, see below.
+@end defvar
+
@defspec save-window-excursion forms@dots{}
This special form records the window configuration, executes @var{forms}
in sequence, then restores the earlier window configuration. The window
@@ -3209,18 +3224,25 @@
configuration on disk and read it back in another Emacs session the
following two functions can be used.
-@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} and to not save values of parameters in the list
+@code{window-state-ignored-parameters}, see below. This argument should
+be non-@code{nil} when the state shall be written on disk and read back
+in another session.
@end defun
+@defvar window-state-ignored-parameters
+This variable lists all parameters whose value is not recorded by the
+function @code{window-state-get} when its @var{ignore} argument is
+non-@code{nil}, see above.
+@end 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 +3261,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 installs the values of all window parameters listed by
+@code{window-persistent-parameters}, see above, provided their values
+are stored in @var{state}.
@end defun
=== modified file 'lisp/window.el'
--- lisp/window.el 2011-12-24 19:16:53 +0000
+++ lisp/window.el 2011-12-29 10:11:05 +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
(cond
@@ -3590,11 +3592,15 @@
(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 non-nil, add a parameter if and only
+ ;; if it is not in `window-state-ignored-parameters'.
+ (unless (and ignore
+ (memq (car parameter)
+ window-state-ignored-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 +3622,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))))))))))))
(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 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 +3673,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 +3752,15 @@
(state (cdr (assq 'buffer item))))
(when combination-limit
(set-window-combination-limit window combination-limit))
- ;; Process parameters.
+ ;; 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)))
+ ;; Assign persistent window parameters.
(when parameters
(dolist (parameter parameters)
- (set-window-parameter window (car parameter) (cdr parameter))))
+ (when (memq (car parameter) window-persistent-parameters)
+ (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/window.c'
--- src/window.c 2011-12-13 13:58:20 +0000
+++ src/window.c 2011-12-29 11:21:42 +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,26 @@
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), Vwindow_persistent_parameters)))
+ 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)
+ && !NILP (Fmemq (XCAR (car), Vwindow_persistent_parameters)))
+ Fset_window_parameter (window, XCAR (car), XCDR (car));
+ }
+
XSETFASTINT (w->last_modified, 0);
XSETFASTINT (w->last_overlay_modified, 0);
@@ -5810,7 +5830,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 +5858,11 @@
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;
+ /* Store copies of all window parameters. When
+ Fset_window_configuration later considers a parameter as
+ persistent it will take it from the copy stored here. */
+ p->window_parameters = Fcopy_alist (w->window_parameters);
+
if (!NILP (w->buffer))
{
/* Save w's value of point in the window configuration.
@@ -6542,6 +6566,15 @@
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 restored to their previous values by the
+functions `set-window-configuration' and `window-state-put'. Any
+parameterts not listed here are left alone by `set-window-configuration'
+respectively not installed by `window-state-put'. */);
+ Vwindow_persistent_parameters = Qnil;
+
defsubr (&Sselected_window);
defsubr (&Sminibuffer_window);
defsubr (&Swindow_minibuffer_p);
next prev parent reply other threads:[~2011-12-29 11:39 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-21 20:41 bug#10348: 24.0.92; Save and load window states Michael Bach
2011-12-22 17:04 ` martin rudalics
2011-12-22 17:14 ` Drew Adams
2011-12-22 21:57 ` Juri Linkov
2011-12-22 22:57 ` Juanma Barranquero
2011-12-22 23:34 ` Juri Linkov
2011-12-23 10:30 ` martin rudalics
2011-12-23 15:10 ` Drew Adams
2011-12-24 19:04 ` Juri Linkov
2011-12-23 10:30 ` martin rudalics
2011-12-23 1:03 ` Stefan Monnier
2011-12-23 10:31 ` martin rudalics
2011-12-23 11:30 ` Michael Bach
2011-12-23 21:14 ` Juri Linkov
2011-12-24 9:26 ` martin rudalics
2011-12-24 19:08 ` Juri Linkov
2011-12-25 13:57 ` martin rudalics
2011-12-24 0:07 ` Stefan Monnier
2011-12-24 9:27 ` martin rudalics
2011-12-25 11:00 ` Stefan Monnier
2011-12-25 13:58 ` martin rudalics
2011-12-25 21:36 ` Juri Linkov
2011-12-26 11:07 ` martin rudalics
2011-12-26 0:22 ` Stefan Monnier
2011-12-26 11:07 ` martin rudalics
2011-12-26 18:25 ` martin rudalics
2011-12-27 23:23 ` Stefan Monnier
2011-12-28 15:57 ` martin rudalics
2011-12-28 23:09 ` Stefan Monnier
2011-12-29 11:39 ` martin rudalics [this message]
2012-01-16 9:42 ` martin rudalics
2011-12-28 9:50 ` martin rudalics
2011-12-24 19:17 ` Juri Linkov
2012-01-16 9:43 ` martin rudalics
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4EFC5161.8040808@gmx.at \
--to=rudalics@gmx.at \
--cc=10348@debbugs.gnu.org \
--cc=monnier@IRO.UMontreal.CA \
--cc=phaebz@gmail.com \
/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 external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.