changeset 55059:fa9573e2db2a

(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.
author Lars Hansen <larsh@soem.dk>
date Wed, 21 Apr 2004 20:53:35 +0000
parents 053797c3d447
children 4a1324ad659c
files lisp/desktop.el
diffstat 1 files changed, 92 insertions(+), 150 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/desktop.el	Wed Apr 21 20:52:18 2004 +0000
+++ b/lisp/desktop.el	Wed Apr 21 20:53:35 2004 +0000
@@ -83,12 +83,6 @@
 
 ;;; Code:
 
-;; Make the compilation more silent
-(eval-when-compile
-  ;; We use functions from these modules
-  ;; We can't (require 'mh-e) since that wants to load something.
-  (mapcar 'require '(info dired reporter)))
-
 (defvar desktop-file-version "206"
   "Version number of desktop file format.
 Written into the desktop file and used at desktop read to provide
@@ -253,8 +247,9 @@
 (defcustom desktop-buffer-modes-to-save
   '(Info-mode rmail-mode)
   "If a buffer is of one of these major modes, save the buffer state.
-It is up to the functions in `desktop-buffer-handlers' to decide
-whether the buffer should be recreated or not, and how."
+This applies to buffers not visiting a file and not beeing a dired buffer.
+Modes specified here must have a handler in `desktop-buffer-mode-handlers'
+to be restored."
   :type '(repeat symbol)
   :group 'desktop)
 
@@ -272,53 +267,59 @@
   :type '(choice (const absolute) (const tilde) (const local))
   :group 'desktop)
 
-(defcustom desktop-buffer-misc-functions
-  '(desktop-buffer-info-misc-data
-    desktop-buffer-dired-misc-data)
-  "*Functions used to determine auxiliary information for a buffer.
-These functions are called by `desktop-save' in order, with no
-arguments.  If a function returns non-nil, its value is saved along
-with the state of the buffer for which it was called; no further
-functions will be called.
+;;;###autoload
+(defvar desktop-buffer-misc-data-function nil
+  "Function returning major mode specific data for desktop file.
+This variable becomes buffer local when set.
+The function specified is called by `desktop-save', with argument
+DESKTOP-DIRNAME.  If it returns non-nil, its value is saved along
+with the state of the buffer for which it was called.
 
 When file names are returned, they should be formatted using the call
-\"(desktop-file-name FILE-NAME dirname)\".
+\"(desktop-file-name FILE-NAME DESKTOP-DIRNAME)\".
 
-Later, when `desktop-read' restores buffers, each of the functions in
-`desktop-buffer-handlers' will have access to a buffer local variable,
-named `desktop-buffer-misc', whose value is what the function in
-`desktop-buffer-misc-functions' returned."
-  :type '(repeat function)
-  :group 'desktop)
+Later, when `desktop-read' calls a function in `desktop-buffer-mode-handlers'
+to restore the buffer, the auxiliary information is passed as argument.")
+(make-variable-buffer-local 'desktop-buffer-misc-data-function)
+(make-obsolete-variable 'desktop-buffer-misc-functions
+                        'desktop-buffer-misc-data-function)
 
-(defcustom desktop-buffer-handlers
-  '(desktop-buffer-dired
-    desktop-buffer-rmail
-    desktop-buffer-mh
-    desktop-buffer-info
-    desktop-buffer-file)
-  "*Functions called by `desktop-read' in order to create a buffer.
-The functions are called without explicit parameters but can use the
-following variables:
+(defcustom desktop-buffer-mode-handlers '(
+  (dired-mode . dired-restore-desktop-buffer)
+  (rmail-mode . rmail-restore-desktop-buffer)
+  (mh-folder-mode . mh-restore-desktop-buffer)
+  (Info-mode . Info-restore-desktop-buffer))
+  "Alist of major mode specific functions to restore a desktop buffer.
+Functions are called by `desktop-read'. List elements must have the form
+\(MAJOR-MODE . FUNCTION).
+
+Buffers with a major mode not specified here, are restored by the default
+handler `desktop-restore-file-buffer'.
+
+Handlers are called with parameters
+
+   desktop-buffer-file-name
+   desktop-buffer-name
+   desktop-buffer-misc
+
+Furthermore, they may use the following variables:
 
    desktop-file-version
-   desktop-buffer-file-name
-   desktop-buffer-name
    desktop-buffer-major-mode
    desktop-buffer-minor-modes
    desktop-buffer-point
    desktop-buffer-mark
    desktop-buffer-read-only
-   desktop-buffer-misc
    desktop-buffer-locals
 
-If one function returns non-nil, no further functions are called.
-If the function returns a buffer, then the saved mode settings
+If a handler returns a buffer, then the saved mode settings
 and variable values for that buffer are copied into it."
-  :type '(repeat function)
+  :type 'alist
   :group 'desktop)
 
-(put 'desktop-buffer-handlers 'risky-local-variable t)
+(put 'desktop-buffer-mode-handlers 'risky-local-variable t)
+(make-obsolete-variable 'desktop-buffer-handlers
+                        'desktop-buffer-mode-handlers)
 
 (defcustom desktop-minor-mode-table
   '((auto-fill-function auto-fill-mode)
@@ -608,7 +609,9 @@
                     (point)
                     (list (mark t) mark-active)
                     buffer-read-only
-                    (run-hook-with-args-until-success 'desktop-buffer-misc-functions)
+                    ;; Auxiliary information
+                    (when desktop-buffer-misc-data-function
+                      (funcall desktop-buffer-misc-data-function dirname))
                     (let ((locals desktop-locals-to-save)
                           (loclist (buffer-local-variables))
                           (ll))
@@ -703,7 +706,9 @@
             "~"))))
     (if (file-exists-p (expand-file-name desktop-base-file-name desktop-dirname))
       ;; Desktop file found, process it.
-      (let ((desktop-first-buffer nil))
+      (let ((desktop-first-buffer nil)
+            (desktop-buffer-ok-count 0)
+            (desktop-buffer-fail-count 0))
         ;; Evaluate desktop buffer.
         (load (expand-file-name desktop-base-file-name desktop-dirname) t t t)
         ;; `desktop-create-buffer' puts buffers at end of the buffer list.
@@ -715,7 +720,12 @@
         (run-hooks 'desktop-delay-hook)
         (setq desktop-delay-hook nil)
         (run-hooks 'desktop-after-read-hook)
-        (message "Desktop loaded.")
+        (message "Desktop: %d buffer%s restored%s."
+                 desktop-buffer-ok-count
+                 (if (= 1 desktop-buffer-ok-count) "" "s")
+                 (if (< 0 desktop-buffer-fail-count)
+                     (format ", %d failed to restore" desktop-buffer-fail-count)
+                   ""))
         t)
       ;; No desktop file found.
       (desktop-clear)
@@ -772,106 +782,21 @@
   (desktop-read desktop-dirname))
 
 ;; ----------------------------------------------------------------------------
-;; Note: the following functions use the dynamic variable binding in Lisp.
-;;
-
-(eval-when-compile ; Just to silence the byte compiler
-  (defvar desktop-file-version)
-  (defvar desktop-buffer-file-name)
-  (defvar desktop-buffer-name)
-  (defvar desktop-buffer-major-mode)
-  (defvar desktop-buffer-minor-modes)
-  (defvar desktop-buffer-point)
-  (defvar desktop-buffer-mark)
-  (defvar desktop-buffer-read-only)
-  (defvar desktop-buffer-misc)
-  (defvar desktop-buffer-locals)
-)
-
-(defun desktop-buffer-info-misc-data ()
-  (if (eq major-mode 'Info-mode)
-      (list Info-current-file
-            Info-current-node)))
-
-;; ----------------------------------------------------------------------------
-(defun desktop-buffer-dired-misc-data ()
-  (when (eq major-mode 'dired-mode)
-    (eval-when-compile (defvar dirname))
-    (cons
-     ;; Value of `dired-directory'.
-     (if (consp dired-directory)
-	 ;; Directory name followed by list of files.
-	 (cons (desktop-file-name (car dired-directory) dirname) (cdr dired-directory))
-       ;; Directory name, optionally with with shell wildcard.
-       (desktop-file-name dired-directory dirname))
-     ;; Subdirectories in `dired-subdir-alist'.
-     (cdr
-      (nreverse
-       (mapcar
-	(function (lambda (f) (desktop-file-name (car f) dirname)))
-	dired-subdir-alist))))))
-
-;; ----------------------------------------------------------------------------
-(defun desktop-buffer-info () "Load an info file."
-  (if (eq 'Info-mode desktop-buffer-major-mode)
-      (progn
-	(let ((first (nth 0 desktop-buffer-misc))
-	      (second (nth 1 desktop-buffer-misc)))
-	(when (and first second)
-	  (require 'info)
-	  (with-no-warnings
-	   (Info-find-node first second))
-	  (current-buffer))))))
-
-;; ----------------------------------------------------------------------------
-(eval-when-compile (defvar rmail-buffer)) ; Just to silence the byte compiler.
-(defun desktop-buffer-rmail () "Load an RMAIL file."
-  (if (eq 'rmail-mode desktop-buffer-major-mode)
-      (condition-case error
-	  (progn (rmail-input desktop-buffer-file-name)
-                         (if (eq major-mode 'rmail-mode)
-                             (current-buffer)
-                           rmail-buffer))
-	(file-locked
-	 (kill-buffer (current-buffer))
-	 'ignored))))
-
-;; ----------------------------------------------------------------------------
-(defun desktop-buffer-mh () "Load a folder in the mh system."
-  (if (eq 'mh-folder-mode desktop-buffer-major-mode)
-      (with-no-warnings
-	(mh-find-path)
-        (mh-visit-folder desktop-buffer-name)
-	(current-buffer))))
-
-;; ----------------------------------------------------------------------------
-(defun desktop-buffer-dired () "Load a directory using dired."
-  (if (eq 'dired-mode desktop-buffer-major-mode)
-      ;; First element of `desktop-buffer-misc' is the value of `dired-directory'.
-      ;; This value is a directory name, optionally with with shell wildcard or
-      ;; a directory name followed by list of files.
-      (let* ((dired-dir (car desktop-buffer-misc))
-	     (dir (if (consp dired-dir) (car dired-dir) dired-dir)))
-	(if (file-directory-p (file-name-directory dir))
-	    (progn
-	      (dired dired-dir)
-              ;; The following elements of `desktop-buffer-misc' are the keys
-              ;; from `dired-subdir-alist'.
-	      (mapcar 'dired-maybe-insert-subdir (cdr desktop-buffer-misc))
-	      (current-buffer))
-	  (message "Directory %s no longer exists." dir)
-	  (sit-for 1)
-	  'ignored))))
-
-;; ----------------------------------------------------------------------------
-(defun desktop-buffer-file ()
-  "Load a file."
+(defun desktop-restore-file-buffer (desktop-buffer-file-name
+                                    desktop-buffer-name
+                                    desktop-buffer-misc)
+  "Restore a file buffer."
+  (eval-when-compile ; Just to silence the byte compiler
+    (defvar desktop-buffer-major-mode)
+    (defvar desktop-buffer-locals))
   (if desktop-buffer-file-name
       (if (or (file-exists-p desktop-buffer-file-name)
-	      (and desktop-missing-file-warning
-		   (y-or-n-p (format
-			      "File \"%s\" no longer exists. Re-create? "
-			      desktop-buffer-file-name))))
+              (let ((msg (format "Desktop: File \"%s\" no longer exists."
+                                 desktop-buffer-file-name)))
+                 (if desktop-missing-file-warning
+		     (y-or-n-p (concat msg " Re-create? "))
+                   (message msg)
+                   nil)))
 	  (let* ((auto-insert nil) ; Disable auto insertion
 		 (coding-system-for-read
 		  (or coding-system-for-read
@@ -885,7 +810,7 @@
 		 (functionp desktop-buffer-major-mode)
 		 (funcall desktop-buffer-major-mode))
 	    buf)
-	'ignored)))
+	nil)))
 
 ;; ----------------------------------------------------------------------------
 ;; Create a buffer, load its file, set is mode, ...;  called from Desktop file
@@ -907,20 +832,32 @@
   desktop-buffer-misc
   &optional
   desktop-buffer-locals)
+  ;; Just to silence the byte compiler. Bound locally in `desktop-read'.
+  (eval-when-compile
+    (defvar desktop-buffer-ok-count)
+    (defvar desktop-buffer-fail-count))
   ;; To make desktop files with relative file names possible, we cannot
   ;; allow `default-directory' to change. Therefore we save current buffer.
   (save-current-buffer
     (let (
       (buffer-list (buffer-list))
-      (hlist desktop-buffer-handlers)
-      (result)
-      (handler)
+      (result
+         (condition-case err
+             (funcall (or (cdr (assq desktop-buffer-major-mode desktop-buffer-mode-handlers))
+                          'desktop-restore-file-buffer)
+                      desktop-buffer-file-name
+                      desktop-buffer-name
+                      desktop-buffer-misc)
+           (error
+             (message "Desktop: Can't load buffer %s: %s"
+                      desktop-buffer-name (error-message-string err))
+             (when desktop-missing-file-warning (sit-for 1))
+             nil)))
     )
-      ;; Call desktop-buffer-handlers to create buffer.
-      (while (and (not result) hlist)
-        (setq handler (car hlist))
-        (setq result (funcall handler))
-        (setq hlist (cdr hlist)))
+      (if (bufferp result)
+          (setq desktop-buffer-ok-count (1+ desktop-buffer-ok-count))
+        (setq desktop-buffer-fail-count (1+ desktop-buffer-fail-count))
+        (setq result nil))
       (unless (bufferp result) (setq result nil))
       ;; Restore buffer list order with new buffer at end. Don't change
       ;; the order for old desktop files (old desktop module behaviour).
@@ -947,7 +884,12 @@
             desktop-buffer-minor-modes)))
         ;; Even though point and mark are non-nil when written by `desktop-save'
         ;; they may be modified by handlers wanting to set point or mark themselves.
-        (when desktop-buffer-point (goto-char desktop-buffer-point))
+        (when desktop-buffer-point
+          (goto-char
+            (condition-case err
+                ;; Evaluate point. Thus point can be something like '(search-forward ...
+                (eval desktop-buffer-point)
+              (error (message "%s" (error-message-string err)) 1))))
         (when desktop-buffer-mark
           (if (consp desktop-buffer-mark)
             (progn