From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Alan Mackenzie Newsgroups: gmane.emacs.bugs Subject: bug#22025: Emacs 25 corrupts Emacs 24 .emacs.desktop. Date: Thu, 3 Dec 2015 08:40:31 +0000 Message-ID: <20151203084031.GB2136@acm.fritz.box> References: <20151127083837.GB1782@acm.fritz.box> <83r3jbstgq.fsf@gnu.org> <20151201121940.GA2611@acm.fritz.box> <83a8pukwdq.fsf@gnu.org> <20151201170138.GB2611@acm.fritz.box> <83zixuj9b8.fsf@gnu.org> <20151202112722.GA2318@acm.fritz.box> <83egf5j6x2.fsf@gnu.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: ger.gmane.org 1449131966 20706 80.91.229.3 (3 Dec 2015 08:39:26 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Thu, 3 Dec 2015 08:39:26 +0000 (UTC) Cc: 22025@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Thu Dec 03 09:39:14 2015 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1a4PQ1-00089j-Kx for geb-bug-gnu-emacs@m.gmane.org; Thu, 03 Dec 2015 09:39:13 +0100 Original-Received: from localhost ([::1]:34016 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a4PQ0-0002sx-MS for geb-bug-gnu-emacs@m.gmane.org; Thu, 03 Dec 2015 03:39:12 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:55583) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a4PPv-0002oZ-2p for bug-gnu-emacs@gnu.org; Thu, 03 Dec 2015 03:39:08 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a4PPq-0005Mx-Sc for bug-gnu-emacs@gnu.org; Thu, 03 Dec 2015 03:39:06 -0500 Original-Received: from debbugs.gnu.org ([208.118.235.43]:47147) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a4PPq-0005Ms-PB for bug-gnu-emacs@gnu.org; Thu, 03 Dec 2015 03:39:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.80) (envelope-from ) id 1a4PPq-0000Pm-CN for bug-gnu-emacs@gnu.org; Thu, 03 Dec 2015 03:39:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Alan Mackenzie Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 03 Dec 2015 08:39:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 22025 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 22025-submit@debbugs.gnu.org id=B22025.14491319101557 (code B ref 22025); Thu, 03 Dec 2015 08:39:02 +0000 Original-Received: (at 22025) by debbugs.gnu.org; 3 Dec 2015 08:38:30 +0000 Original-Received: from localhost ([127.0.0.1]:36855 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1a4PPJ-0000P2-Rx for submit@debbugs.gnu.org; Thu, 03 Dec 2015 03:38:30 -0500 Original-Received: from mail.muc.de ([193.149.48.3]:42659) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1a4PPF-0000Ok-SK for 22025@debbugs.gnu.org; Thu, 03 Dec 2015 03:38:27 -0500 Original-Received: (qmail 23486 invoked by uid 3782); 3 Dec 2015 08:38:23 -0000 Original-Received: from acm.muc.de (p579E903F.dip0.t-ipconnect.de [87.158.144.63]) by colin.muc.de (tmda-ofmipd) with ESMTP; Thu, 03 Dec 2015 09:38:22 +0100 Original-Received: (qmail 2530 invoked by uid 1000); 3 Dec 2015 08:40:31 -0000 Content-Disposition: inline In-Reply-To: <83egf5j6x2.fsf@gnu.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-Delivery-Agent: TMDA/1.1.12 (Macallan) X-Primary-Address: acm@muc.de X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 208.118.235.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:109546 Archived-At: Hello, Eli. On Wed, Dec 02, 2015 at 03:50:49PM +0200, Eli Zaretskii wrote: > > Date: Wed, 2 Dec 2015 11:27:22 +0000 > > Cc: 22025@debbugs.gnu.org > > From: Alan Mackenzie > > > I think NEWS is the appropriate place to alert them to this. > > I'm a bit wary about NEWS. How many people actually read it thoroughly? > > At each new release, I try to read NEWS, but my eyes start glazing over > > before I even get half way through. > If they don't pay attention, they will stay with the old format. Do > they lose much? They will lose the mark ring being save. Precisely that. Possibly more information will be added to buffer entries in the future (version 208 seems designed to allow that possibility whilst staying backward compatible). > > But that aside, how about the following NEWS entry (to be followed by > > actual code)? > LGTM, thanks. OK, here is the patch. Do you think I should solicit a review from somebody else before I commit it to emacs-25? Desktop: protect users against inadvertant upgrading of desktop file. An upgraded (version 208) desktop file cannot be read in Emacs < 25. * etc/NEWS: Add an entry about upgrading a desktop file. * lisp/desktop.el (desktop-file-version): Amend doc string. (desktop-native-file-version, desktop-io-file-version): new variables. (desktop-clear): Set desktop-io-file-version to nil. (desktop-buffer-info): make the presence of the last item on the list conditional on (>= desktop-io-file-version 208). (desktop-save): Add extra parameter VERSION to take user's C-u or C-u C-u. Amend the doc string. Add code to determine the output file version. (desktop-create-buffer): Set desktop-io-file-version to the input file's version. diff --git a/etc/NEWS b/etc/NEWS index a18c9ce..e7439fd 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -371,6 +371,17 @@ current package keywords are recognized. Set the new option It's meant for use together with `compile': emacs -batch --eval "(checkdoc-file \"subr.el\")" +** Desktop + +--- +*** The desktop format version has been upgraded from 206 to 208. +Although Emacs 25.1 can read a version 206 desktop, earlier Emacsen +cannot read a version 208 desktop. To upgrade your desktop file, you +must explicitly request the upgrade, by C-u M-x desktop-save. You are +recommended to do this as soon as you have firmly upgraded to Emacs +25.1 (or later). Should you ever need to downgrade your desktop file +to version 206, you can do this with C-u C-u M-x desktop-save. + ** New function `bookmark-set-no-overwrite' bound to C-x r M. It raises an error if a bookmark of that name already exists, unlike `bookmark-set' which silently updates an existing bookmark. diff --git a/lisp/desktop.el b/lisp/desktop.el index 5a709b9..ee7a7ae 100644 --- a/lisp/desktop.el +++ b/lisp/desktop.el @@ -140,8 +140,15 @@ (defvar desktop-file-version "208" "Version number of desktop file format. -Written into the desktop file and used at desktop read to provide -backward compatibility.") +Used at desktop read to provide backward compatibility.") + +(defconst desktop-native-file-version 208 + "Format version of the current desktop package, an integer.") +(defvar desktop-io-file-version nil + "The format version of the current desktop file (an integer) or nil.") +;; Note: Historically, the version number is embedded in the entry for +;; each buffer. It is highly inadvisable for different buffer entries +;; to have different format versions. ;; ---------------------------------------------------------------------------- ;; USER OPTIONS -- settings you might want to play with. @@ -693,6 +700,7 @@ desktop-clear if different)." (interactive) (desktop-lazy-abort) + (setq desktop-io-file-version nil) (dolist (var desktop-globals-to-clear) (if (symbolp var) (eval `(setq-default ,var nil)) @@ -781,44 +789,46 @@ desktop-buffer-info local variables; auxiliary information given by `desktop-var-serdes-funs'." (set-buffer buffer) - (list - ;; base name of the buffer; replaces the buffer name if managed by uniquify - (and (fboundp 'uniquify-buffer-base-name) (uniquify-buffer-base-name)) - ;; basic information - (desktop-file-name (buffer-file-name) desktop-dirname) - (buffer-name) - major-mode - ;; minor modes - (let (ret) - (dolist (minor-mode (mapcar #'car minor-mode-alist) ret) - (and (boundp minor-mode) - (symbol-value minor-mode) - (let* ((special (assq minor-mode desktop-minor-mode-table)) - (value (cond (special (cadr special)) - ((functionp minor-mode) minor-mode)))) - (when value (cl-pushnew value ret)))))) - ;; point and mark, and read-only status - (point) - (list (mark t) mark-active) - buffer-read-only - ;; auxiliary information - (when (functionp desktop-save-buffer) - (funcall desktop-save-buffer desktop-dirname)) - ;; local variables - (let ((loclist (buffer-local-variables)) - (ll nil)) - (dolist (local desktop-locals-to-save) - (let ((here (assq local loclist))) - (cond (here - (push here ll)) - ((member local loclist) - (push local ll))))) - ll) - (mapcar (lambda (record) - (let ((var (car record))) - (list var - (funcall (cadr record) (symbol-value var))))) - desktop-var-serdes-funs))) + `( + ;; base name of the buffer; replaces the buffer name if managed by uniquify + ,(and (fboundp 'uniquify-buffer-base-name) (uniquify-buffer-base-name)) + ;; basic information + ,(desktop-file-name (buffer-file-name) desktop-dirname) + ,(buffer-name) + ,major-mode + ;; minor modes + ,(let (ret) + (dolist (minor-mode (mapcar #'car minor-mode-alist) ret) + (and (boundp minor-mode) + (symbol-value minor-mode) + (let* ((special (assq minor-mode desktop-minor-mode-table)) + (value (cond (special (cadr special)) + ((functionp minor-mode) minor-mode)))) + (when value (cl-pushnew value ret)))))) + ;; point and mark, and read-only status + ,(point) + ,(list (mark t) mark-active) + ,buffer-read-only + ;; auxiliary information + ,(when (functionp desktop-save-buffer) + (funcall desktop-save-buffer desktop-dirname)) + ;; local variables + ,(let ((loclist (buffer-local-variables)) + (ll nil)) + (dolist (local desktop-locals-to-save) + (let ((here (assq local loclist))) + (cond (here + (push here ll)) + ((member local loclist) + (push local ll))))) + ll) + ,@(when (>= desktop-io-file-version 208) + (list + (mapcar (lambda (record) + (let ((var (car record))) + (list var + (funcall (cadr record) (symbol-value var))))) + desktop-var-serdes-funs))))) ;; ---------------------------------------------------------------------------- (defun desktop--v2s (value) @@ -983,20 +993,33 @@ desktop-save-frameset :predicate #'desktop--check-dont-save)))) ;;;###autoload -(defun desktop-save (dirname &optional release only-if-changed) +(defun desktop-save (dirname &optional release only-if-changed version) "Save the desktop in a desktop file. Parameter DIRNAME specifies where to save the desktop file. Optional parameter RELEASE says whether we're done with this desktop. If ONLY-IF-CHANGED is non-nil, compare the current desktop information to that in the desktop file, and if the desktop information has not -changed since it was last saved then do not rewrite the file." +changed since it was last saved then do not rewrite the file. + +When called interactively, a bare command prefix, C-u, will cause +the desktop file to be saved in format version 208 (which only +Emacs 25.1 and later can read). A double command prefix, C-u +C-u, will save the file in version 206 (readable by any Emacs +from version 22.1 onwards). Confirmation will be requested in +either case. In a non-interactive call, VERSION can be given as +either 206 or 208, and this will be accepted as the format +version in which to save the desktop without further +confirmation." (interactive (list ;; Or should we just use (car desktop-path)? (let ((default (if (member "." desktop-path) default-directory user-emacs-directory))) (read-directory-name "Directory to save desktop file in: " - default default t)))) + default default t)) + nil + nil + current-prefix-arg)) (setq desktop-dirname (file-name-as-directory (expand-file-name dirname))) (save-excursion (let ((eager desktop-restore-eager) @@ -1017,12 +1040,34 @@ desktop-save (desktop-release-lock) (unless (and new-modtime (desktop-owner)) (desktop-claim-lock))) + ;; What format are we going to write the file in? + (setq desktop-io-file-version + (cond + ((equal version '(4)) + (if (or (eq desktop-io-file-version 208) + (yes-or-no-p "Save desktop file in format 208 \ +\(Readable by Emacs 25.1 and later only)? ")) + 208 + (or desktop-io-file-version desktop-native-file-version))) + ((equal version '(16)) + (if (or (eq desktop-io-file-version 206) + (yes-or-no-p "Save desktop file in format 206 \ +\(Readable by all Emacs versions since 22.1)? ")) + 206 + (or desktop-io-file-version desktop-native-file-version))) + ((memq version '(206 208)) + version) + ((null desktop-io-file-version) ; As yet, no desktop file exists. + desktop-native-file-version) + (t + desktop-io-file-version))) + (with-temp-buffer (insert ";; -*- mode: emacs-lisp; coding: emacs-mule; -*-\n" desktop-header ";; Created " (current-time-string) "\n" - ";; Desktop file format version " desktop-file-version "\n" + ";; Desktop file format version " (format "%d" desktop-io-file-version) "\n" ";; Emacs version " emacs-version "\n") (save-excursion (run-hooks 'desktop-save-hook)) (goto-char (point-max)) @@ -1052,7 +1097,7 @@ desktop-save "desktop-create-buffer" "desktop-append-buffer-args") " " - desktop-file-version) + (format "%d" desktop-io-file-version)) ;; If there's a non-empty base name, we save it instead of the buffer name (when (and base (not (string= base ""))) (setcar (nthcdr 1 l) base)) @@ -1390,6 +1435,8 @@ desktop-create-buffer compacted-vars &rest _unsupported) + (setq desktop-io-file-version file-version) + (let ((desktop-file-version file-version) (desktop-buffer-file-name buffer-filename) (desktop-buffer-name buffer-name) -- Alan Mackenzie (Nuremberg, Germany).