(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.
:group 'desktop
:version "24.4")
-(defcustom desktop-restore-in-current-display nil
+(defcustom desktop-restore-in-current-display t
"Controls how restoring of frames treats displays.
If t, restores frames into the current display.
If nil, restores frames into their original displays (if possible).
Only minor modes for which the name of the buffer-local variable
and the name of the minor mode function are different have to be added to
this table. See also `desktop-minor-mode-handlers'."
- :type 'sexp
+ :type '(alist :key-type (symbol :tag "Minor mode")
+ :value-type (list :tag "Restore function"
+ (choice (const nil) function)))
:group 'desktop)
;;;###autoload
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))
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)
: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."
+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.
+
+This function can save the desktop in either format version
+208 (which only Emacs 25.1 and later can read) or version
+206 (which is readable by any Emacs from version 22.1 onwards).
+By default, it will use the same format the desktop file had when
+it was last saved, or version 208 when writing a fresh desktop
+file.
+
+To upgrade a version 206 file to version 208, call this command
+explicitly with a bare prefix argument: C-u M-x desktop-save.
+You are recommended to do this once you have firmly upgraded to
+Emacs 25.1 (or later). To downgrade a version 208 file to version
+206, use a double command prefix: C-u C-u M-x desktop-save.
+Confirmation will be requested in either case. In a non-interactive
+call, VERSION can be given as an integer, either 206 or 208, which
+will be accepted as the format version in which to save the file
+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)
(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))
"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))
"Restore the state of a set of frames.
This function depends on the value of `desktop-saved-frameset'
being set (usually, by reading it from the desktop)."
- (when (desktop-restoring-frameset-p)
+ (when (and (display-graphic-p) (desktop-restoring-frameset-p))
(frameset-restore desktop-saved-frameset
:reuse-frames (eq desktop-restore-reuses-frames t)
:cleanup-frames (not (eq desktop-restore-reuses-frames 'keep))
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)
(setq command-line-args (delete key command-line-args))
(desktop-save-mode 0)))
(when desktop-save-mode
- ;; People don't expect emacs -nw, or --daemon,
- ;; to create graphical frames (bug#17693).
- ;; TODO perhaps there should be a separate value
- ;; for desktop-restore-frames to control this startup behavior?
- (let ((desktop-restore-frames (and desktop-restore-frames
- initial-window-system
- (not (daemonp)))))
- (desktop-read)
- (setq inhibit-startup-screen t)))))
+ (desktop-read)
+ (setq inhibit-startup-screen t))))
(provide 'desktop)