/[emacs]/emacs/lisp/desktop.el
ViewVC logotype

Diff of /emacs/lisp/desktop.el

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.90 by ttn, Sat Aug 6 22:13:42 2005 UTC revision 1.91 by lh, Wed Aug 10 19:38:52 2005 UTC
# Line 51  Line 51 
51  ;; function is added to the `after-init-hook'. This function is  ;; function is added to the `after-init-hook'. This function is
52  ;; responsible for loading the desktop when Emacs is started.  ;; responsible for loading the desktop when Emacs is started.
53    
54  ;; Some words on minor modes: Most minor modes are controlled by  ;; Special handling.
55  ;; buffer-local variables, which have a standard save / restore  ;; -----------------
56  ;; mechanism.  To handle all minor modes, we take the following  ;; Variables `desktop-buffer-mode-handlers' and `desktop-minor-mode-handlers'
57  ;; approach: (1) check whether the variable name from  ;; are supplied to handle special major and minor modes respectively.
58  ;; `minor-mode-alist' is also a function; and (2) use translation  ;; `desktop-buffer-mode-handlers' is an alist of major mode specific functions
59  ;; table `desktop-minor-mode-table' in the case where the two names  ;; to restore a desktop buffer. Elements must have the form
60  ;; are not the same.  ;;
61    ;;    (MAJOR-MODE . RESTORE-BUFFER-FUNCTION).
62    ;;
63    ;; Functions listed are called by `desktop-create-buffer' when `desktop-read'
64    ;; evaluates the desktop file. Buffers with a major mode not specified here,
65    ;; are restored by the default handler `desktop-restore-file-buffer'.
66    ;; `desktop-minor-mode-handlers' is an alist of functions to restore
67    ;; non-standard minor modes.  Elements must have the form
68    ;;
69    ;;    (MINOR-MODE . RESTORE-FUNCTION).
70    ;;
71    ;; Functions are called by `desktop-create-buffer' to restore minor modes.
72    ;; Minor modes not specified here, are restored by the standard minor mode
73    ;; function.  If you write a module that defines a major or minor mode that
74    ;; needs a special handler, then place code like
75    
76    ;;    (defun foo-restore-desktop-buffer
77    ;;    ...
78    ;;    (add-to-list 'desktop-buffer-mode-handlers
79    ;;                 '(foo-mode . foo-restore-desktop-buffer))
80    
81    ;; or
82    
83    ;;    (defun bar-desktop-restore
84    ;;    ...
85    ;;    (add-to-list 'desktop-minor-mode-handlers
86    ;;                 '(bar-mode . bar-desktop-restore))
87    
88    ;; in the module itself, and make shure that the mode function is
89    ;; autoloaded. See the docstrings of `desktop-buffer-mode-handlers' and
90    ;; `desktop-minor-mode-handlers' for more info.
91    
92    ;; Minor modes.
93    ;; ------------
94    ;; Conventional minor modes (see node "Minor Mode Conventions" in the elisp
95    ;; manual) are handled in the following way:
96    ;; When `desktop-save' saves the state of a buffer to the desktop file, it
97    ;; saves as `desktop-minor-modes' the list of names of those variables in
98    ;; `minor-mode-alist' that have a non-nil value.
99    ;; When `desktop-create' restores the buffer, each of the symbols in
100    ;; `desktop-minor-modes' is called as function with parameter 1.
101    ;; The variables `desktop-minor-mode-table' and `desktop-minor-mode-handlers'
102    ;; are used to handle non-conventional minor modes.  `desktop-save' uses
103    ;; `desktop-minor-mode-table' to map minor mode variables to minor mode
104    ;; functions before writing `desktop-minor-modes'. If a minor mode has a
105    ;; variable name that is different form its function name, an entry
106    
107    ;;    (NAME RESTORE-FUNCTION)
108    
109    ;; should be added to `desktop-minor-mode-table'.  If a minor mode should not
110    ;; be restored, RESTORE-FUNCTION should be set to nil.  `desktop-create' uses
111    ;; `desktop-minor-mode-handlers' to lookup minor modes that needs a restore
112    ;; function different from the usual minor mode function.
113    ;; ---------------------------------------------------------------------------
114    
115  ;; By the way: don't use desktop.el to customize Emacs -- the file .emacs  ;; By the way: don't use desktop.el to customize Emacs -- the file .emacs
116  ;; in your home directory is used for that.  Saving global default values  ;; in your home directory is used for that.  Saving global default values
# Line 207  to the value obtained by evaluating FORM Line 260  to the value obtained by evaluating FORM
260    :group 'desktop    :group 'desktop
261    :version "22.1")    :version "22.1")
262    
263  (defcustom desktop-clear-preserve-buffers-regexp  (defcustom desktop-clear-preserve-buffers
264    "^\\(\\*scratch\\*\\|\\*Messages\\*\\|\\*server\\*\\|\\*tramp/.+\\*\\)$"    '("\\*scratch\\*" "\\*Messages\\*" "\\*server\\*" "\\*tramp/.+\\*")
265    "Regexp identifying buffers that `desktop-clear' should not delete.    "*List of buffers that `desktop-clear' should not delete.
266  See also `desktop-clear-preserve-buffers'."  Each element is a regular expression.  Buffers with a name matched by any of
267    :type 'regexp  these won't be deleted."
   :group 'desktop  
   :version "22.1")  
   
 (defcustom desktop-clear-preserve-buffers nil  
   "*List of buffer names that `desktop-clear' should not delete.  
 See also `desktop-clear-preserve-buffers-regexp'."  
268    :type '(repeat string)    :type '(repeat string)
269    :group 'desktop)    :group 'desktop)
270    
271    ;;;###autoload
272  (defcustom desktop-locals-to-save  (defcustom desktop-locals-to-save
273    '(desktop-locals-to-save  ; Itself!  Think it over.    '(desktop-locals-to-save  ; Itself!  Think it over.
274      truncate-lines      truncate-lines
# Line 230  See also `desktop-clear-preserve-buffers Line 278  See also `desktop-clear-preserve-buffers
278      overwrite-mode      overwrite-mode
279      change-log-default-name      change-log-default-name
280      line-number-mode      line-number-mode
281      buffer-file-coding-system)      column-number-mode
282        size-indication-mode
283        buffer-file-coding-system
284        indent-tabs-mode
285        indicate-buffer-boundaries
286        indicate-empty-lines
287        show-trailing-whitespace)
288    "List of local variables to save for each buffer.    "List of local variables to save for each buffer.
289  The variables are saved only when they really are local."  The variables are saved only when they really are local.  Conventional minor
290    modes are restored automatically; they should not be listed here."
291    :type '(repeat symbol)    :type '(repeat symbol)
292    :group 'desktop)    :group 'desktop)
 (make-variable-buffer-local 'desktop-locals-to-save)  
293    
294  ;; We skip .log files because they are normally temporary.  ;; We skip .log files because they are normally temporary.
295  ;;         (ftp) files because they require passwords and whatnot.  ;;         (ftp) files because they require passwords and whatnot.
# Line 301  file along with the state of the buffer Line 355  file along with the state of the buffer
355  When file names are returned, they should be formatted using the call  When file names are returned, they should be formatted using the call
356  \"(desktop-file-name FILE-NAME DESKTOP-DIRNAME)\".  \"(desktop-file-name FILE-NAME DESKTOP-DIRNAME)\".
357    
358  Later, when `desktop-read' calls a function in `desktop-buffer-mode-handlers'  Later, when `desktop-read' evaluates the desktop file, auxiliary information
359  to restore the buffer, the auxiliary information is passed as the argument  is passed as the argument DESKTOP-BUFFER-MISC to functions in
360  DESKTOP-BUFFER-MISC.")  `desktop-buffer-mode-handlers'.")
361  (make-variable-buffer-local 'desktop-save-buffer)  (make-variable-buffer-local 'desktop-save-buffer)
362  (make-obsolete-variable 'desktop-buffer-modes-to-save  (make-obsolete-variable 'desktop-buffer-modes-to-save
363                          'desktop-save-buffer "22.1")                          'desktop-save-buffer "22.1")
364  (make-obsolete-variable 'desktop-buffer-misc-functions  (make-obsolete-variable 'desktop-buffer-misc-functions
365                          'desktop-save-buffer "22.1")                          'desktop-save-buffer "22.1")
366    
367  (defcustom desktop-buffer-mode-handlers  ;;;###autoload
368    '((dired-mode . dired-restore-desktop-buffer)  (defvar desktop-buffer-mode-handlers
369      (rmail-mode . rmail-restore-desktop-buffer)    nil
     (mh-folder-mode . mh-restore-desktop-buffer)  
     (Info-mode . Info-restore-desktop-buffer))  
370    "Alist of major mode specific functions to restore a desktop buffer.    "Alist of major mode specific functions to restore a desktop buffer.
371  Functions are called by `desktop-read'.  List elements must have the form  Functions listed are called by `desktop-create-buffer' when `desktop-read'
372  \(MAJOR-MODE . RESTORE-BUFFER-FUNCTION).  evaluates the desktop file.  List elements must have the form
373    
374       (MAJOR-MODE . RESTORE-BUFFER-FUNCTION).
375    
376  Buffers with a major mode not specified here, are restored by the default  Buffers with a major mode not specified here, are restored by the default
377  handler `desktop-restore-file-buffer'.  handler `desktop-restore-file-buffer'.
# Line 337  Furthermore, they may use the following Line 391  Furthermore, they may use the following
391     desktop-buffer-locals     desktop-buffer-locals
392    
393  If a handler returns a buffer, then the saved mode settings  If a handler returns a buffer, then the saved mode settings
394  and variable values for that buffer are copied into it."  and variable values for that buffer are copied into it.
395    :type 'alist  
396    :group 'desktop)  Modules that define a major mode that needs a special handler should contain
397    code like
398    
399       (defun foo-restore-desktop-buffer
400       ...
401       (add-to-list 'desktop-buffer-mode-handlers
402                    '(foo-mode . foo-restore-desktop-buffer))
403    
404    Furthermore the major mode function must be autoloaded.")
405    
406  (put 'desktop-buffer-mode-handlers 'risky-local-variable t)  (put 'desktop-buffer-mode-handlers 'risky-local-variable t)
407  (make-obsolete-variable 'desktop-buffer-handlers  (make-obsolete-variable 'desktop-buffer-handlers
# Line 355  mode is active.  RESTORE-FUNCTION is the Line 417  mode is active.  RESTORE-FUNCTION is the
417  called.  RESTORE-FUNCTION nil means don't try to restore the minor mode.  called.  RESTORE-FUNCTION nil means don't try to restore the minor mode.
418  Only minor modes for which the name of the buffer-local variable  Only minor modes for which the name of the buffer-local variable
419  and the name of the minor mode function are different have to be added to  and the name of the minor mode function are different have to be added to
420  this table."  this table.  See also `desktop-minor-mode-handlers'."
421    :type 'sexp    :type 'sexp
422    :group 'desktop)    :group 'desktop)
423    
424    ;;;###autoload
425    (defvar desktop-minor-mode-handlers
426      nil
427      "Alist of functions to restore non-standard minor modes.
428    Functions are called by `desktop-create-buffer' to restore minor modes.
429    List elements must have the form
430    
431       (MINOR-MODE . RESTORE-FUNCTION).
432    
433    Minor modes not specified here, are restored by the standard minor mode
434    function.
435    
436    Handlers are called with argument list
437    
438       (DESKTOP-BUFFER-LOCALS)
439    
440    Furthermore, they may use the following variables:
441    
442       desktop-file-version
443       desktop-buffer-file-name
444       desktop-buffer-name
445       desktop-buffer-major-mode
446       desktop-buffer-minor-modes
447       desktop-buffer-point
448       desktop-buffer-mark
449       desktop-buffer-read-only
450       desktop-buffer-misc
451    
452    When a handler is called, the buffer has been created and the major mode has
453    been set, but local variables listed in desktop-buffer-locals has not yet been
454    created and set.
455    
456    Modules that define a minor mode that needs a special handler should contain
457    code like
458    
459       (defun foo-desktop-restore
460       ...
461       (add-to-list 'desktop-minor-mode-handlers
462                    '(foo-mode . foo-desktop-restore))
463    
464    Furthermore the minor mode function must be autoloaded.
465    
466    See also `desktop-minor-mode-table'.")
467    
468    (put 'desktop-minor-mode-handlers 'risky-local-variable t)
469    
470  ;; ----------------------------------------------------------------------------  ;; ----------------------------------------------------------------------------
471  (defvar desktop-dirname nil  (defvar desktop-dirname nil
472    "The directory in which the desktop file should be saved.")    "The directory in which the desktop file should be saved.")
# Line 382  this table." Line 490  this table."
490  ;; ----------------------------------------------------------------------------  ;; ----------------------------------------------------------------------------
491  (defun desktop-clear ()  (defun desktop-clear ()
492    "Empty the Desktop.    "Empty the Desktop.
493  This kills all buffers except for internal ones and those matching  This kills all buffers except for internal ones and those with names matched by
494  `desktop-clear-preserve-buffers-regexp' or listed in  a regular expression in the list `desktop-clear-preserve-buffers'.
495  `desktop-clear-preserve-buffers'.  Furthermore, it clears the  Furthermore, it clears the variables listed in `desktop-globals-to-clear'."
 variables listed in `desktop-globals-to-clear'."  
496    (interactive)    (interactive)
497    (desktop-lazy-abort)    (desktop-lazy-abort)
498    (dolist (var desktop-globals-to-clear)    (dolist (var desktop-globals-to-clear)
499      (if (symbolp var)      (if (symbolp var)
500        (eval `(setq-default ,var nil))        (eval `(setq-default ,var nil))
501        (eval `(setq-default ,(car var) ,(cdr var)))))        (eval `(setq-default ,(car var) ,(cdr var)))))
502    (let ((buffers (buffer-list)))    (let ((buffers (buffer-list))
503            (preserve-regexp (concat "^\\("
504                                     (mapconcat (lambda (regexp)
505                                                  (concat "\\(" regexp "\\)"))
506                                                desktop-clear-preserve-buffers
507                                                "\\|")
508                                     "\\)$")))
509      (while buffers      (while buffers
510        (let ((bufname (buffer-name (car buffers))))        (let ((bufname (buffer-name (car buffers))))
511           (or           (or
512             (null bufname)             (null bufname)
513             (string-match desktop-clear-preserve-buffers-regexp bufname)             (string-match preserve-regexp bufname)
            (member bufname desktop-clear-preserve-buffers)  
514             ;; Don't kill buffers made for internal purposes.             ;; Don't kill buffers made for internal purposes.
515             (and (not (equal bufname "")) (eq (aref bufname 0) ?\s))             (and (not (equal bufname "")) (eq (aref bufname 0) ?\s))
516             (kill-buffer (car buffers))))             (kill-buffer (car buffers))))
# Line 622  See also `desktop-base-file-name'." Line 734  See also `desktop-base-file-name'."
734                            (and                            (and
735                              (boundp minor-mode)                              (boundp minor-mode)
736                              (symbol-value minor-mode)                              (symbol-value minor-mode)
737                              (let ((special (assq minor-mode desktop-minor-mode-table)))                              (let* ((special (assq minor-mode desktop-minor-mode-table))
738                                (when (or special (functionp minor-mode))                                     (value (cond (special (cadr special))
739                                  (setq ret                                                  ((functionp minor-mode) minor-mode))))
740                                    (cons                                (when value (add-to-list 'ret value)))))
                                     (if special (cadr special) minor-mode)  
                                     ret))))))  
741                          (mapcar #'car minor-mode-alist))                          (mapcar #'car minor-mode-alist))
742                        ret)                        ret)
743                      (point)                      (point)
# Line 685  See also `desktop-base-file-name'." Line 795  See also `desktop-base-file-name'."
795                    (insert ")\n\n")))                    (insert ")\n\n")))
796              info)              info)
797        (setq default-directory dirname)        (setq default-directory dirname)
       (when (file-exists-p filename) (delete-file filename))  
798        (let ((coding-system-for-write 'emacs-mule))        (let ((coding-system-for-write 'emacs-mule))
799          (write-region (point-min) (point-max) filename nil 'nomessage))))          (write-region (point-min) (point-max) filename nil 'nomessage))))
800    (setq desktop-dirname dirname))    (setq desktop-dirname dirname))
# Line 850  directory DIRNAME." Line 959  directory DIRNAME."
959              buf)              buf)
960          nil)))          nil)))
961    
962    (defun desktop-load-file (function)
963      "Load the file where auto loaded FUNCTION is defined."
964      (let ((fcell (symbol-function function)))
965        (when (and (listp fcell)
966                   (eq 'autoload (car fcell)))
967          (load (cadr fcell)))))
968    
969  ;; ----------------------------------------------------------------------------  ;; ----------------------------------------------------------------------------
970  ;; Create a buffer, load its file, set its mode, ...;  ;; Create a buffer, load its file, set its mode, ...;
971  ;; called from Desktop file only.  ;; called from Desktop file only.
972    
973  (eval-when-compile ; Just to silence the byte compiler  ;; Just to silence the byte compiler.
974     (defvar desktop-first-buffer) ;; Dynamically bound in `desktop-read'  (eval-when-compile
975  )    (defvar desktop-first-buffer)) ; Dynamically bound in `desktop-read'
976    
977  (defun desktop-create-buffer  (defun desktop-create-buffer
978    (desktop-file-version    (desktop-file-version
# Line 877  directory DIRNAME." Line 993  directory DIRNAME."
993    ;; To make desktop files with relative file names possible, we cannot    ;; To make desktop files with relative file names possible, we cannot
994    ;; allow `default-directory' to change. Therefore we save current buffer.    ;; allow `default-directory' to change. Therefore we save current buffer.
995    (save-current-buffer    (save-current-buffer
996        ;; Give major mode module a chance to add a handler.
997        (desktop-load-file desktop-buffer-major-mode)
998      (let ((buffer-list (buffer-list))      (let ((buffer-list (buffer-list))
999            (result            (result
1000             (condition-case err             (condition-case err
# Line 914  directory DIRNAME." Line 1032  directory DIRNAME."
1032                 (auto-fill-mode 0))                 (auto-fill-mode 0))
1033                (t                (t
1034                 (mapc #'(lambda (minor-mode)                 (mapc #'(lambda (minor-mode)
1035                           (when (functionp minor-mode) (funcall minor-mode 1)))                           ;; Give minor mode module a chance to add a handler.
1036                             (desktop-load-file minor-mode)
1037                             (let ((handler (cdr (assq minor-mode desktop-minor-mode-handlers))))
1038                               (if handler
1039                                   (funcall handler desktop-buffer-locals)
1040                                 (when (functionp minor-mode)
1041                                   (funcall minor-mode 1)))))
1042                       desktop-buffer-minor-modes)))                       desktop-buffer-minor-modes)))
1043          ;; Even though point and mark are non-nil when written by `desktop-save'          ;; Even though point and mark are non-nil when written by `desktop-save',
1044          ;; they may be modified by handlers wanting to set point or mark themselves.          ;; they may be modified by handlers wanting to set point or mark themselves.
1045          (when desktop-buffer-point          (when desktop-buffer-point
1046            (goto-char            (goto-char

Legend:
Removed from v.1.90  
changed lines
  Added in v.1.91

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26