(help-for-help): Update help text.
[bpt/emacs.git] / lisp / desktop.el
CommitLineData
6343ed61
RS
1;;; desktop.el --- save partial status of Emacs when killed
2
f4c73d07 3;; Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
6343ed61
RS
4
5;; Author: Morten Welinder <terra@diku.dk>
b6105c76
RS
6;; Keywords: customization
7;; Favourite-brand-of-beer: None, I hate beer.
6343ed61
RS
8
9;; This file is part of GNU Emacs.
10
11;; GNU Emacs is free software; you can redistribute it and/or modify
12;; it under the terms of the GNU General Public License as published by
13;; the Free Software Foundation; either version 2, or (at your option)
14;; any later version.
15
16;; GNU Emacs is distributed in the hope that it will be useful,
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
b578f267
EN
22;; along with GNU Emacs; see the file COPYING. If not, write to the
23;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24;; Boston, MA 02111-1307, USA.
6343ed61
RS
25
26;;; Commentary:
27
0b9bd504
RS
28;; Save the Desktop, i.e.,
29;; - some global variables
30;; - the list of buffers with associated files. For each buffer also
31;; - the major mode
32;; - the default directory
33;; - the point
34;; - the mark & mark-active
35;; - buffer-read-only
ec4c6f22 36;; - some local variables
6343ed61 37
0b9bd504
RS
38;; To use this, first put these three lines in the bottom of your .emacs
39;; file (the later the better):
40;;
41;; (load "desktop")
42;; (desktop-load-default)
43;; (desktop-read)
44;;
ec4c6f22 45;; Between the second and the third line you may wish to add something that
de9e2828 46;; updates the variables `desktop-globals-to-save' and/or
ec4c6f22
RS
47;; `desktop-locals-to-save'. If for instance you want to save the local
48;; variable `foobar' for every buffer in which it is local, you could add
49;; the line
50;;
51;; (setq desktop-locals-to-save (cons 'foobar desktop-locals-to-save))
52;;
f4c73d07 53;; To avoid saving excessive amounts of data you may also wish to add
ec4c6f22
RS
54;; something like the following
55;;
56;; (add-hook 'kill-emacs-hook
de9e2828 57;; '(lambda ()
ec4c6f22
RS
58;; (desktop-truncate search-ring 3)
59;; (desktop-truncate regexp-search-ring 3)))
60;;
61;; which will make sure that no more than three search items are saved. You
fa379636
KH
62;; must place this line *after* the (load "desktop") line. See also the
63;; variable desktop-save-hook.
6343ed61 64
0b9bd504
RS
65;; Start Emacs in the root directory of your "project". The desktop saver
66;; is inactive by default. You activate it by M-x desktop-save RET. When
67;; you exit the next time the above data will be saved. This ensures that
68;; all the files you were editing will be reloaded the next time you start
69;; Emacs from the same directory and that points will be set where you
ec4c6f22 70;; left them. If you save a desktop file in your home directory it will
de9e2828 71;; act as a default desktop when you start Emacs from a directory that
ec4c6f22
RS
72;; doesn't have its own. I never do this, but you may want to.
73
74;; By the way: don't use desktop.el to customize Emacs -- the file .emacs
75;; in your home directory is used for that. Saving global default values
76;; for buffers is an example of misuse.
77
0b9bd504
RS
78;; PLEASE NOTE: The kill ring can be saved as specified by the variable
79;; `desktop-globals-to-save' (by default it isn't). This may result in saving
80;; things you did not mean to keep. Use M-x desktop-clear RET.
ec4c6f22 81
fa379636
KH
82;; Thanks to hetrick@phys.uva.nl (Jim Hetrick) for useful ideas.
83;; avk@rtsg.mot.com (Andrew V. Klein) for a dired tip.
84;; chris@tecc.co.uk (Chris Boucher) for a mark tip.
85;; f89-kam@nada.kth.se (Klas Mellbourn) for a mh-e tip.
86;; kifer@sbkifer.cs.sunysb.edu (M. Kifer) for a bug hunt.
f4c73d07 87;; treese@lcs.mit.edu (Win Treese) for ange-ftp tips.
253406b9 88;; pot@cnuce.cnr.it (Francesco Potorti`) for misc. tips.
0b9bd504
RS
89;; ---------------------------------------------------------------------------
90;; TODO:
91;;
92;; Save window configuration.
93;; Recognize more minor modes.
94;; Save mark rings.
95;; Start-up with buffer-menu???
6343ed61
RS
96
97;;; Code:
98
ec4c6f22
RS
99;; Make the compilation more silent
100(eval-when-compile
101 ;; We use functions from these modules
fa379636
KH
102 ;; We can't (require 'mh-e) since that wants to load something.
103 (mapcar 'require '(info dired reporter)))
ec4c6f22 104;; ----------------------------------------------------------------------------
0b9bd504
RS
105;; USER OPTIONS -- settings you might want to play with.
106;; ----------------------------------------------------------------------------
bbf5eb28
RS
107
108(defgroup desktop nil
109 "Save status of Emacs when you exit."
110 :group 'frames)
111
0b9bd504 112(defconst desktop-basefilename
fc715501 113 (convert-standard-filename ".emacs.desktop")
577ed2b2 114 "File for Emacs desktop, not including the directory name.")
6343ed61 115
bbf5eb28 116(defcustom desktop-missing-file-warning nil
577ed2b2 117 "*If non-nil then desktop warns when a file no longer exists.
bbf5eb28
RS
118Otherwise it simply ignores that file."
119 :type 'boolean
120 :group 'desktop)
6343ed61 121
0b9bd504 122(defvar desktop-globals-to-save
6343ed61 123 (list 'desktop-missing-file-warning
0b9bd504 124 ;; Feature: saving kill-ring implies saving kill-ring-yank-pointer
ec4c6f22 125 ;; 'kill-ring
0b9bd504
RS
126 'tags-file-name
127 'tags-table-list
ec4c6f22
RS
128 'search-ring
129 'regexp-search-ring
de9e2828 130 'register-alist
0b9bd504 131 ;; 'desktop-globals-to-save ; Itself!
b6105c76 132 )
0e7c8611
RS
133 "List of global variables to save when killing Emacs.
134An element may be variable name (a symbol)
135or a cons cell of the form (VAR . MAX-SIZE),
136which means to truncate VAR's value to at most MAX-SIZE elements
137\(if the value is a list) before saving the value.")
6343ed61 138
ec4c6f22
RS
139(defvar desktop-locals-to-save
140 (list 'desktop-locals-to-save ; Itself! Think it over.
141 'truncate-lines
142 'case-fold-search
143 'case-replace
144 'fill-column
145 'overwrite-mode
146 'change-log-default-name
fa379636 147 'line-number-mode
ec4c6f22 148 )
577ed2b2
RS
149 "List of local variables to save for each buffer.
150The variables are saved only when they really are local.")
de9e2828 151(make-variable-buffer-local 'desktop-locals-to-save)
ec4c6f22 152
0b9bd504 153;; We skip .log files because they are normally temporary.
a7acbbe4 154;; (ftp) files because they require passwords and whatnot.
0b9bd504 155;; TAGS files to save time (tags-file-name is saved instead).
bbf5eb28 156(defcustom desktop-buffers-not-to-save
de9e2828 157 "\\(^nn\\.a[0-9]+\\|\\.log\\|(ftp)\\|^tags\\|^TAGS\\)$"
bbf5eb28
RS
158 "Regexp identifying buffers that are to be excluded from saving."
159 :type 'regexp
160 :group 'desktop)
6343ed61 161
fa379636 162;; Skip ange-ftp files
bbf5eb28 163(defcustom desktop-files-not-to-save
fa379636 164 "^/[^/:]*:"
bbf5eb28
RS
165 "Regexp identifying files whose buffers are to be excluded from saving."
166 :type 'regexp
167 :group 'desktop)
fa379636 168
bbf5eb28
RS
169(defcustom desktop-buffer-major-mode nil
170 "When desktop creates a buffer, this holds the desired Major mode."
171 :type 'symbol
172 :group 'desktop)
569c754e 173
bbf5eb28
RS
174(defcustom desktop-buffer-file-name nil
175 "When desktop creates a buffer, this holds the file name to visit."
176 :type '(choice file (const nil))
177 :group 'desktop)
569c754e 178
bbf5eb28
RS
179(defcustom desktop-buffer-name nil
180 "When desktop creates a buffer, this holds the desired buffer name."
181 :type '(choice string (const nil))
182 :group 'desktop)
569c754e 183
2699e23e
RS
184(defvar desktop-buffer-misc nil
185 "When desktop creates a buffer, this holds a list of misc info.
186It is used by the `desktop-buffer-handlers' functions.")
187
bbf5eb28 188(defcustom desktop-buffer-handlers
0b9bd504 189 '(desktop-buffer-dired
6343ed61 190 desktop-buffer-rmail
ec4c6f22 191 desktop-buffer-mh
6343ed61
RS
192 desktop-buffer-info
193 desktop-buffer-file)
577ed2b2 194 "*List of functions to call in order to create a buffer.
569c754e
RS
195The functions are called without explicit parameters but can use the
196variables `desktop-buffer-major-mode', `desktop-buffer-file-name',
197`desktop-buffer-name'.
198If one function returns non-nil, no further functions are called.
bbf5eb28
RS
199If the function returns t then the buffer is considered created."
200 :type '(repeat function)
201 :group 'desktop)
ec4c6f22
RS
202
203(defvar desktop-create-buffer-form "(desktop-create-buffer 205"
204 "Opening of form for creation of new buffers.")
fa379636 205
bbf5eb28 206(defcustom desktop-save-hook nil
fa379636 207 "Hook run before saving the desktop to allow you to cut history lists and
bbf5eb28
RS
208the like shorter."
209 :type 'hook
210 :group 'desktop)
0b9bd504
RS
211;; ----------------------------------------------------------------------------
212(defvar desktop-dirname nil
6343ed61
RS
213 "The directory in which the current desktop file resides.")
214
215(defconst desktop-header
0b9bd504
RS
216";; --------------------------------------------------------------------------
217;; Desktop File for Emacs
218;; --------------------------------------------------------------------------
6343ed61 219" "*Header to place in Desktop file.")
de9e2828
RS
220
221(defvar desktop-delay-hook nil
222 "Hooks run after all buffers are loaded; intended for internal use.")
0b9bd504 223;; ----------------------------------------------------------------------------
ec4c6f22
RS
224(defun desktop-truncate (l n)
225 "Truncate LIST to at most N elements destructively."
226 (let ((here (nthcdr (1- n) l)))
227 (if (consp here)
de9e2828 228 (setcdr here nil))))
ec4c6f22 229;; ----------------------------------------------------------------------------
f9be4574
RS
230(defcustom desktop-clear-preserve-buffers
231 '("*scratch*" "*Messages*")
232 "*Buffer names that `desktop-clear' should not delete."
233 :type '(repeat string)
234 :group 'desktop)
235
236(defun desktop-clear ()
237 "Empty the Desktop.
238This kills all buffers except for internal ones
239and those listed in `desktop-clear-preserve-buffers'."
6343ed61 240 (interactive)
fa379636
KH
241 (setq kill-ring nil
242 kill-ring-yank-pointer nil
243 search-ring nil
244 search-ring-yank-pointer nil
245 regexp-search-ring nil
246 regexp-search-ring-yank-pointer nil)
f9be4574
RS
247 (let ((buffers (buffer-list)))
248 (while buffers
249 (or (member (buffer-name (car buffers)) desktop-clear-preserve-buffers)
250 ;; Don't kill buffers made for internal purposes.
251 (and (not (equal (buffer-name (car buffers)) ""))
252 (eq (aref (buffer-name (car buffers)) 0) ?\ ))
253 (kill-buffer (car buffers)))
254 (setq buffers (cdr buffers))))
b6105c76 255 (delete-other-windows))
0b9bd504 256;; ----------------------------------------------------------------------------
de9e2828 257(add-hook 'kill-emacs-hook 'desktop-kill)
ec4c6f22 258
6343ed61 259(defun desktop-kill ()
0b9bd504 260 (if desktop-dirname
fa379636
KH
261 (condition-case err
262 (desktop-save desktop-dirname)
263 (file-error
264 (if (yes-or-no-p "Error while saving the desktop. Quit anyway? ")
265 nil
266 (signal (car err) (cdr err)))))))
0b9bd504 267;; ----------------------------------------------------------------------------
ed2f7fc8
RS
268(defun desktop-list* (&rest args)
269 (if (null (cdr args))
270 (car args)
271 (setq args (nreverse args))
272 (let ((value (cons (nth 1 args) (car args))))
273 (setq args (cdr (cdr args)))
274 (while args
275 (setq value (cons (car args) value))
276 (setq args (cdr args)))
277 value)))
278
de9e2828 279(defun desktop-internal-v2s (val)
577ed2b2
RS
280 "Convert VALUE to a pair (QUOTE . TXT); (eval (read TXT)) gives VALUE.
281TXT is a string that when read and evaluated yields value.
282QUOTE may be `may' (value may be quoted),
283`must' (values must be quoted), or nil (value may not be quoted)."
de9e2828 284 (cond
e2247420 285 ((or (numberp val) (null val) (eq t val))
de9e2828 286 (cons 'may (prin1-to-string val)))
e2247420 287 ((stringp val)
95bf6435
RS
288 (let ((copy (copy-sequence val)))
289 (set-text-properties 0 (length copy) nil copy)
290 ;; Get rid of text properties because we cannot read them
291 (cons 'may (prin1-to-string copy))))
de9e2828
RS
292 ((symbolp val)
293 (cons 'must (prin1-to-string val)))
294 ((vectorp val)
295 (let* ((special nil)
296 (pass1 (mapcar
297 (lambda (el)
298 (let ((res (desktop-internal-v2s el)))
299 (if (null (car res))
300 (setq special t))
301 res))
302 val)))
303 (if special
304 (cons nil (concat "(vector "
305 (mapconcat (lambda (el)
306 (if (eq (car el) 'must)
307 (concat "'" (cdr el))
308 (cdr el)))
309 pass1
310 " ")
311 ")"))
312 (cons 'may (concat "[" (mapconcat 'cdr pass1 " ") "]")))))
313 ((consp val)
b4929f75
RS
314 (let ((p val)
315 newlist
ed2f7fc8 316 use-list*
b4929f75
RS
317 anynil)
318 (while (consp p)
319 (let ((q.txt (desktop-internal-v2s (car p))))
320 (or anynil (setq anynil (null (car q.txt))))
321 (setq newlist (cons q.txt newlist)))
322 (setq p (cdr p)))
323 (if p
324 (let ((last (desktop-internal-v2s p))
325 (el (car newlist)))
ed2f7fc8
RS
326 (or anynil (setq anynil (null (car last))))
327 (or anynil
328 (setq newlist (cons '(must . ".") newlist)))
329 (setq use-list* t)
330 (setq newlist (cons last newlist))))
b4929f75
RS
331 (setq newlist (nreverse newlist))
332 (if anynil
333 (cons nil
ed2f7fc8 334 (concat (if use-list* "(desktop-list* " "(list ")
b4929f75
RS
335 (mapconcat (lambda (el)
336 (if (eq (car el) 'must)
337 (concat "'" (cdr el))
338 (cdr el)))
339 newlist
340 " ")
341 ")"))
342 (cons 'must
343 (concat "(" (mapconcat 'cdr newlist " ") ")")))))
de9e2828
RS
344 ((subrp val)
345 (cons nil (concat "(symbol-function '"
346 (substring (prin1-to-string val) 7 -1)
347 ")")))
348 ((markerp val)
349 (let ((pos (prin1-to-string (marker-position val)))
350 (buf (prin1-to-string (buffer-name (marker-buffer val)))))
351 (cons nil (concat "(let ((mk (make-marker)))"
352 " (add-hook 'desktop-delay-hook"
353 " (list 'lambda '() (list 'set-marker mk "
354 pos " (get-buffer " buf ")))) mk)"))))
355 (t ; save as text
fa379636 356 (cons 'may "\"Unprintable entity\""))))
de9e2828 357
ec4c6f22 358(defun desktop-value-to-string (val)
577ed2b2
RS
359 "Convert VALUE to a string that when read evaluates to the same value.
360Not all types of values are supported."
de9e2828
RS
361 (let* ((print-escape-newlines t)
362 (float-output-format nil)
363 (quote.txt (desktop-internal-v2s val))
364 (quote (car quote.txt))
365 (txt (cdr quote.txt)))
366 (if (eq quote 'must)
367 (concat "'" txt)
368 txt)))
ec4c6f22 369;; ----------------------------------------------------------------------------
0e7c8611
RS
370(defun desktop-outvar (varspec)
371 "Output a setq statement for variable VAR to the desktop file.
372The argument VARSPEC may be the variable name VAR (a symbol),
373or a cons cell of the form (VAR . MAX-SIZE),
374which means to truncate VAR's value to at most MAX-SIZE elements
375\(if the value is a list) before saving the value."
376 (let (var size)
377 (if (consp varspec)
378 (setq var (car varspec) size (cdr varspec))
379 (setq var varspec))
380 (if (boundp var)
381 (progn
382 (if (and (integerp size)
383 (> size 0)
384 (listp (eval var)))
385 (desktop-truncate (eval var) size))
386 (insert "(setq "
387 (symbol-name var)
388 " "
389 (desktop-value-to-string (symbol-value var))
390 ")\n")))))
0b9bd504 391;; ----------------------------------------------------------------------------
ec4c6f22 392(defun desktop-save-buffer-p (filename bufname mode &rest dummy)
b6105c76 393 "Return t if the desktop should record a particular buffer for next startup.
0b9bd504 394FILENAME is the visited file name, BUFNAME is the buffer name, and
6343ed61 395MODE is the major mode."
fa379636
KH
396 (let ((case-fold-search nil))
397 (or (and filename
398 (not (string-match desktop-buffers-not-to-save bufname))
399 (not (string-match desktop-files-not-to-save filename)))
400 (and (eq mode 'dired-mode)
401 (save-excursion
402 (set-buffer (get-buffer bufname))
403 (not (string-match desktop-files-not-to-save
404 default-directory))))
405 (and (null filename)
406 (memq mode '(Info-mode rmail-mode))))))
0b9bd504 407;; ----------------------------------------------------------------------------
6343ed61
RS
408(defun desktop-save (dirname)
409 "Save the Desktop file. Parameter DIRNAME specifies where to save desktop."
410 (interactive "DDirectory to save desktop file in: ")
fa379636 411 (run-hooks 'desktop-save-hook)
6343ed61 412 (save-excursion
0b9bd504 413 (let ((filename (expand-file-name
6343ed61 414 (concat dirname desktop-basefilename)))
0b9bd504
RS
415 (info (nreverse
416 (mapcar
6343ed61
RS
417 (function (lambda (b)
418 (set-buffer b)
0b9bd504 419 (list
6343ed61
RS
420 (buffer-file-name)
421 (buffer-name)
ec4c6f22
RS
422 major-mode
423 (list ; list explaining minor modes
fa379636 424 (not (null auto-fill-function)))
6343ed61 425 (point)
de9e2828 426 (list (mark t) mark-active)
6343ed61 427 buffer-read-only
ec4c6f22
RS
428 (cond ((eq major-mode 'Info-mode)
429 (list Info-current-file
430 Info-current-node))
431 ((eq major-mode 'dired-mode)
f4c73d07
RS
432 (cons
433 (expand-file-name dired-directory)
434 (cdr
435 (nreverse
436 (mapcar
437 (function car)
438 dired-subdir-alist))))))
ec4c6f22
RS
439 (let ((locals desktop-locals-to-save)
440 (loclist (buffer-local-variables))
441 (ll))
442 (while locals
443 (let ((here (assq (car locals) loclist)))
444 (if here
445 (setq ll (cons here ll))
446 (if (member (car locals) loclist)
447 (setq ll (cons (car locals) ll)))))
448 (setq locals (cdr locals)))
449 ll)
6343ed61
RS
450 )))
451 (buffer-list))))
452 (buf (get-buffer-create "*desktop*")))
453 (set-buffer buf)
454 (erase-buffer)
fa379636 455
0b9bd504
RS
456 (insert desktop-header
457 ";; Created " (current-time-string) "\n"
fa379636
KH
458 ";; Emacs version " emacs-version "\n\n"
459 ";; Global section:\n")
6343ed61
RS
460 (mapcar (function desktop-outvar) desktop-globals-to-save)
461 (if (memq 'kill-ring desktop-globals-to-save)
0b9bd504
RS
462 (insert "(setq kill-ring-yank-pointer (nthcdr "
463 (int-to-string
6343ed61
RS
464 (- (length kill-ring) (length kill-ring-yank-pointer)))
465 " kill-ring))\n"))
466
0b9bd504 467 (insert "\n;; Buffer section:\n")
de9e2828
RS
468 (mapcar
469 (function (lambda (l)
470 (if (apply 'desktop-save-buffer-p l)
471 (progn
472 (insert desktop-create-buffer-form)
473 (mapcar
474 (function (lambda (e)
475 (insert "\n "
476 (desktop-value-to-string e))))
477 l)
478 (insert ")\n\n")))))
479 info)
6343ed61
RS
480 (setq default-directory dirname)
481 (if (file-exists-p filename) (delete-file filename))
482 (write-region (point-min) (point-max) filename nil 'nomessage)))
483 (setq desktop-dirname dirname))
0b9bd504 484;; ----------------------------------------------------------------------------
6343ed61
RS
485(defun desktop-remove ()
486 "Delete the Desktop file and inactivate the desktop system."
487 (interactive)
488 (if desktop-dirname
489 (let ((filename (concat desktop-dirname desktop-basefilename)))
fa379636
KH
490 (setq desktop-dirname nil)
491 (if (file-exists-p filename)
492 (delete-file filename)))))
0b9bd504 493;; ----------------------------------------------------------------------------
6343ed61 494(defun desktop-read ()
253406b9
RS
495 "Read the Desktop file and the files it specifies.
496This is a no-op when Emacs is running in batch mode."
6343ed61 497 (interactive)
253406b9
RS
498 (if noninteractive
499 nil
500 (let ((dirs '("./" "~/")))
501 (while (and dirs
502 (not (file-exists-p (expand-file-name
503 desktop-basefilename
504 (car dirs)))))
505 (setq dirs (cdr dirs)))
506 (setq desktop-dirname (and dirs (expand-file-name (car dirs))))
507 (if desktop-dirname
508 (progn
509 (load (expand-file-name desktop-basefilename desktop-dirname)
510 t t t)
511 (run-hooks 'desktop-delay-hook)
512 (setq desktop-delay-hook nil)
513 (message "Desktop loaded."))
514 (desktop-clear)))))
0b9bd504 515;; ----------------------------------------------------------------------------
6343ed61 516(defun desktop-load-default ()
577ed2b2
RS
517 "Load the `default' start-up library manually.
518Also inhibit further loading of it. Call this from your `.emacs' file
519to provide correct modes for autoloaded files."
0b9bd504 520 (if (not inhibit-default-init) ; safety check
6343ed61
RS
521 (progn
522 (load "default" t t)
523 (setq inhibit-default-init t))))
0b9bd504
RS
524;; ----------------------------------------------------------------------------
525;; Note: the following functions use the dynamic variable binding in Lisp.
0b9bd504 526;;
6343ed61 527(defun desktop-buffer-info () "Load an info file."
569c754e 528 (if (eq 'Info-mode desktop-buffer-major-mode)
6343ed61
RS
529 (progn
530 (require 'info)
2699e23e 531 (Info-find-node (nth 0 desktop-buffer-misc) (nth 1 desktop-buffer-misc))
6343ed61 532 t)))
0b9bd504 533;; ----------------------------------------------------------------------------
b6105c76 534(defun desktop-buffer-rmail () "Load an RMAIL file."
569c754e 535 (if (eq 'rmail-mode desktop-buffer-major-mode)
e36d00d4 536 (condition-case error
569c754e 537 (progn (rmail-input desktop-buffer-file-name) t)
e2247420
RS
538 (file-locked
539 (kill-buffer (current-buffer))
540 'ignored))))
0b9bd504 541;; ----------------------------------------------------------------------------
ec4c6f22 542(defun desktop-buffer-mh () "Load a folder in the mh system."
569c754e 543 (if (eq 'mh-folder-mode desktop-buffer-major-mode)
ec4c6f22
RS
544 (progn
545 (require 'mh-e)
546 (mh-find-path)
569c754e 547 (mh-visit-folder desktop-buffer-name)
ec4c6f22
RS
548 t)))
549;; ----------------------------------------------------------------------------
6343ed61 550(defun desktop-buffer-dired () "Load a directory using dired."
569c754e 551 (if (eq 'dired-mode desktop-buffer-major-mode)
2699e23e 552 (if (file-directory-p (file-name-directory (car desktop-buffer-misc)))
fa379636 553 (progn
2699e23e
RS
554 (dired (car desktop-buffer-misc))
555 (mapcar 'dired-insert-subdir (cdr desktop-buffer-misc))
fa379636 556 t)
2699e23e 557 (message "Directory %s no longer exists." (car desktop-buffer-misc))
fa379636
KH
558 (sit-for 1)
559 'ignored)))
0b9bd504 560;; ----------------------------------------------------------------------------
6343ed61 561(defun desktop-buffer-file () "Load a file."
569c754e
RS
562 (if desktop-buffer-file-name
563 (if (or (file-exists-p desktop-buffer-file-name)
6343ed61 564 (and desktop-missing-file-warning
0b9bd504
RS
565 (y-or-n-p (format
566 "File \"%s\" no longer exists. Re-create? "
569c754e
RS
567 desktop-buffer-file-name))))
568 (progn (find-file desktop-buffer-file-name) t)
6343ed61 569 'ignored)))
0b9bd504
RS
570;; ----------------------------------------------------------------------------
571;; Create a buffer, load its file, set is mode, ...; called from Desktop file
6343ed61 572;; only.
569c754e
RS
573(defun desktop-create-buffer (ver desktop-buffer-file-name desktop-buffer-name
574 desktop-buffer-major-mode
2699e23e 575 mim pt mk ro desktop-buffer-misc &optional locals)
6343ed61
RS
576 (let ((hlist desktop-buffer-handlers)
577 (result)
578 (handler))
579 (while (and (not result) hlist)
580 (setq handler (car hlist))
581 (setq result (funcall handler))
582 (setq hlist (cdr hlist)))
b6105c76 583 (if (eq result t)
6343ed61 584 (progn
569c754e
RS
585 (if (not (equal (buffer-name) desktop-buffer-name))
586 (rename-buffer desktop-buffer-name))
ec4c6f22 587 (auto-fill-mode (if (nth 0 mim) 1 0))
6343ed61 588 (goto-char pt)
0b9bd504
RS
589 (if (consp mk)
590 (progn
591 (set-mark (car mk))
592 (setq mark-active (car (cdr mk))))
593 (set-mark mk))
594 ;; Never override file system if the file really is read-only marked.
595 (if ro (setq buffer-read-only ro))
ec4c6f22
RS
596 (while locals
597 (let ((this (car locals)))
598 (if (consp this)
599 ;; an entry of this form `(symbol . value)'
600 (progn
601 (make-local-variable (car this))
602 (set (car this) (cdr this)))
603 ;; an entry of the form `symbol'
604 (make-local-variable this)
605 (makunbound this)))
606 (setq locals (cdr locals)))
6343ed61 607 ))))
ec4c6f22
RS
608
609;; Backward compatibility -- update parameters to 205 standards.
569c754e
RS
610(defun desktop-buffer (desktop-buffer-file-name desktop-buffer-name
611 desktop-buffer-major-mode
2699e23e 612 mim pt mk ro tl fc cfs cr desktop-buffer-misc)
569c754e 613 (desktop-create-buffer 205 desktop-buffer-file-name desktop-buffer-name
2699e23e
RS
614 desktop-buffer-major-mode (cdr mim) pt mk ro
615 desktop-buffer-misc
ec4c6f22
RS
616 (list (cons 'truncate-lines tl)
617 (cons 'fill-column fc)
618 (cons 'case-fold-search cfs)
619 (cons 'case-replace cr)
620 (cons 'overwrite-mode (car mim)))))
0b9bd504 621;; ----------------------------------------------------------------------------
ab1d55ea 622(provide 'desktop)
6343ed61
RS
623
624;; desktop.el ends here.