Comment fixes.
[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.
0b9bd504
RS
88;; ---------------------------------------------------------------------------
89;; TODO:
90;;
91;; Save window configuration.
92;; Recognize more minor modes.
93;; Save mark rings.
94;; Start-up with buffer-menu???
6343ed61
RS
95
96;;; Code:
97
ec4c6f22
RS
98;; Make the compilation more silent
99(eval-when-compile
100 ;; We use functions from these modules
fa379636
KH
101 ;; We can't (require 'mh-e) since that wants to load something.
102 (mapcar 'require '(info dired reporter)))
ec4c6f22 103;; ----------------------------------------------------------------------------
0b9bd504
RS
104;; USER OPTIONS -- settings you might want to play with.
105;; ----------------------------------------------------------------------------
106(defconst desktop-basefilename
4a091f2a 107 (if (or (eq system-type 'ms-dos) (eq system-type 'windows-nt))
6343ed61
RS
108 "emacs.dsk" ; Ms-Dos does not support multiple dots in file name
109 ".emacs.desktop")
577ed2b2 110 "File for Emacs desktop, not including the directory name.")
6343ed61 111
0b9bd504 112(defvar desktop-missing-file-warning t
577ed2b2
RS
113 "*If non-nil then desktop warns when a file no longer exists.
114Otherwise it simply ignores that file.")
6343ed61 115
0b9bd504 116(defvar desktop-globals-to-save
6343ed61 117 (list 'desktop-missing-file-warning
0b9bd504 118 ;; Feature: saving kill-ring implies saving kill-ring-yank-pointer
ec4c6f22 119 ;; 'kill-ring
0b9bd504
RS
120 'tags-file-name
121 'tags-table-list
ec4c6f22
RS
122 'search-ring
123 'regexp-search-ring
de9e2828 124 'register-alist
0b9bd504 125 ;; 'desktop-globals-to-save ; Itself!
b6105c76 126 )
0e7c8611
RS
127 "List of global variables to save when killing Emacs.
128An element may be variable name (a symbol)
129or a cons cell of the form (VAR . MAX-SIZE),
130which means to truncate VAR's value to at most MAX-SIZE elements
131\(if the value is a list) before saving the value.")
6343ed61 132
ec4c6f22
RS
133(defvar desktop-locals-to-save
134 (list 'desktop-locals-to-save ; Itself! Think it over.
135 'truncate-lines
136 'case-fold-search
137 'case-replace
138 'fill-column
139 'overwrite-mode
140 'change-log-default-name
fa379636 141 'line-number-mode
ec4c6f22 142 )
577ed2b2
RS
143 "List of local variables to save for each buffer.
144The variables are saved only when they really are local.")
de9e2828 145(make-variable-buffer-local 'desktop-locals-to-save)
ec4c6f22 146
0b9bd504 147;; We skip .log files because they are normally temporary.
a7acbbe4 148;; (ftp) files because they require passwords and whatnot.
0b9bd504 149;; TAGS files to save time (tags-file-name is saved instead).
6343ed61 150(defvar desktop-buffers-not-to-save
de9e2828 151 "\\(^nn\\.a[0-9]+\\|\\.log\\|(ftp)\\|^tags\\|^TAGS\\)$"
6343ed61
RS
152 "Regexp identifying buffers that are to be excluded from saving.")
153
fa379636
KH
154;; Skip ange-ftp files
155(defvar desktop-files-not-to-save
156 "^/[^/:]*:"
157 "Regexp identifying files whose buffers are to be excluded from saving.")
158
6343ed61 159(defvar desktop-buffer-handlers
0b9bd504 160 '(desktop-buffer-dired
6343ed61 161 desktop-buffer-rmail
ec4c6f22 162 desktop-buffer-mh
6343ed61
RS
163 desktop-buffer-info
164 desktop-buffer-file)
577ed2b2
RS
165 "*List of functions to call in order to create a buffer.
166The functions are called without explicit parameters but may access
167the the major mode as `mam', the file name as `fn', the buffer name as
168`bn', the default directory as `dd'. If some function returns non-nil
169no further functions are called. If the function returns t then the
170buffer is considered created.")
ec4c6f22
RS
171
172(defvar desktop-create-buffer-form "(desktop-create-buffer 205"
173 "Opening of form for creation of new buffers.")
fa379636
KH
174
175(defvar desktop-save-hook nil
176 "Hook run before saving the desktop to allow you to cut history lists and
177the like shorter.")
0b9bd504
RS
178;; ----------------------------------------------------------------------------
179(defvar desktop-dirname nil
6343ed61
RS
180 "The directory in which the current desktop file resides.")
181
182(defconst desktop-header
0b9bd504
RS
183";; --------------------------------------------------------------------------
184;; Desktop File for Emacs
185;; --------------------------------------------------------------------------
6343ed61 186" "*Header to place in Desktop file.")
de9e2828
RS
187
188(defvar desktop-delay-hook nil
189 "Hooks run after all buffers are loaded; intended for internal use.")
0b9bd504 190;; ----------------------------------------------------------------------------
ec4c6f22
RS
191(defun desktop-truncate (l n)
192 "Truncate LIST to at most N elements destructively."
193 (let ((here (nthcdr (1- n) l)))
194 (if (consp here)
de9e2828 195 (setcdr here nil))))
ec4c6f22 196;; ----------------------------------------------------------------------------
6343ed61
RS
197(defun desktop-clear () "Empty the Desktop."
198 (interactive)
fa379636
KH
199 (setq kill-ring nil
200 kill-ring-yank-pointer nil
201 search-ring nil
202 search-ring-yank-pointer nil
203 regexp-search-ring nil
204 regexp-search-ring-yank-pointer nil)
b6105c76
RS
205 (mapcar (function kill-buffer) (buffer-list))
206 (delete-other-windows))
0b9bd504 207;; ----------------------------------------------------------------------------
de9e2828 208(add-hook 'kill-emacs-hook 'desktop-kill)
ec4c6f22 209
6343ed61 210(defun desktop-kill ()
0b9bd504 211 (if desktop-dirname
fa379636
KH
212 (condition-case err
213 (desktop-save desktop-dirname)
214 (file-error
215 (if (yes-or-no-p "Error while saving the desktop. Quit anyway? ")
216 nil
217 (signal (car err) (cdr err)))))))
0b9bd504 218;; ----------------------------------------------------------------------------
de9e2828 219(defun desktop-internal-v2s (val)
577ed2b2
RS
220 "Convert VALUE to a pair (QUOTE . TXT); (eval (read TXT)) gives VALUE.
221TXT is a string that when read and evaluated yields value.
222QUOTE may be `may' (value may be quoted),
223`must' (values must be quoted), or nil (value may not be quoted)."
de9e2828 224 (cond
e2247420 225 ((or (numberp val) (null val) (eq t val))
de9e2828 226 (cons 'may (prin1-to-string val)))
e2247420 227 ((stringp val)
95bf6435
RS
228 (let ((copy (copy-sequence val)))
229 (set-text-properties 0 (length copy) nil copy)
230 ;; Get rid of text properties because we cannot read them
231 (cons 'may (prin1-to-string copy))))
de9e2828
RS
232 ((symbolp val)
233 (cons 'must (prin1-to-string val)))
234 ((vectorp val)
235 (let* ((special nil)
236 (pass1 (mapcar
237 (lambda (el)
238 (let ((res (desktop-internal-v2s el)))
239 (if (null (car res))
240 (setq special t))
241 res))
242 val)))
243 (if special
244 (cons nil (concat "(vector "
245 (mapconcat (lambda (el)
246 (if (eq (car el) 'must)
247 (concat "'" (cdr el))
248 (cdr el)))
249 pass1
250 " ")
251 ")"))
252 (cons 'may (concat "[" (mapconcat 'cdr pass1 " ") "]")))))
253 ((consp val)
b4929f75
RS
254 (let ((p val)
255 newlist
256 anynil)
257 (while (consp p)
258 (let ((q.txt (desktop-internal-v2s (car p))))
259 (or anynil (setq anynil (null (car q.txt))))
260 (setq newlist (cons q.txt newlist)))
261 (setq p (cdr p)))
262 (if p
263 (let ((last (desktop-internal-v2s p))
264 (el (car newlist)))
265 (setcar newlist
266 (if (or anynil (setq anynil (null (car last))))
267 (cons nil
268 (concat "(cons "
269 (if (eq (car el) 'must) "'" "")
270 (cdr el)
271 " "
272 (if (eq (car last) 'must) "'" "")
273 (cdr last)
274 ")"))
275 (cons 'must
276 (concat (cdr el) " . " (cdr last)))))))
277 (setq newlist (nreverse newlist))
278 (if anynil
279 (cons nil
280 (concat "(list "
281 (mapconcat (lambda (el)
282 (if (eq (car el) 'must)
283 (concat "'" (cdr el))
284 (cdr el)))
285 newlist
286 " ")
287 ")"))
288 (cons 'must
289 (concat "(" (mapconcat 'cdr newlist " ") ")")))))
de9e2828
RS
290 ((subrp val)
291 (cons nil (concat "(symbol-function '"
292 (substring (prin1-to-string val) 7 -1)
293 ")")))
294 ((markerp val)
295 (let ((pos (prin1-to-string (marker-position val)))
296 (buf (prin1-to-string (buffer-name (marker-buffer val)))))
297 (cons nil (concat "(let ((mk (make-marker)))"
298 " (add-hook 'desktop-delay-hook"
299 " (list 'lambda '() (list 'set-marker mk "
300 pos " (get-buffer " buf ")))) mk)"))))
301 (t ; save as text
fa379636 302 (cons 'may "\"Unprintable entity\""))))
de9e2828 303
ec4c6f22 304(defun desktop-value-to-string (val)
577ed2b2
RS
305 "Convert VALUE to a string that when read evaluates to the same value.
306Not all types of values are supported."
de9e2828
RS
307 (let* ((print-escape-newlines t)
308 (float-output-format nil)
309 (quote.txt (desktop-internal-v2s val))
310 (quote (car quote.txt))
311 (txt (cdr quote.txt)))
312 (if (eq quote 'must)
313 (concat "'" txt)
314 txt)))
ec4c6f22 315;; ----------------------------------------------------------------------------
0e7c8611
RS
316(defun desktop-outvar (varspec)
317 "Output a setq statement for variable VAR to the desktop file.
318The argument VARSPEC may be the variable name VAR (a symbol),
319or a cons cell of the form (VAR . MAX-SIZE),
320which means to truncate VAR's value to at most MAX-SIZE elements
321\(if the value is a list) before saving the value."
322 (let (var size)
323 (if (consp varspec)
324 (setq var (car varspec) size (cdr varspec))
325 (setq var varspec))
326 (if (boundp var)
327 (progn
328 (if (and (integerp size)
329 (> size 0)
330 (listp (eval var)))
331 (desktop-truncate (eval var) size))
332 (insert "(setq "
333 (symbol-name var)
334 " "
335 (desktop-value-to-string (symbol-value var))
336 ")\n")))))
0b9bd504 337;; ----------------------------------------------------------------------------
ec4c6f22 338(defun desktop-save-buffer-p (filename bufname mode &rest dummy)
b6105c76 339 "Return t if the desktop should record a particular buffer for next startup.
0b9bd504 340FILENAME is the visited file name, BUFNAME is the buffer name, and
6343ed61 341MODE is the major mode."
fa379636
KH
342 (let ((case-fold-search nil))
343 (or (and filename
344 (not (string-match desktop-buffers-not-to-save bufname))
345 (not (string-match desktop-files-not-to-save filename)))
346 (and (eq mode 'dired-mode)
347 (save-excursion
348 (set-buffer (get-buffer bufname))
349 (not (string-match desktop-files-not-to-save
350 default-directory))))
351 (and (null filename)
352 (memq mode '(Info-mode rmail-mode))))))
0b9bd504 353;; ----------------------------------------------------------------------------
6343ed61
RS
354(defun desktop-save (dirname)
355 "Save the Desktop file. Parameter DIRNAME specifies where to save desktop."
356 (interactive "DDirectory to save desktop file in: ")
fa379636 357 (run-hooks 'desktop-save-hook)
6343ed61 358 (save-excursion
0b9bd504 359 (let ((filename (expand-file-name
6343ed61 360 (concat dirname desktop-basefilename)))
0b9bd504
RS
361 (info (nreverse
362 (mapcar
6343ed61
RS
363 (function (lambda (b)
364 (set-buffer b)
0b9bd504 365 (list
6343ed61
RS
366 (buffer-file-name)
367 (buffer-name)
ec4c6f22
RS
368 major-mode
369 (list ; list explaining minor modes
fa379636 370 (not (null auto-fill-function)))
6343ed61 371 (point)
de9e2828 372 (list (mark t) mark-active)
6343ed61 373 buffer-read-only
ec4c6f22
RS
374 (cond ((eq major-mode 'Info-mode)
375 (list Info-current-file
376 Info-current-node))
377 ((eq major-mode 'dired-mode)
f4c73d07
RS
378 (cons
379 (expand-file-name dired-directory)
380 (cdr
381 (nreverse
382 (mapcar
383 (function car)
384 dired-subdir-alist))))))
ec4c6f22
RS
385 (let ((locals desktop-locals-to-save)
386 (loclist (buffer-local-variables))
387 (ll))
388 (while locals
389 (let ((here (assq (car locals) loclist)))
390 (if here
391 (setq ll (cons here ll))
392 (if (member (car locals) loclist)
393 (setq ll (cons (car locals) ll)))))
394 (setq locals (cdr locals)))
395 ll)
6343ed61
RS
396 )))
397 (buffer-list))))
398 (buf (get-buffer-create "*desktop*")))
399 (set-buffer buf)
400 (erase-buffer)
fa379636 401
0b9bd504
RS
402 (insert desktop-header
403 ";; Created " (current-time-string) "\n"
fa379636
KH
404 ";; Emacs version " emacs-version "\n\n"
405 ";; Global section:\n")
6343ed61
RS
406 (mapcar (function desktop-outvar) desktop-globals-to-save)
407 (if (memq 'kill-ring desktop-globals-to-save)
0b9bd504
RS
408 (insert "(setq kill-ring-yank-pointer (nthcdr "
409 (int-to-string
6343ed61
RS
410 (- (length kill-ring) (length kill-ring-yank-pointer)))
411 " kill-ring))\n"))
412
0b9bd504 413 (insert "\n;; Buffer section:\n")
de9e2828
RS
414 (mapcar
415 (function (lambda (l)
416 (if (apply 'desktop-save-buffer-p l)
417 (progn
418 (insert desktop-create-buffer-form)
419 (mapcar
420 (function (lambda (e)
421 (insert "\n "
422 (desktop-value-to-string e))))
423 l)
424 (insert ")\n\n")))))
425 info)
6343ed61
RS
426 (setq default-directory dirname)
427 (if (file-exists-p filename) (delete-file filename))
428 (write-region (point-min) (point-max) filename nil 'nomessage)))
429 (setq desktop-dirname dirname))
0b9bd504 430;; ----------------------------------------------------------------------------
6343ed61
RS
431(defun desktop-remove ()
432 "Delete the Desktop file and inactivate the desktop system."
433 (interactive)
434 (if desktop-dirname
435 (let ((filename (concat desktop-dirname desktop-basefilename)))
fa379636
KH
436 (setq desktop-dirname nil)
437 (if (file-exists-p filename)
438 (delete-file filename)))))
0b9bd504 439;; ----------------------------------------------------------------------------
6343ed61
RS
440(defun desktop-read ()
441 "Read the Desktop file and the files it specifies."
442 (interactive)
443 (let ((filename))
444 (if (file-exists-p (concat "./" desktop-basefilename))
445 (setq desktop-dirname (expand-file-name "./"))
446 (if (file-exists-p (concat "~/" desktop-basefilename))
447 (setq desktop-dirname (expand-file-name "~/"))
448 (setq desktop-dirname nil)))
449 (if desktop-dirname
450 (progn
451 (load (concat desktop-dirname desktop-basefilename) t t t)
de9e2828 452 (run-hooks 'desktop-delay-hook)
6343ed61
RS
453 (message "Desktop loaded."))
454 (desktop-clear))))
0b9bd504 455;; ----------------------------------------------------------------------------
6343ed61 456(defun desktop-load-default ()
577ed2b2
RS
457 "Load the `default' start-up library manually.
458Also inhibit further loading of it. Call this from your `.emacs' file
459to provide correct modes for autoloaded files."
0b9bd504 460 (if (not inhibit-default-init) ; safety check
6343ed61
RS
461 (progn
462 (load "default" t t)
463 (setq inhibit-default-init t))))
0b9bd504
RS
464;; ----------------------------------------------------------------------------
465;; Note: the following functions use the dynamic variable binding in Lisp.
0b9bd504 466;;
6343ed61 467(defun desktop-buffer-info () "Load an info file."
ec4c6f22 468 (if (eq 'Info-mode mam)
6343ed61
RS
469 (progn
470 (require 'info)
471 (Info-find-node (nth 0 misc) (nth 1 misc))
472 t)))
0b9bd504 473;; ----------------------------------------------------------------------------
b6105c76
RS
474(defun desktop-buffer-rmail () "Load an RMAIL file."
475 (if (eq 'rmail-mode mam)
e36d00d4 476 (condition-case error
e2247420
RS
477 (progn (rmail-input fn) t)
478 (file-locked
479 (kill-buffer (current-buffer))
480 'ignored))))
0b9bd504 481;; ----------------------------------------------------------------------------
ec4c6f22
RS
482(defun desktop-buffer-mh () "Load a folder in the mh system."
483 (if (eq 'mh-folder-mode mam)
484 (progn
485 (require 'mh-e)
486 (mh-find-path)
487 (mh-visit-folder bn)
488 t)))
489;; ----------------------------------------------------------------------------
6343ed61 490(defun desktop-buffer-dired () "Load a directory using dired."
b6105c76 491 (if (eq 'dired-mode mam)
f4c73d07 492 (if (file-directory-p (file-name-directory (car misc)))
fa379636
KH
493 (progn
494 (dired (car misc))
f4c73d07 495 (mapcar 'dired-insert-subdir (cdr misc))
fa379636
KH
496 t)
497 (message "Directory %s no longer exists." (car misc))
498 (sit-for 1)
499 'ignored)))
0b9bd504 500;; ----------------------------------------------------------------------------
6343ed61
RS
501(defun desktop-buffer-file () "Load a file."
502 (if fn
503 (if (or (file-exists-p fn)
504 (and desktop-missing-file-warning
0b9bd504
RS
505 (y-or-n-p (format
506 "File \"%s\" no longer exists. Re-create? "
6343ed61
RS
507 fn))))
508 (progn (find-file fn) t)
509 'ignored)))
0b9bd504
RS
510;; ----------------------------------------------------------------------------
511;; Create a buffer, load its file, set is mode, ...; called from Desktop file
6343ed61 512;; only.
ec4c6f22 513(defun desktop-create-buffer (ver fn bn mam mim pt mk ro misc &optional locals)
6343ed61
RS
514 (let ((hlist desktop-buffer-handlers)
515 (result)
516 (handler))
517 (while (and (not result) hlist)
518 (setq handler (car hlist))
519 (setq result (funcall handler))
520 (setq hlist (cdr hlist)))
b6105c76 521 (if (eq result t)
6343ed61
RS
522 (progn
523 (if (not (equal (buffer-name) bn))
524 (rename-buffer bn))
ec4c6f22 525 (auto-fill-mode (if (nth 0 mim) 1 0))
6343ed61 526 (goto-char pt)
0b9bd504
RS
527 (if (consp mk)
528 (progn
529 (set-mark (car mk))
530 (setq mark-active (car (cdr mk))))
531 (set-mark mk))
532 ;; Never override file system if the file really is read-only marked.
533 (if ro (setq buffer-read-only ro))
ec4c6f22
RS
534 (while locals
535 (let ((this (car locals)))
536 (if (consp this)
537 ;; an entry of this form `(symbol . value)'
538 (progn
539 (make-local-variable (car this))
540 (set (car this) (cdr this)))
541 ;; an entry of the form `symbol'
542 (make-local-variable this)
543 (makunbound this)))
544 (setq locals (cdr locals)))
6343ed61 545 ))))
ec4c6f22
RS
546
547;; Backward compatibility -- update parameters to 205 standards.
548(defun desktop-buffer (fn bn mam mim pt mk ro tl fc cfs cr misc)
549 (desktop-create-buffer 205 fn bn mam (cdr mim) pt mk ro misc
550 (list (cons 'truncate-lines tl)
551 (cons 'fill-column fc)
552 (cons 'case-fold-search cfs)
553 (cons 'case-replace cr)
554 (cons 'overwrite-mode (car mim)))))
0b9bd504 555;; ----------------------------------------------------------------------------
ab1d55ea 556(provide 'desktop)
6343ed61
RS
557
558;; desktop.el ends here.