all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Alan Mackenzie <acm@muc.de>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 22025@debbugs.gnu.org
Subject: bug#22025: Emacs 25 corrupts Emacs 24 .emacs.desktop.
Date: Thu, 3 Dec 2015 08:40:31 +0000	[thread overview]
Message-ID: <20151203084031.GB2136@acm.fritz.box> (raw)
In-Reply-To: <83egf5j6x2.fsf@gnu.org>

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 <acm@muc.de>

> > > 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).





  reply	other threads:[~2015-12-03  8:40 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-27  8:38 bug#22025: Emacs 25 corrupts Emacs 24 .emacs.desktop Alan Mackenzie
2015-11-27  9:05 ` Eli Zaretskii
2015-11-27  9:47   ` Alan Mackenzie
2015-11-27 10:23     ` Eli Zaretskii
2015-11-27 11:39       ` Alan Mackenzie
2015-11-27 12:27       ` Andy Moreton
2015-12-01 12:19   ` Alan Mackenzie
2015-12-01 15:43     ` Eli Zaretskii
2015-12-01 17:01       ` Alan Mackenzie
2015-12-01 17:46         ` Drew Adams
2015-12-02 12:35           ` Alan Mackenzie
2015-12-02 14:47             ` Drew Adams
2015-12-01 18:46         ` Eli Zaretskii
2015-12-02 11:27           ` Alan Mackenzie
2015-12-02 13:16             ` Andy Moreton
2015-12-02 13:50             ` Eli Zaretskii
2015-12-03  8:40               ` Alan Mackenzie [this message]
2015-12-03 10:30                 ` Eli Zaretskii
2016-01-15 16:18                   ` Alan Mackenzie
2016-01-15 18:31                     ` Eli Zaretskii
2016-01-18 13:37                       ` Alan Mackenzie
     [not found]                 ` <<83mvtrj02w.fsf@gnu.org>
2015-12-03 14:33                   ` Drew Adams
2015-12-03 14:57                     ` Alan Mackenzie
2015-12-03 15:35                       ` Drew Adams
2015-12-03 15:44                         ` Alan Mackenzie
2019-09-29 21:17 ` Stefan Kangas
     [not found] <<20151127083837.GB1782@acm.fritz.box>

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=20151203084031.GB2136@acm.fritz.box \
    --to=acm@muc.de \
    --cc=22025@debbugs.gnu.org \
    --cc=eliz@gnu.org \
    /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.