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.
This commit is contained in:
parent
130d512045
commit
20defc5538
2 changed files with 114 additions and 48 deletions
11
etc/NEWS
11
etc/NEWS
|
@ -315,6 +315,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,
|
||||
|
|
151
lisp/desktop.el
151
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 @@ deletes all frames except the selected one (and its minibuffer frame,
|
|||
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 @@ buffer, which is (in order):
|
|||
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,41 @@ Frames with a non-nil `desktop-dont-save' parameter are not saved."
|
|||
: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)
|
||||
|
@ -1017,12 +1048,34 @@ changed since it was last saved then do not rewrite the file."
|
|||
(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 +1105,7 @@ changed since it was last saved then do not rewrite the file."
|
|||
"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 +1443,8 @@ and try to load that."
|
|||
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)
|
||||
|
|
Loading…
Add table
Reference in a new issue