aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Hansen2005-08-10 19:38:52 +0000
committerLars Hansen2005-08-10 19:38:52 +0000
commit0f4804e7eb7b8582926dd95ca3eda4ae49502067 (patch)
tree7894626b8ce207415f5f11f764ca31c98913cb39
parent2d77d354f1a21047ad037c52e3a6978e783a51a5 (diff)
downloademacs-0f4804e7eb7b8582926dd95ca3eda4ae49502067.tar.gz
emacs-0f4804e7eb7b8582926dd95ca3eda4ae49502067.zip
(desktop-buffer-mode-handlers): Make
non-customizable. Add autoload cookie. Change initial value to nil; add elements in respective modules instead. Fix doc string. (desktop-load-file): New function. (desktop-minor-mode-handlers): New autoloaded variable. (desktop-create-buffer): Call minor mode handlers. Use desktop-load-file to load major and minor mode modules prior to checking for a handler. (desktop-save): Don't add nil to desktop-minor-modes for minor modes with nil function in desktop-minor-mode-table. Don't delete desktop file before rewriting it. (desktop-locals-to-save): Add autoload cookie. Don't make automatically buffer-local. Add variables column-number-mode, size-indication-mode, indent-tabs-mode, indicate-buffer-boundaries, indicate-empty-lines and show-trailing-whitespace. (desktop-clear): Allow desktop-clear-preserve-buffers to contain regexps. Don't use desktop-clear-preserve-buffers-regexp. (desktop-clear-preserve-buffers-regexp): Delete. (desktop-clear-preserve-buffers): Update initial value and docstring. (desktop-save-buffer): Fix doc string.
-rw-r--r--lisp/desktop.el232
1 files changed, 178 insertions, 54 deletions
diff --git a/lisp/desktop.el b/lisp/desktop.el
index 57065d2f813..f8be1f0685d 100644
--- a/lisp/desktop.el
+++ b/lisp/desktop.el
@@ -51,13 +51,66 @@
51;; function is added to the `after-init-hook'. This function is 51;; function is added to the `after-init-hook'. This function is
52;; responsible for loading the desktop when Emacs is started. 52;; responsible for loading the desktop when Emacs is started.
53 53
54;; Some words on minor modes: Most minor modes are controlled by 54;; Special handling.
55;; buffer-local variables, which have a standard save / restore 55;; -----------------
56;; mechanism. To handle all minor modes, we take the following 56;; Variables `desktop-buffer-mode-handlers' and `desktop-minor-mode-handlers'
57;; approach: (1) check whether the variable name from 57;; are supplied to handle special major and minor modes respectively.
58;; `minor-mode-alist' is also a function; and (2) use translation 58;; `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 59;; to restore a desktop buffer. Elements must have the form
60;; are not the same. 60;;
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;; ---------------------------------------------------------------------------
61 114
62;; By the way: don't use desktop.el to customize Emacs -- the file .emacs 115;; By the way: don't use desktop.el to customize Emacs -- the file .emacs
63;; in your home directory is used for that. Saving global default values 116;; in your home directory is used for that. Saving global default values
@@ -207,20 +260,15 @@ to the value obtained by evaluating FORM."
207 :group 'desktop 260 :group 'desktop
208 :version "22.1") 261 :version "22.1")
209 262
210(defcustom desktop-clear-preserve-buffers-regexp 263(defcustom desktop-clear-preserve-buffers
211 "^\\(\\*scratch\\*\\|\\*Messages\\*\\|\\*server\\*\\|\\*tramp/.+\\*\\)$" 264 '("\\*scratch\\*" "\\*Messages\\*" "\\*server\\*" "\\*tramp/.+\\*")
212 "Regexp identifying buffers that `desktop-clear' should not delete. 265 "*List of buffers that `desktop-clear' should not delete.
213See also `desktop-clear-preserve-buffers'." 266Each element is a regular expression. Buffers with a name matched by any of
214 :type 'regexp 267these won't be deleted."
215 :group 'desktop
216 :version "22.1")
217
218(defcustom desktop-clear-preserve-buffers nil
219 "*List of buffer names that `desktop-clear' should not delete.
220See also `desktop-clear-preserve-buffers-regexp'."
221 :type '(repeat string) 268 :type '(repeat string)
222 :group 'desktop) 269 :group 'desktop)
223 270
271;;;###autoload
224(defcustom desktop-locals-to-save 272(defcustom desktop-locals-to-save
225 '(desktop-locals-to-save ; Itself! Think it over. 273 '(desktop-locals-to-save ; Itself! Think it over.
226 truncate-lines 274 truncate-lines
@@ -230,12 +278,18 @@ See also `desktop-clear-preserve-buffers-regexp'."
230 overwrite-mode 278 overwrite-mode
231 change-log-default-name 279 change-log-default-name
232 line-number-mode 280 line-number-mode
233 buffer-file-coding-system) 281 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)
234 "List of local variables to save for each buffer. 288 "List of local variables to save for each buffer.
235The variables are saved only when they really are local." 289The variables are saved only when they really are local. Conventional minor
290modes are restored automatically; they should not be listed here."
236 :type '(repeat symbol) 291 :type '(repeat symbol)
237 :group 'desktop) 292 :group 'desktop)
238(make-variable-buffer-local 'desktop-locals-to-save)
239 293
240;; We skip .log files because they are normally temporary. 294;; We skip .log files because they are normally temporary.
241;; (ftp) files because they require passwords and whatnot. 295;; (ftp) files because they require passwords and whatnot.
@@ -301,23 +355,23 @@ file along with the state of the buffer for which it was called.
301When file names are returned, they should be formatted using the call 355When file names are returned, they should be formatted using the call
302\"(desktop-file-name FILE-NAME DESKTOP-DIRNAME)\". 356\"(desktop-file-name FILE-NAME DESKTOP-DIRNAME)\".
303 357
304Later, when `desktop-read' calls a function in `desktop-buffer-mode-handlers' 358Later, when `desktop-read' evaluates the desktop file, auxiliary information
305to restore the buffer, the auxiliary information is passed as the argument 359is passed as the argument DESKTOP-BUFFER-MISC to functions in
306DESKTOP-BUFFER-MISC.") 360`desktop-buffer-mode-handlers'.")
307(make-variable-buffer-local 'desktop-save-buffer) 361(make-variable-buffer-local 'desktop-save-buffer)
308(make-obsolete-variable 'desktop-buffer-modes-to-save 362(make-obsolete-variable 'desktop-buffer-modes-to-save
309 'desktop-save-buffer "22.1") 363 'desktop-save-buffer "22.1")
310(make-obsolete-variable 'desktop-buffer-misc-functions 364(make-obsolete-variable 'desktop-buffer-misc-functions
311 'desktop-save-buffer "22.1") 365 'desktop-save-buffer "22.1")
312 366
313(defcustom desktop-buffer-mode-handlers 367;;;###autoload
314 '((dired-mode . dired-restore-desktop-buffer) 368(defvar desktop-buffer-mode-handlers
315 (rmail-mode . rmail-restore-desktop-buffer) 369 nil
316 (mh-folder-mode . mh-restore-desktop-buffer)
317 (Info-mode . Info-restore-desktop-buffer))
318 "Alist of major mode specific functions to restore a desktop buffer. 370 "Alist of major mode specific functions to restore a desktop buffer.
319Functions are called by `desktop-read'. List elements must have the form 371Functions listed are called by `desktop-create-buffer' when `desktop-read'
320\(MAJOR-MODE . RESTORE-BUFFER-FUNCTION). 372evaluates the desktop file. List elements must have the form
373
374 (MAJOR-MODE . RESTORE-BUFFER-FUNCTION).
321 375
322Buffers with a major mode not specified here, are restored by the default 376Buffers with a major mode not specified here, are restored by the default
323handler `desktop-restore-file-buffer'. 377handler `desktop-restore-file-buffer'.
@@ -337,9 +391,17 @@ Furthermore, they may use the following variables:
337 desktop-buffer-locals 391 desktop-buffer-locals
338 392
339If a handler returns a buffer, then the saved mode settings 393If a handler returns a buffer, then the saved mode settings
340and variable values for that buffer are copied into it." 394and variable values for that buffer are copied into it.
341 :type 'alist 395
342 :group 'desktop) 396Modules that define a major mode that needs a special handler should contain
397code 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
404Furthermore the major mode function must be autoloaded.")
343 405
344(put 'desktop-buffer-mode-handlers 'risky-local-variable t) 406(put 'desktop-buffer-mode-handlers 'risky-local-variable t)
345(make-obsolete-variable 'desktop-buffer-handlers 407(make-obsolete-variable 'desktop-buffer-handlers
@@ -355,10 +417,56 @@ mode is active. RESTORE-FUNCTION is the function to activate the minor mode.
355called. RESTORE-FUNCTION nil means don't try to restore the minor mode. 417called. RESTORE-FUNCTION nil means don't try to restore the minor mode.
356Only minor modes for which the name of the buffer-local variable 418Only minor modes for which the name of the buffer-local variable
357and the name of the minor mode function are different have to be added to 419and the name of the minor mode function are different have to be added to
358this table." 420this table. See also `desktop-minor-mode-handlers'."
359 :type 'sexp 421 :type 'sexp
360 :group 'desktop) 422 :group 'desktop)
361 423
424;;;###autoload
425(defvar desktop-minor-mode-handlers
426 nil
427 "Alist of functions to restore non-standard minor modes.
428Functions are called by `desktop-create-buffer' to restore minor modes.
429List elements must have the form
430
431 (MINOR-MODE . RESTORE-FUNCTION).
432
433Minor modes not specified here, are restored by the standard minor mode
434function.
435
436Handlers are called with argument list
437
438 (DESKTOP-BUFFER-LOCALS)
439
440Furthermore, 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
452When a handler is called, the buffer has been created and the major mode has
453been set, but local variables listed in desktop-buffer-locals has not yet been
454created and set.
455
456Modules that define a minor mode that needs a special handler should contain
457code like
458
459 (defun foo-desktop-restore
460 ...
461 (add-to-list 'desktop-minor-mode-handlers
462 '(foo-mode . foo-desktop-restore))
463
464Furthermore the minor mode function must be autoloaded.
465
466See also `desktop-minor-mode-table'.")
467
468(put 'desktop-minor-mode-handlers 'risky-local-variable t)
469
362;; ---------------------------------------------------------------------------- 470;; ----------------------------------------------------------------------------
363(defvar desktop-dirname nil 471(defvar desktop-dirname nil
364 "The directory in which the desktop file should be saved.") 472 "The directory in which the desktop file should be saved.")
@@ -382,23 +490,27 @@ this table."
382;; ---------------------------------------------------------------------------- 490;; ----------------------------------------------------------------------------
383(defun desktop-clear () 491(defun desktop-clear ()
384 "Empty the Desktop. 492 "Empty the Desktop.
385This kills all buffers except for internal ones and those matching 493This kills all buffers except for internal ones and those with names matched by
386`desktop-clear-preserve-buffers-regexp' or listed in 494a regular expression in the list `desktop-clear-preserve-buffers'.
387`desktop-clear-preserve-buffers'. Furthermore, it clears the 495Furthermore, it clears the variables listed in `desktop-globals-to-clear'."
388variables listed in `desktop-globals-to-clear'."
389 (interactive) 496 (interactive)
390 (desktop-lazy-abort) 497 (desktop-lazy-abort)
391 (dolist (var desktop-globals-to-clear) 498 (dolist (var desktop-globals-to-clear)
392 (if (symbolp var) 499 (if (symbolp var)
393 (eval `(setq-default ,var nil)) 500 (eval `(setq-default ,var nil))
394 (eval `(setq-default ,(car var) ,(cdr var))))) 501 (eval `(setq-default ,(car var) ,(cdr var)))))
395 (let ((buffers (buffer-list))) 502 (let ((buffers (buffer-list))
503 (preserve-regexp (concat "^\\("
504 (mapconcat (lambda (regexp)
505 (concat "\\(" regexp "\\)"))
506 desktop-clear-preserve-buffers
507 "\\|")
508 "\\)$")))
396 (while buffers 509 (while buffers
397 (let ((bufname (buffer-name (car buffers)))) 510 (let ((bufname (buffer-name (car buffers))))
398 (or 511 (or
399 (null bufname) 512 (null bufname)
400 (string-match desktop-clear-preserve-buffers-regexp bufname) 513 (string-match preserve-regexp bufname)
401 (member bufname desktop-clear-preserve-buffers)
402 ;; Don't kill buffers made for internal purposes. 514 ;; Don't kill buffers made for internal purposes.
403 (and (not (equal bufname "")) (eq (aref bufname 0) ?\s)) 515 (and (not (equal bufname "")) (eq (aref bufname 0) ?\s))
404 (kill-buffer (car buffers)))) 516 (kill-buffer (car buffers))))
@@ -622,12 +734,10 @@ See also `desktop-base-file-name'."
622 (and 734 (and
623 (boundp minor-mode) 735 (boundp minor-mode)
624 (symbol-value minor-mode) 736 (symbol-value minor-mode)
625 (let ((special (assq minor-mode desktop-minor-mode-table))) 737 (let* ((special (assq minor-mode desktop-minor-mode-table))
626 (when (or special (functionp minor-mode)) 738 (value (cond (special (cadr special))
627 (setq ret 739 ((functionp minor-mode) minor-mode))))
628 (cons 740 (when value (add-to-list 'ret value)))))
629 (if special (cadr special) minor-mode)
630 ret))))))
631 (mapcar #'car minor-mode-alist)) 741 (mapcar #'car minor-mode-alist))
632 ret) 742 ret)
633 (point) 743 (point)
@@ -685,7 +795,6 @@ See also `desktop-base-file-name'."
685 (insert ")\n\n"))) 795 (insert ")\n\n")))
686 info) 796 info)
687 (setq default-directory dirname) 797 (setq default-directory dirname)
688 (when (file-exists-p filename) (delete-file filename))
689 (let ((coding-system-for-write 'emacs-mule)) 798 (let ((coding-system-for-write 'emacs-mule))
690 (write-region (point-min) (point-max) filename nil 'nomessage)))) 799 (write-region (point-min) (point-max) filename nil 'nomessage))))
691 (setq desktop-dirname dirname)) 800 (setq desktop-dirname dirname))
@@ -850,13 +959,20 @@ directory DIRNAME."
850 buf) 959 buf)
851 nil))) 960 nil)))
852 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
853;; ---------------------------------------------------------------------------- 969;; ----------------------------------------------------------------------------
854;; Create a buffer, load its file, set its mode, ...; 970;; Create a buffer, load its file, set its mode, ...;
855;; called from Desktop file only. 971;; called from Desktop file only.
856 972
857(eval-when-compile ; Just to silence the byte compiler 973;; Just to silence the byte compiler.
858 (defvar desktop-first-buffer) ;; Dynamically bound in `desktop-read' 974(eval-when-compile
859) 975 (defvar desktop-first-buffer)) ; Dynamically bound in `desktop-read'
860 976
861(defun desktop-create-buffer 977(defun desktop-create-buffer
862 (desktop-file-version 978 (desktop-file-version
@@ -877,6 +993,8 @@ directory DIRNAME."
877 ;; To make desktop files with relative file names possible, we cannot 993 ;; To make desktop files with relative file names possible, we cannot
878 ;; allow `default-directory' to change. Therefore we save current buffer. 994 ;; allow `default-directory' to change. Therefore we save current buffer.
879 (save-current-buffer 995 (save-current-buffer
996 ;; Give major mode module a chance to add a handler.
997 (desktop-load-file desktop-buffer-major-mode)
880 (let ((buffer-list (buffer-list)) 998 (let ((buffer-list (buffer-list))
881 (result 999 (result
882 (condition-case err 1000 (condition-case err
@@ -914,9 +1032,15 @@ directory DIRNAME."
914 (auto-fill-mode 0)) 1032 (auto-fill-mode 0))
915 (t 1033 (t
916 (mapc #'(lambda (minor-mode) 1034 (mapc #'(lambda (minor-mode)
917 (when (functionp minor-mode) (funcall minor-mode 1))) 1035 ;; 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)))))
918 desktop-buffer-minor-modes))) 1042 desktop-buffer-minor-modes)))
919 ;; Even though point and mark are non-nil when written by `desktop-save' 1043 ;; Even though point and mark are non-nil when written by `desktop-save',
920 ;; they may be modified by handlers wanting to set point or mark themselves. 1044 ;; they may be modified by handlers wanting to set point or mark themselves.
921 (when desktop-buffer-point 1045 (when desktop-buffer-point
922 (goto-char 1046 (goto-char