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: Tue, 1 Dec 2015 12:19:41 +0000	[thread overview]
Message-ID: <20151201121940.GA2611@acm.fritz.box> (raw)
In-Reply-To: <83r3jbstgq.fsf@gnu.org>

On Fri, Nov 27, 2015 at 11:05:25AM +0200, Eli Zaretskii wrote:
> > Date: Fri, 27 Nov 2015 08:38:37 +0000
> > From: Alan Mackenzie <acm@muc.de>

> > Emacs 25 has read a version 206 .desktop file, but written a version 208
> > file on termination.  Emacs 24 cannot execute this version.

> > There was no yes-or-no-p asking "are you sure you want to convert your
> > desktop to a format incompatible with previous Emacs versions?".

> > Manually restoring a .desktop to version 206 is fraught with
> > difficulties, even for somebody (myself) who understands the issues
> > reasonably well, and has an old version of .desktop saved "just in
> > case".

> > Recommendation
> > --------------

> > Emacs 25, having loaded a version 206 .desktop, should save it in the
> > same format until the user has positively consented to it being
> > converted to version 208.

> This would be a nice enhancement, but it certainly isn't a bug in my
> book.

> Of course, if making that happen is relatively easy, it would be good
> to have such a compatibility mode.  Patches welcome.

OK, here is a patch.  It introduces a customizable variable,
`desktop-version-strategy' which specifies in which version (206 or 208),
the desktop file should be saved.  Until that variable is set to non-nil,
the user is prompted each time the desktop is loaded.  She is given the
opportunity at that time to customize it immediately via a `yes-or-no-p'.




diff --git a/lisp/desktop.el b/lisp/desktop.el
index 5a709b9..e5b4395 100644
--- a/lisp/desktop.el
+++ b/lisp/desktop.el
@@ -143,6 +143,16 @@ desktop-file-version
 Written into the desktop file and 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-infile-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.
+(defvar desktop-outfile-version nil
+  "The format version in which the desktop file will next be written, or nil")
+
 ;; ----------------------------------------------------------------------------
 ;; USER OPTIONS -- settings you might want to play with.
 ;; ----------------------------------------------------------------------------
@@ -240,6 +250,19 @@ desktop-load-locked-desktop
   :group 'desktop
   :version "22.2")
 
+(defcustom desktop-version-strategy nil
+  "Strategy to chose format version when writing .emacs.desktop file.
+Version 206 is compatible with Emacs 22.x, 23.x and 24.x, and also with Emacs 25.x.
+Version 208 is enhanced, but incompatible with Emacs 24.x and earlier."
+  :type '(radio
+          (const :tag "Keep current format, and prompt user again when there's \
+an old format at next desktop load." nil)
+          (const :tag "Keep current format, but don't prompt the user again." t)
+          (const :tag "Save desktop file in format 206 (compatible with Emacs <= 24)." 206)
+          (const :tag "Save desktop file in format 208 (Emacs >= 25)." 208))
+  :group 'desktop
+  :version "25.1")
+
 (define-obsolete-variable-alias 'desktop-basefilename
                                 'desktop-base-file-name "22.1")
 
@@ -781,44 +804,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-outfile-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)
@@ -1017,12 +1042,22 @@ 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-outfile-version
+              (cond
+               ((memq desktop-version-strategy '(208 206))
+                desktop-version-strategy)
+               (desktop-infile-version)
+               (desktop-outfile-version)
+               (t                    ; As yet, no desktop file exists.
+                desktop-native-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-outfile-version) "\n"
 	   ";; Emacs version " emacs-version "\n")
 	  (save-excursion (run-hooks 'desktop-save-hook))
 	  (goto-char (point-max))
@@ -1052,7 +1087,7 @@ desktop-save
 			    "desktop-create-buffer"
 			  "desktop-append-buffer-args")
 			" "
-			desktop-file-version)
+			(format "%d" desktop-outfile-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))
@@ -1121,6 +1156,44 @@ desktop-first-buffer
 (defvar desktop-buffer-ok-count)
 (defvar desktop-buffer-fail-count)
 
