bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#22025: Emacs 25 corrupts Emacs 24 .emacs.desktop.


From: Alan Mackenzie
Subject: bug#22025: Emacs 25 corrupts Emacs 24 .emacs.desktop.
Date: Tue, 1 Dec 2015 12:19:41 +0000
User-agent: Mutt/1.5.23 (2014-03-12)

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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]