diff options
| author | Alan Mackenzie | 2016-01-18 13:32:22 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2016-01-18 13:32:22 +0000 |
| commit | 20defc5538de705fc6b39d5a754244e6787db162 (patch) | |
| tree | 0b68d5c295c3f7c0f878b4654955fb6b43ce0962 | |
| parent | 130d512045aa376333b664d58c501b3884187592 (diff) | |
| download | emacs-20defc5538de705fc6b39d5a754244e6787db162.tar.gz emacs-20defc5538de705fc6b39d5a754244e6787db162.zip | |
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.
| -rw-r--r-- | etc/NEWS | 11 | ||||
| -rw-r--r-- | lisp/desktop.el | 151 |
2 files changed, 114 insertions, 48 deletions
| @@ -315,6 +315,17 @@ current package keywords are recognized. Set the new option | |||
| 315 | It's meant for use together with `compile': | 315 | It's meant for use together with `compile': |
| 316 | emacs -batch --eval "(checkdoc-file \"subr.el\")" | 316 | emacs -batch --eval "(checkdoc-file \"subr.el\")" |
| 317 | 317 | ||
| 318 | ** Desktop | ||
| 319 | |||
| 320 | --- | ||
| 321 | *** The desktop format version has been upgraded from 206 to 208. | ||
| 322 | Although Emacs 25.1 can read a version 206 desktop, earlier Emacsen | ||
| 323 | cannot read a version 208 desktop. To upgrade your desktop file, you | ||
| 324 | must explicitly request the upgrade, by C-u M-x desktop-save. You are | ||
| 325 | recommended to do this as soon as you have firmly upgraded to Emacs | ||
| 326 | 25.1 (or later). Should you ever need to downgrade your desktop file | ||
| 327 | to version 206, you can do this with C-u C-u M-x desktop-save. | ||
| 328 | |||
| 318 | +++ | 329 | +++ |
| 319 | ** New function `bookmark-set-no-overwrite' bound to C-x r M. | 330 | ** New function `bookmark-set-no-overwrite' bound to C-x r M. |
| 320 | It raises an error if a bookmark of that name already exists, | 331 | It raises an error if a bookmark of that name already exists, |
diff --git a/lisp/desktop.el b/lisp/desktop.el index cb973c48f8d..e795d9c2300 100644 --- a/lisp/desktop.el +++ b/lisp/desktop.el | |||
| @@ -140,8 +140,15 @@ | |||
| 140 | 140 | ||
| 141 | (defvar desktop-file-version "208" | 141 | (defvar desktop-file-version "208" |
| 142 | "Version number of desktop file format. | 142 | "Version number of desktop file format. |
| 143 | Written into the desktop file and used at desktop read to provide | 143 | Used at desktop read to provide backward compatibility.") |
| 144 | backward compatibility.") | 144 | |
| 145 | (defconst desktop-native-file-version 208 | ||
| 146 | "Format version of the current desktop package, an integer.") | ||
| 147 | (defvar desktop-io-file-version nil | ||
| 148 | "The format version of the current desktop file (an integer) or nil.") | ||
| 149 | ;; Note: Historically, the version number is embedded in the entry for | ||
| 150 | ;; each buffer. It is highly inadvisable for different buffer entries | ||
| 151 | ;; to have different format versions. | ||
| 145 | 152 | ||
| 146 | ;; ---------------------------------------------------------------------------- | 153 | ;; ---------------------------------------------------------------------------- |
| 147 | ;; USER OPTIONS -- settings you might want to play with. | 154 | ;; USER OPTIONS -- settings you might want to play with. |
| @@ -693,6 +700,7 @@ deletes all frames except the selected one (and its minibuffer frame, | |||
| 693 | if different)." | 700 | if different)." |
| 694 | (interactive) | 701 | (interactive) |
| 695 | (desktop-lazy-abort) | 702 | (desktop-lazy-abort) |
| 703 | (setq desktop-io-file-version nil) | ||
| 696 | (dolist (var desktop-globals-to-clear) | 704 | (dolist (var desktop-globals-to-clear) |
| 697 | (if (symbolp var) | 705 | (if (symbolp var) |
| 698 | (eval `(setq-default ,var nil)) | 706 | (eval `(setq-default ,var nil)) |
| @@ -781,44 +789,46 @@ buffer, which is (in order): | |||
| 781 | local variables; | 789 | local variables; |
| 782 | auxiliary information given by `desktop-var-serdes-funs'." | 790 | auxiliary information given by `desktop-var-serdes-funs'." |
| 783 | (set-buffer buffer) | 791 | (set-buffer buffer) |
| 784 | (list | 792 | `( |
| 785 | ;; base name of the buffer; replaces the buffer name if managed by uniquify | 793 | ;; base name of the buffer; replaces the buffer name if managed by uniquify |
| 786 | (and (fboundp 'uniquify-buffer-base-name) (uniquify-buffer-base-name)) | 794 | ,(and (fboundp 'uniquify-buffer-base-name) (uniquify-buffer-base-name)) |
| 787 | ;; basic information | 795 | ;; basic information |
| 788 | (desktop-file-name (buffer-file-name) desktop-dirname) | 796 | ,(desktop-file-name (buffer-file-name) desktop-dirname) |
| 789 | (buffer-name) | 797 | ,(buffer-name) |
| 790 | major-mode | 798 | ,major-mode |
| 791 | ;; minor modes | 799 | ;; minor modes |
| 792 | (let (ret) | 800 | ,(let (ret) |
| 793 | (dolist (minor-mode (mapcar #'car minor-mode-alist) ret) | 801 | (dolist (minor-mode (mapcar #'car minor-mode-alist) ret) |
| 794 | (and (boundp minor-mode) | 802 | (and (boundp minor-mode) |
| 795 | (symbol-value minor-mode) | 803 | (symbol-value minor-mode) |
| 796 | (let* ((special (assq minor-mode desktop-minor-mode-table)) | 804 | (let* ((special (assq minor-mode desktop-minor-mode-table)) |
| 797 | (value (cond (special (cadr special)) | 805 | (value (cond (special (cadr special)) |
| 798 | ((functionp minor-mode) minor-mode)))) | 806 | ((functionp minor-mode) minor-mode)))) |
| 799 | (when value (cl-pushnew value ret)))))) | 807 | (when value (cl-pushnew value ret)))))) |
| 800 | ;; point and mark, and read-only status | 808 | ;; point and mark, and read-only status |
| 801 | (point) | 809 | ,(point) |
| 802 | (list (mark t) mark-active) | 810 | ,(list (mark t) mark-active) |
| 803 | buffer-read-only | 811 | ,buffer-read-only |
| 804 | ;; auxiliary information | 812 | ;; auxiliary information |
| 805 | (when (functionp desktop-save-buffer) | 813 | ,(when (functionp desktop-save-buffer) |
| 806 | (funcall desktop-save-buffer desktop-dirname)) | 814 | (funcall desktop-save-buffer desktop-dirname)) |
| 807 | ;; local variables | 815 | ;; local variables |
| 808 | (let ((loclist (buffer-local-variables)) | 816 | ,(let ((loclist (buffer-local-variables)) |
| 809 | (ll nil)) | 817 | (ll nil)) |
| 810 | (dolist (local desktop-locals-to-save) | 818 | (dolist (local desktop-locals-to-save) |
| 811 | (let ((here (assq local loclist))) | 819 | (let ((here (assq local loclist))) |
| 812 | (cond (here | 820 | (cond (here |
| 813 | (push here ll)) | 821 | (push here ll)) |
| 814 | ((member local loclist) | 822 | ((member local loclist) |
| 815 | (push local ll))))) | 823 | (push local ll))))) |
| 816 | ll) | 824 | ll) |
| 817 | (mapcar (lambda (record) | 825 | ,@(when (>= desktop-io-file-version 208) |
| 818 | (let ((var (car record))) | 826 | (list |
| 819 | (list var | 827 | (mapcar (lambda (record) |
| 820 | (funcall (cadr record) (symbol-value var))))) | 828 | (let ((var (car record))) |
| 821 | desktop-var-serdes-funs))) | 829 | (list var |
| 830 | (funcall (cadr record) (symbol-value var))))) | ||
| 831 | desktop-var-serdes-funs))))) | ||
| 822 | 832 | ||
| 823 | ;; ---------------------------------------------------------------------------- | 833 | ;; ---------------------------------------------------------------------------- |
| 824 | (defun desktop--v2s (value) | 834 | (defun desktop--v2s (value) |
| @@ -983,20 +993,41 @@ Frames with a non-nil `desktop-dont-save' parameter are not saved." | |||
| 983 | :predicate #'desktop--check-dont-save)))) | 993 | :predicate #'desktop--check-dont-save)))) |
| 984 | 994 | ||
| 985 | ;;;###autoload | 995 | ;;;###autoload |
| 986 | (defun desktop-save (dirname &optional release only-if-changed) | 996 | (defun desktop-save (dirname &optional release only-if-changed version) |
| 987 | "Save the desktop in a desktop file. | 997 | "Save the desktop in a desktop file. |
| 988 | Parameter DIRNAME specifies where to save the desktop file. | 998 | Parameter DIRNAME specifies where to save the desktop file. |
| 989 | Optional parameter RELEASE says whether we're done with this desktop. | 999 | Optional parameter RELEASE says whether we're done with this |
| 990 | If ONLY-IF-CHANGED is non-nil, compare the current desktop information | 1000 | desktop. If ONLY-IF-CHANGED is non-nil, compare the current |
| 991 | to that in the desktop file, and if the desktop information has not | 1001 | desktop information to that in the desktop file, and if the |
| 992 | changed since it was last saved then do not rewrite the file." | 1002 | desktop information has not changed since it was last saved then |
| 1003 | do not rewrite the file. | ||
| 1004 | |||
| 1005 | This function can save the desktop in either format version | ||
| 1006 | 208 (which only Emacs 25.1 and later can read) or version | ||
| 1007 | 206 (which is readable by any Emacs from version 22.1 onwards). | ||
| 1008 | By default, it will use the same format the desktop file had when | ||
| 1009 | it was last saved, or version 208 when writing a fresh desktop | ||
| 1010 | file. | ||
| 1011 | |||
| 1012 | To upgrade a version 206 file to version 208, call this command | ||
| 1013 | explicitly with a bare prefix argument: C-u M-x desktop-save. | ||
| 1014 | You are recommended to do this once you have firmly upgraded to | ||
| 1015 | Emacs 25.1 (or later). To downgrade a version 208 file to version | ||
| 1016 | 206, use a double command prefix: C-u C-u M-x desktop-save. | ||
| 1017 | Confirmation will be requested in either case. In a non-interactive | ||
| 1018 | call, VERSION can be given as an integer, either 206 or 208, which | ||
| 1019 | will be accepted as the format version in which to save the file | ||
| 1020 | without further confirmation." | ||
| 993 | (interactive (list | 1021 | (interactive (list |
| 994 | ;; Or should we just use (car desktop-path)? | 1022 | ;; Or should we just use (car desktop-path)? |
| 995 | (let ((default (if (member "." desktop-path) | 1023 | (let ((default (if (member "." desktop-path) |
| 996 | default-directory | 1024 | default-directory |
| 997 | user-emacs-directory))) | 1025 | user-emacs-directory))) |
| 998 | (read-directory-name "Directory to save desktop file in: " | 1026 | (read-directory-name "Directory to save desktop file in: " |
| 999 | default default t)))) | 1027 | default default t)) |
| 1028 | nil | ||
| 1029 | nil | ||
| 1030 | current-prefix-arg)) | ||
| 1000 | (setq desktop-dirname (file-name-as-directory (expand-file-name dirname))) | 1031 | (setq desktop-dirname (file-name-as-directory (expand-file-name dirname))) |
| 1001 | (save-excursion | 1032 | (save-excursion |
| 1002 | (let ((eager desktop-restore-eager) | 1033 | (let ((eager desktop-restore-eager) |
| @@ -1017,12 +1048,34 @@ changed since it was last saved then do not rewrite the file." | |||
| 1017 | (desktop-release-lock) | 1048 | (desktop-release-lock) |
| 1018 | (unless (and new-modtime (desktop-owner)) (desktop-claim-lock))) | 1049 | (unless (and new-modtime (desktop-owner)) (desktop-claim-lock))) |
| 1019 | 1050 | ||
| 1051 | ;; What format are we going to write the file in? | ||
| 1052 | (setq desktop-io-file-version | ||
| 1053 | (cond | ||
| 1054 | ((equal version '(4)) | ||
| 1055 | (if (or (eq desktop-io-file-version 208) | ||
| 1056 | (yes-or-no-p "Save desktop file in format 208 \ | ||
| 1057 | \(Readable by Emacs 25.1 and later only)? ")) | ||
| 1058 | 208 | ||
| 1059 | (or desktop-io-file-version desktop-native-file-version))) | ||
| 1060 | ((equal version '(16)) | ||
| 1061 | (if (or (eq desktop-io-file-version 206) | ||
| 1062 | (yes-or-no-p "Save desktop file in format 206 \ | ||
| 1063 | \(Readable by all Emacs versions since 22.1)? ")) | ||
| 1064 | 206 | ||
| 1065 | (or desktop-io-file-version desktop-native-file-version))) | ||
| 1066 | ((memq version '(206 208)) | ||
| 1067 | version) | ||
| 1068 | ((null desktop-io-file-version) ; As yet, no desktop file exists. | ||
| 1069 | desktop-native-file-version) | ||
| 1070 | (t | ||
| 1071 | desktop-io-file-version))) | ||
| 1072 | |||
| 1020 | (with-temp-buffer | 1073 | (with-temp-buffer |
| 1021 | (insert | 1074 | (insert |
| 1022 | ";; -*- mode: emacs-lisp; coding: emacs-mule; -*-\n" | 1075 | ";; -*- mode: emacs-lisp; coding: emacs-mule; -*-\n" |
| 1023 | desktop-header | 1076 | desktop-header |
| 1024 | ";; Created " (current-time-string) "\n" | 1077 | ";; Created " (current-time-string) "\n" |
| 1025 | ";; Desktop file format version " desktop-file-version "\n" | 1078 | ";; Desktop file format version " (format "%d" desktop-io-file-version) "\n" |
| 1026 | ";; Emacs version " emacs-version "\n") | 1079 | ";; Emacs version " emacs-version "\n") |
| 1027 | (save-excursion (run-hooks 'desktop-save-hook)) | 1080 | (save-excursion (run-hooks 'desktop-save-hook)) |
| 1028 | (goto-char (point-max)) | 1081 | (goto-char (point-max)) |
| @@ -1052,7 +1105,7 @@ changed since it was last saved then do not rewrite the file." | |||
| 1052 | "desktop-create-buffer" | 1105 | "desktop-create-buffer" |
| 1053 | "desktop-append-buffer-args") | 1106 | "desktop-append-buffer-args") |
| 1054 | " " | 1107 | " " |
| 1055 | desktop-file-version) | 1108 | (format "%d" desktop-io-file-version)) |
| 1056 | ;; If there's a non-empty base name, we save it instead of the buffer name | 1109 | ;; If there's a non-empty base name, we save it instead of the buffer name |
| 1057 | (when (and base (not (string= base ""))) | 1110 | (when (and base (not (string= base ""))) |
| 1058 | (setcar (nthcdr 1 l) base)) | 1111 | (setcar (nthcdr 1 l) base)) |
| @@ -1390,6 +1443,8 @@ and try to load that." | |||
| 1390 | compacted-vars | 1443 | compacted-vars |
| 1391 | &rest _unsupported) | 1444 | &rest _unsupported) |
| 1392 | 1445 | ||
| 1446 | (setq desktop-io-file-version file-version) | ||
| 1447 | |||
| 1393 | (let ((desktop-file-version file-version) | 1448 | (let ((desktop-file-version file-version) |
| 1394 | (desktop-buffer-file-name buffer-filename) | 1449 | (desktop-buffer-file-name buffer-filename) |
| 1395 | (desktop-buffer-name buffer-name) | 1450 | (desktop-buffer-name buffer-name) |