aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Hansen2004-04-21 20:53:35 +0000
committerLars Hansen2004-04-21 20:53:35 +0000
commite5780ae17ec1b3ef148e26911bff2b2baa4dbe8c (patch)
treeea396468fa96ac53578e46e45da292f97a9f4b8d
parent31b4c8480936d1b189cf005a9fa9a4e8d20e8ed4 (diff)
downloademacs-e5780ae17ec1b3ef148e26911bff2b2baa4dbe8c.tar.gz
emacs-e5780ae17ec1b3ef148e26911bff2b2baa4dbe8c.zip
(desktop-buffer-mode-handlers): New variabel. Alist
of major mode specific functions to restore a desktop buffer. (desktop-buffer-handlers): Make variabel obsolete. (desktop-create-buffer): Use desktop-buffer-mode-handlers. Catch errors signaled in handlers. Update buffer count. Evaluate desktop-buffer-point. (desktop-buffer-dired): Rename to dired-restore-desktop-buffer and move to dired.el. (desktop-buffer-info): Rename to Info-restore-desktop-buffer and move to info.el. (desktop-buffer-rmail): Rename to rmail-restore-desktop-buffer and move to mail/rmail.el. (desktop-buffer-mh): Rename to mh-restore-desktop-buffer and move to mh-e/mh-e.el. (desktop-buffer-file): Rename to desktop-restore-file-buffer. An fail, print message (to message buffer) even if desktop-missing-file-warning is nil. (desktop-buffer-misc-data-function): New buffer local variable. Function returning major mode specific data. (desktop-buffer-misc-functions): Make variable obsolete. (desktop-save): Use desktop-buffer-misc-data-function. (desktop-buffer-dired-misc-data): Rename to dired-desktop-buffer-misc-data and move to dired.el. (desktop-buffer-info-misc-data): Rename to Info-desktop-buffer-misc-data and move to info.el. (desktop-read): Add message about number of buffers restored/failed.
-rw-r--r--lisp/desktop.el240
1 files changed, 91 insertions, 149 deletions
diff --git a/lisp/desktop.el b/lisp/desktop.el
index beac1f39005..5589097dfde 100644
--- a/lisp/desktop.el
+++ b/lisp/desktop.el
@@ -83,12 +83,6 @@
83 83
84;;; Code: 84;;; Code:
85 85
86;; Make the compilation more silent
87(eval-when-compile
88 ;; We use functions from these modules
89 ;; We can't (require 'mh-e) since that wants to load something.
90 (mapcar 'require '(info dired reporter)))
91
92(defvar desktop-file-version "206" 86(defvar desktop-file-version "206"
93 "Version number of desktop file format. 87 "Version number of desktop file format.
94Written into the desktop file and used at desktop read to provide 88Written into the desktop file and used at desktop read to provide
@@ -253,8 +247,9 @@ The variables are saved only when they really are local."
253(defcustom desktop-buffer-modes-to-save 247(defcustom desktop-buffer-modes-to-save
254 '(Info-mode rmail-mode) 248 '(Info-mode rmail-mode)
255 "If a buffer is of one of these major modes, save the buffer state. 249 "If a buffer is of one of these major modes, save the buffer state.
256It is up to the functions in `desktop-buffer-handlers' to decide 250This applies to buffers not visiting a file and not beeing a dired buffer.
257whether the buffer should be recreated or not, and how." 251Modes specified here must have a handler in `desktop-buffer-mode-handlers'
252to be restored."
258 :type '(repeat symbol) 253 :type '(repeat symbol)
259 :group 'desktop) 254 :group 'desktop)
260 255
@@ -272,53 +267,59 @@ Possible values are:
272 :type '(choice (const absolute) (const tilde) (const local)) 267 :type '(choice (const absolute) (const tilde) (const local))
273 :group 'desktop) 268 :group 'desktop)
274 269
275(defcustom desktop-buffer-misc-functions 270;;;###autoload
276 '(desktop-buffer-info-misc-data 271(defvar desktop-buffer-misc-data-function nil
277 desktop-buffer-dired-misc-data) 272 "Function returning major mode specific data for desktop file.
278 "*Functions used to determine auxiliary information for a buffer. 273This variable becomes buffer local when set.
279These functions are called by `desktop-save' in order, with no 274The function specified is called by `desktop-save', with argument
280arguments. If a function returns non-nil, its value is saved along 275DESKTOP-DIRNAME. If it returns non-nil, its value is saved along
281with the state of the buffer for which it was called; no further 276with the state of the buffer for which it was called.
282functions will be called.
283 277
284When file names are returned, they should be formatted using the call 278When file names are returned, they should be formatted using the call
285\"(desktop-file-name FILE-NAME dirname)\". 279\"(desktop-file-name FILE-NAME DESKTOP-DIRNAME)\".
286 280
287Later, when `desktop-read' restores buffers, each of the functions in 281Later, when `desktop-read' calls a function in `desktop-buffer-mode-handlers'
288`desktop-buffer-handlers' will have access to a buffer local variable, 282to restore the buffer, the auxiliary information is passed as argument.")
289named `desktop-buffer-misc', whose value is what the function in 283(make-variable-buffer-local 'desktop-buffer-misc-data-function)
290`desktop-buffer-misc-functions' returned." 284(make-obsolete-variable 'desktop-buffer-misc-functions
291 :type '(repeat function) 285 'desktop-buffer-misc-data-function)
292 :group 'desktop)
293 286
294(defcustom desktop-buffer-handlers 287(defcustom desktop-buffer-mode-handlers '(
295 '(desktop-buffer-dired 288 (dired-mode . dired-restore-desktop-buffer)
296 desktop-buffer-rmail 289 (rmail-mode . rmail-restore-desktop-buffer)
297 desktop-buffer-mh 290 (mh-folder-mode . mh-restore-desktop-buffer)
298 desktop-buffer-info 291 (Info-mode . Info-restore-desktop-buffer))
299 desktop-buffer-file) 292 "Alist of major mode specific functions to restore a desktop buffer.
300 "*Functions called by `desktop-read' in order to create a buffer. 293Functions are called by `desktop-read'. List elements must have the form
301The functions are called without explicit parameters but can use the 294\(MAJOR-MODE . FUNCTION).
302following variables: 295
296Buffers with a major mode not specified here, are restored by the default
297handler `desktop-restore-file-buffer'.
298
299Handlers are called with parameters
303 300
304 desktop-file-version
305 desktop-buffer-file-name 301 desktop-buffer-file-name
306 desktop-buffer-name 302 desktop-buffer-name
303 desktop-buffer-misc
304
305Furthermore, they may use the following variables:
306
307 desktop-file-version
307 desktop-buffer-major-mode 308 desktop-buffer-major-mode
308 desktop-buffer-minor-modes 309 desktop-buffer-minor-modes
309 desktop-buffer-point 310 desktop-buffer-point
310 desktop-buffer-mark 311 desktop-buffer-mark
311 desktop-buffer-read-only 312 desktop-buffer-read-only
312 desktop-buffer-misc
313 desktop-buffer-locals 313 desktop-buffer-locals
314 314
315If one function returns non-nil, no further functions are called. 315If a handler returns a buffer, then the saved mode settings
316If the function returns a buffer, then the saved mode settings
317and variable values for that buffer are copied into it." 316and variable values for that buffer are copied into it."
318 :type '(repeat function) 317 :type 'alist
319 :group 'desktop) 318 :group 'desktop)
320 319
321(put 'desktop-buffer-handlers 'risky-local-variable t) 320(put 'desktop-buffer-mode-handlers 'risky-local-variable t)
321(make-obsolete-variable 'desktop-buffer-handlers
322 'desktop-buffer-mode-handlers)
322 323
323(defcustom desktop-minor-mode-table 324(defcustom desktop-minor-mode-table
324 '((auto-fill-function auto-fill-mode) 325 '((auto-fill-function auto-fill-mode)
@@ -608,7 +609,9 @@ See also `desktop-base-file-name'."
608 (point) 609 (point)
609 (list (mark t) mark-active) 610 (list (mark t) mark-active)
610 buffer-read-only 611 buffer-read-only
611 (run-hook-with-args-until-success 'desktop-buffer-misc-functions) 612 ;; Auxiliary information
613 (when desktop-buffer-misc-data-function
614 (funcall desktop-buffer-misc-data-function dirname))
612 (let ((locals desktop-locals-to-save) 615 (let ((locals desktop-locals-to-save)
613 (loclist (buffer-local-variables)) 616 (loclist (buffer-local-variables))
614 (ll)) 617 (ll))
@@ -703,7 +706,9 @@ It returns t if a desktop file was loaded, nil otherwise."
703 "~")))) 706 "~"))))
704 (if (file-exists-p (expand-file-name desktop-base-file-name desktop-dirname)) 707 (if (file-exists-p (expand-file-name desktop-base-file-name desktop-dirname))
705 ;; Desktop file found, process it. 708 ;; Desktop file found, process it.
706 (let ((desktop-first-buffer nil)) 709 (let ((desktop-first-buffer nil)
710 (desktop-buffer-ok-count 0)
711 (desktop-buffer-fail-count 0))
707 ;; Evaluate desktop buffer. 712 ;; Evaluate desktop buffer.
708 (load (expand-file-name desktop-base-file-name desktop-dirname) t t t) 713 (load (expand-file-name desktop-base-file-name desktop-dirname) t t t)
709 ;; `desktop-create-buffer' puts buffers at end of the buffer list. 714 ;; `desktop-create-buffer' puts buffers at end of the buffer list.
@@ -715,7 +720,12 @@ It returns t if a desktop file was loaded, nil otherwise."
715 (run-hooks 'desktop-delay-hook) 720 (run-hooks 'desktop-delay-hook)
716 (setq desktop-delay-hook nil) 721 (setq desktop-delay-hook nil)
717 (run-hooks 'desktop-after-read-hook) 722 (run-hooks 'desktop-after-read-hook)
718 (message "Desktop loaded.") 723 (message "Desktop: %d buffer%s restored%s."
724 desktop-buffer-ok-count
725 (if (= 1 desktop-buffer-ok-count) "" "s")
726 (if (< 0 desktop-buffer-fail-count)
727 (format ", %d failed to restore" desktop-buffer-fail-count)
728 ""))
719 t) 729 t)
720 ;; No desktop file found. 730 ;; No desktop file found.
721 (desktop-clear) 731 (desktop-clear)
@@ -772,106 +782,21 @@ directory DIRNAME."
772 (desktop-read desktop-dirname)) 782 (desktop-read desktop-dirname))
773 783
774;; ---------------------------------------------------------------------------- 784;; ----------------------------------------------------------------------------
775;; Note: the following functions use the dynamic variable binding in Lisp. 785(defun desktop-restore-file-buffer (desktop-buffer-file-name
776;; 786 desktop-buffer-name
777 787 desktop-buffer-misc)
778(eval-when-compile ; Just to silence the byte compiler 788 "Restore a file buffer."
779 (defvar desktop-file-version) 789 (eval-when-compile ; Just to silence the byte compiler
780 (defvar desktop-buffer-file-name) 790 (defvar desktop-buffer-major-mode)
781 (defvar desktop-buffer-name) 791 (defvar desktop-buffer-locals))
782 (defvar desktop-buffer-major-mode)
783 (defvar desktop-buffer-minor-modes)
784 (defvar desktop-buffer-point)
785 (defvar desktop-buffer-mark)
786 (defvar desktop-buffer-read-only)
787 (defvar desktop-buffer-misc)
788 (defvar desktop-buffer-locals)
789)
790
791(defun desktop-buffer-info-misc-data ()
792 (if (eq major-mode 'Info-mode)
793 (list Info-current-file
794 Info-current-node)))
795
796;; ----------------------------------------------------------------------------
797(defun desktop-buffer-dired-misc-data ()
798 (when (eq major-mode 'dired-mode)
799 (eval-when-compile (defvar dirname))
800 (cons
801 ;; Value of `dired-directory'.
802 (if (consp dired-directory)
803 ;; Directory name followed by list of files.
804 (cons (desktop-file-name (car dired-directory) dirname) (cdr dired-directory))
805 ;; Directory name, optionally with with shell wildcard.
806 (desktop-file-name dired-directory dirname))
807 ;; Subdirectories in `dired-subdir-alist'.
808 (cdr
809 (nreverse
810 (mapcar
811 (function (lambda (f) (desktop-file-name (car f) dirname)))
812 dired-subdir-alist))))))
813
814;; ----------------------------------------------------------------------------
815(defun desktop-buffer-info () "Load an info file."
816 (if (eq 'Info-mode desktop-buffer-major-mode)
817 (progn
818 (let ((first (nth 0 desktop-buffer-misc))
819 (second (nth 1 desktop-buffer-misc)))
820 (when (and first second)
821 (require 'info)
822 (with-no-warnings
823 (Info-find-node first second))
824 (current-buffer))))))
825
826;; ----------------------------------------------------------------------------
827(eval-when-compile (defvar rmail-buffer)) ; Just to silence the byte compiler.
828(defun desktop-buffer-rmail () "Load an RMAIL file."
829 (if (eq 'rmail-mode desktop-buffer-major-mode)
830 (condition-case error
831 (progn (rmail-input desktop-buffer-file-name)
832 (if (eq major-mode 'rmail-mode)
833 (current-buffer)
834 rmail-buffer))
835 (file-locked
836 (kill-buffer (current-buffer))
837 'ignored))))
838
839;; ----------------------------------------------------------------------------
840(defun desktop-buffer-mh () "Load a folder in the mh system."
841 (if (eq 'mh-folder-mode desktop-buffer-major-mode)
842 (with-no-warnings
843 (mh-find-path)
844 (mh-visit-folder desktop-buffer-name)
845 (current-buffer))))
846
847;; ----------------------------------------------------------------------------
848(defun desktop-buffer-dired () "Load a directory using dired."
849 (if (eq 'dired-mode desktop-buffer-major-mode)
850 ;; First element of `desktop-buffer-misc' is the value of `dired-directory'.
851 ;; This value is a directory name, optionally with with shell wildcard or
852 ;; a directory name followed by list of files.
853 (let* ((dired-dir (car desktop-buffer-misc))
854 (dir (if (consp dired-dir) (car dired-dir) dired-dir)))
855 (if (file-directory-p (file-name-directory dir))
856 (progn
857 (dired dired-dir)
858 ;; The following elements of `desktop-buffer-misc' are the keys
859 ;; from `dired-subdir-alist'.
860 (mapcar 'dired-maybe-insert-subdir (cdr desktop-buffer-misc))
861 (current-buffer))
862 (message "Directory %s no longer exists." dir)
863 (sit-for 1)
864 'ignored))))
865
866;; ----------------------------------------------------------------------------
867(defun desktop-buffer-file ()
868 "Load a file."
869 (if desktop-buffer-file-name 792 (if desktop-buffer-file-name
870 (if (or (file-exists-p desktop-buffer-file-name) 793 (if (or (file-exists-p desktop-buffer-file-name)
871 (and desktop-missing-file-warning 794 (let ((msg (format "Desktop: File \"%s\" no longer exists."
872 (y-or-n-p (format 795 desktop-buffer-file-name)))
873 "File \"%s\" no longer exists. Re-create? " 796 (if desktop-missing-file-warning
874 desktop-buffer-file-name)))) 797 (y-or-n-p (concat msg " Re-create? "))
798 (message msg)
799 nil)))
875 (let* ((auto-insert nil) ; Disable auto insertion 800 (let* ((auto-insert nil) ; Disable auto insertion
876 (coding-system-for-read 801 (coding-system-for-read
877 (or coding-system-for-read 802 (or coding-system-for-read
@@ -885,7 +810,7 @@ directory DIRNAME."
885 (functionp desktop-buffer-major-mode) 810 (functionp desktop-buffer-major-mode)
886 (funcall desktop-buffer-major-mode)) 811 (funcall desktop-buffer-major-mode))
887 buf) 812 buf)
888 'ignored))) 813 nil)))
889 814
890;; ---------------------------------------------------------------------------- 815;; ----------------------------------------------------------------------------
891;; Create a buffer, load its file, set is mode, ...; called from Desktop file 816;; Create a buffer, load its file, set is mode, ...; called from Desktop file
@@ -907,20 +832,32 @@ directory DIRNAME."
907 desktop-buffer-misc 832 desktop-buffer-misc
908 &optional 833 &optional
909 desktop-buffer-locals) 834 desktop-buffer-locals)
835 ;; Just to silence the byte compiler. Bound locally in `desktop-read'.
836 (eval-when-compile
837 (defvar desktop-buffer-ok-count)
838 (defvar desktop-buffer-fail-count))
910 ;; To make desktop files with relative file names possible, we cannot 839 ;; To make desktop files with relative file names possible, we cannot
911 ;; allow `default-directory' to change. Therefore we save current buffer. 840 ;; allow `default-directory' to change. Therefore we save current buffer.
912 (save-current-buffer 841 (save-current-buffer
913 (let ( 842 (let (
914 (buffer-list (buffer-list)) 843 (buffer-list (buffer-list))
915 (hlist desktop-buffer-handlers) 844 (result
916 (result) 845 (condition-case err
917 (handler) 846 (funcall (or (cdr (assq desktop-buffer-major-mode desktop-buffer-mode-handlers))
847 'desktop-restore-file-buffer)
848 desktop-buffer-file-name
849 desktop-buffer-name
850 desktop-buffer-misc)
851 (error
852 (message "Desktop: Can't load buffer %s: %s"
853 desktop-buffer-name (error-message-string err))
854 (when desktop-missing-file-warning (sit-for 1))
855 nil)))
918 ) 856 )
919 ;; Call desktop-buffer-handlers to create buffer. 857 (if (bufferp result)
920 (while (and (not result) hlist) 858 (setq desktop-buffer-ok-count (1+ desktop-buffer-ok-count))
921 (setq handler (car hlist)) 859 (setq desktop-buffer-fail-count (1+ desktop-buffer-fail-count))
922 (setq result (funcall handler)) 860 (setq result nil))
923 (setq hlist (cdr hlist)))
924 (unless (bufferp result) (setq result nil)) 861 (unless (bufferp result) (setq result nil))
925 ;; Restore buffer list order with new buffer at end. Don't change 862 ;; Restore buffer list order with new buffer at end. Don't change
926 ;; the order for old desktop files (old desktop module behaviour). 863 ;; the order for old desktop files (old desktop module behaviour).
@@ -947,7 +884,12 @@ directory DIRNAME."
947 desktop-buffer-minor-modes))) 884 desktop-buffer-minor-modes)))
948 ;; Even though point and mark are non-nil when written by `desktop-save' 885 ;; Even though point and mark are non-nil when written by `desktop-save'
949 ;; they may be modified by handlers wanting to set point or mark themselves. 886 ;; they may be modified by handlers wanting to set point or mark themselves.
950 (when desktop-buffer-point (goto-char desktop-buffer-point)) 887 (when desktop-buffer-point
888 (goto-char
889 (condition-case err
890 ;; Evaluate point. Thus point can be something like '(search-forward ...
891 (eval desktop-buffer-point)
892 (error (message "%s" (error-message-string err)) 1))))
951 (when desktop-buffer-mark 893 (when desktop-buffer-mark
952 (if (consp desktop-buffer-mark) 894 (if (consp desktop-buffer-mark)
953 (progn 895 (progn