+;; ----------------------------------------------------------------------------
+;; Instruct and prompt the user about desktop format version change.
+(defvar desktop-customize-strategy-flag nil
+  "Non-nil when the user has requested cutomization of `desktop-version-strategy'")
+
+(defun desktop-warn-about-and-prompt-for-strategy ()
+  "Warn the user that her desktop file is in an old format, and
+prompt her to customize `desktop-version-strategy'."
+  (save-window-excursion
+    (with-output-to-temp-buffer "*Desktop Format Strategy*"
+      (mapc
+       #'princ
+       `("Your desktop file appears to be in an old format "
+         ,(format "%d" desktop-infile-version)
+         ",\nwhich Emacs "
+         ,(format "%s" emacs-version)
+         " should be able to read successfully.\n\n"
+         "Until you configure Emacs to deal with this, you will be\n"
+         "prompted like this each time you load your desktop.\n\n"
+         "You can chose to preserve the original format of your desktop file,\n"
+         "always to set the format to version 206 (which dates back to Emacs 22.1)\n"
+         "or always to set it to version 208 (the new Emacs 25.x format).\n\n"
+         "BE AWARE THAT Emacs 24.x AND EARLIER CANNOT READ A VERSION 208\n"
+         "DESKTOP FILE!\n\n"
+         "Customize `desktop-version-strategy' to make this choice.\n"
+         "You can do this now (after your buffers have been loaded), or at\n"
+         "any later time.\n\n"
+         "You are recommended to set this user option to version 208 as soon\n"
+         "as you have firmly upgraded to Emacs 25.1 (or later), so as to enjoy\n"
+         "the enhancements which version 208 provides.\n")))
+
+    (setq desktop-customize-strategy-flag
+          (condition-case nil ; Prevent C-g aborting the desktop load.
+              (yes-or-no-p "Customize desktop-version-strategy now \
+\(after buffers are loaded)? ")
+            (quit nil)))
+    (kill-buffer "*Desktop Format Strategy*")))
+
 ;; FIXME Interactively, this should have the option to prompt for dirname.
 ;;;###autoload
 (defun desktop-read (&optional dirname)
@@ -1230,6 +1303,11 @@ desktop-read
 				  (set-window-next-buffers window nil))))
  	    (setq desktop-saved-frameset nil)
 	    (if desktop-autosave-was-enabled (desktop-auto-save-enable))
+
+            ;; Has the user requested to configure `desktop-version-strategy'?
+            (when desktop-customize-strategy-flag
+              (setq desktop-customize-strategy-flag nil)
+              (customize-variable 'desktop-version-strategy))
 	    t))
       ;; No desktop file found.
       (let ((default-directory desktop-dirname))
@@ -1400,6 +1478,17 @@ desktop-create-buffer
 	(desktop-buffer-read-only   buffer-readonly)
 	(desktop-buffer-misc	    buffer-misc)
 	(desktop-buffer-locals	    buffer-locals))
+
+    ;; If this is the first buffer of the session, and the user
+    ;; appears to have just updated to the current Emacs version, warn
+    ;; her about the change in the desktop file format, and prompt her
+    ;; to set `desktop-version-strategy.
+    (when (null desktop-infile-version)
+      (setq desktop-infile-version file-version)
+      (when (and (null desktop-version-strategy)
+                 (/= desktop-infile-version desktop-native-file-version))
+        (desktop-warn-about-and-prompt-for-strategy)))
+
     ;; To make desktop files with relative file names possible, we cannot
     ;; allow `default-directory' to change. Therefore we save current buffer.
     (save-current-buffer


-- 
Alan Mackenzie (Nuremberg, Germany).





  parent reply	other threads:[~2015-12-01 12:19 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 [this message]
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
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=20151201121940.GA2611@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.