From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: martin rudalics Newsgroups: gmane.emacs.bugs Subject: bug#10348: 24.0.92; Save and load window states Date: Wed, 28 Dec 2011 10:50:17 +0100 Message-ID: <4EFAE659.4090601@gmx.at> References: <4ef24371.94110e0a.6fbb.ffffc8f3@mx.google.com> <4EF36318.6000006@gmx.at> <4EF45888.3030204@gmx.at> <4EF59B02.9060608@gmx.at> <4EF72BE9.60604@gmx.at> <4EF8557A.3020001@gmx.at> <4EF8BC0B.6020805@gmx.at> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------000702050504020508070305" X-Trace: dough.gmane.org 1325065897 11024 80.91.229.12 (28 Dec 2011 09:51:37 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Wed, 28 Dec 2011 09:51:37 +0000 (UTC) Cc: Michael Bach , 10348@debbugs.gnu.org To: Stefan Monnier Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Wed Dec 28 10:51:32 2011 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([140.186.70.17]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1RfqAS-0002Jl-J6 for geb-bug-gnu-emacs@m.gmane.org; Wed, 28 Dec 2011 10:51:29 +0100 Original-Received: from localhost ([::1]:57385 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RfqAS-0005fL-2I for geb-bug-gnu-emacs@m.gmane.org; Wed, 28 Dec 2011 04:51:28 -0500 Original-Received: from eggs.gnu.org ([140.186.70.92]:58231) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RfqAO-0005fA-9z for bug-gnu-emacs@gnu.org; Wed, 28 Dec 2011 04:51:26 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RfqAJ-0000Gv-IE for bug-gnu-emacs@gnu.org; Wed, 28 Dec 2011 04:51:24 -0500 Original-Received: from debbugs.gnu.org ([140.186.70.43]:55465) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RfqAJ-0000Gj-Ez for bug-gnu-emacs@gnu.org; Wed, 28 Dec 2011 04:51:19 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.69) (envelope-from ) id 1RfqCw-0006hD-3z for bug-gnu-emacs@gnu.org; Wed, 28 Dec 2011 04:54:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: martin rudalics Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 28 Dec 2011 09:54:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 10348 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 10348-submit@debbugs.gnu.org id=B10348.132506598725661 (code B ref 10348); Wed, 28 Dec 2011 09:54:02 +0000 Original-Received: (at 10348) by debbugs.gnu.org; 28 Dec 2011 09:53:07 +0000 Original-Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RfqC2-0006fq-Fi for submit@debbugs.gnu.org; Wed, 28 Dec 2011 04:53:06 -0500 Original-Received: from mailout-de.gmx.net ([213.165.64.23]) by debbugs.gnu.org with smtp (Exim 4.69) (envelope-from ) id 1RfqBz-0006fi-Hr for 10348@debbugs.gnu.org; Wed, 28 Dec 2011 04:53:05 -0500 Original-Received: (qmail invoked by alias); 28 Dec 2011 09:50:17 -0000 Original-Received: from 62-47-52-13.adsl.highway.telekom.at (EHLO [62.47.52.13]) [62.47.52.13] by mail.gmx.net (mp027) with SMTP; 28 Dec 2011 10:50:17 +0100 X-Authenticated: #14592706 X-Provags-ID: V01U2FsdGVkX18HoZZNzGAHuVqZiWuIdf4Oz5nkFy7ULiWqUaLdKq fWENv7VMxvnsRM User-Agent: Thunderbird 2.0.0.21 (Windows/20090302) In-Reply-To: <4EF8BC0B.6020805@gmx.at> X-Y-GMX-Trusted: 0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list Resent-Date: Wed, 28 Dec 2011 04:54:02 -0500 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:55246 Archived-At: This is a multi-part message in MIME format. --------------000702050504020508070305 Content-Type: text/plain; charset=ISO-8859-15; format=flowed Content-Transfer-Encoding: 7bit I wrote a tentative patch to handle this. Please have a look. Thanks, martin --------------000702050504020508070305 Content-Type: text/plain; name="window-parameters.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="window-parameters.diff" === 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. +frame. This function copies the value of all window parameters listed +by @code{window-persistent-parameters}, see below. @end defun +@defvar window-persistent-parameters +This variable lists all window parameters that shall be saved by +@code{current-window-configuration}, see above, and restored by +@code{set-window-configuration}, see below. 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. + +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. +@end 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 +@code{window-persistent-parameters}, see above, to their values saved in +@var{configuration}. + 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. -@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. + +This function copies the value of all window parameters listed by the +variable @code{window-persistent-parameters}, see above. @end defun +@defvar 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 +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 +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 +@code{window-persistent-parameters}, see above, to their values 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-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 (cond @@ -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)))))))))))) (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 +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), 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)) + 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); --------------000702050504020508070305--