1 ;;; desktop.el --- save partial status of Emacs when killed
3 ;; Copyright (C) 1993 Free Software Foundation, Inc.
5 ;; Author: Morten Welinder <terra@diku.dk>
8 ;; This file is part of GNU Emacs.
10 ;; GNU Emacs is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
26 ; Save the Desktop, i.e.,
27 ; - some global variables
28 ; - the list of buffers with associated files. For each buffer also
30 ; - the default directory
39 ; To use this, first put these three lines in the bottom of your .emacs
40 ; file (the later the better):
43 ; (desktop-load-default)
47 ; Start Emacs in the root directory of your "project". The desktop saver
48 ; is inactive by default. You activate it by M-X desktop-save RET. When
49 ; you exit the next time the above data will be saved. This ensures that
50 ; all the files you were editing will be reloaded the next time you start
51 ; Emacs from the same directory and that points will be set where you
54 ; PLEASE NOTE: When the kill ring is saved as specified by the variable
55 ; `desktop-globals-to-save' (by default it isn't). This may result in saving
56 ; things you did not mean to keep. Use M-X desktop-clear RET.
58 ; Thanks to hetrick@phys.uva.nl (Jim Hetrick) for useful ideas.
59 ; ---------------------------------------------------------------------------
62 ; Dec , 1992: Version 1.0 written; never released.
63 ; Jan , 1993: Minor modes now saved: auto-fill-mode, overwrite-mode.
64 ; Apr 26, 1993: Version 1.1 released.
65 ; Apr 29, 1993: Now supports RMAIL, Info, and dired modes.
66 ; Will now search home directory for desktop file.
67 ; desktop-save asks for directory to save in.
68 ; May 31, 1993: Version 1.3
69 ; Now works with Emacs 19.
70 ; Jun 1, 1993: Minor bug fix.
74 ; Save window configuration.
75 ; Recognize more minor modes.
77 ; Start-up with buffer-menu???
81 ; USER OPTIONS -- settings you might want to play with.
82 ; -----------------------------------------------------------------------------
83 (defconst desktop-basefilename
84 (if (equal system-type
'ms-dos
)
85 "emacs.dsk" ; Ms-Dos does not support multiple dots in file name
87 "File for Emacs desktop. A directory name will be prepended to this name.")
89 (defvar desktop-missing-file-warning t
90 "*If non-nil then issue warning if a file no longer exists.
91 Otherwise simply ignore the file.")
93 (defvar desktop-globals-to-save
94 (list 'desktop-missing-file-warning
95 ; 'kill-ring ; Feature: Also saves kill-ring-yank-pointer
96 'desktop-globals-to-save
) ; Itself!
97 "List of global variables to save when killing Emacs.")
99 (defvar desktop-buffers-not-to-save
100 "\\(\\.log\\|(ftp)\\)$"
101 "Regexp identifying buffers that are to be excluded from saving.")
103 (defvar desktop-buffer-handlers
104 '(desktop-buffer-dired
108 "*List of functions to call in order to create a buffer.
109 The functions are called without parameters
110 but may access the the major mode as `mam',
111 the file name as `fn', the buffer name as `bn', the default directory as
112 `dd'. If some function returns non-nil no further functions are called.
113 If the function returns t then the buffer is considered created.")
114 ; ---------------------------------------------------------------------------
115 (defvar desktop-dirname nil
116 "The directory in which the current desktop file resides.")
118 (defconst desktop-header
119 "; ---------------------------------------------------------------------------
120 ; Desktop File for Emacs
121 ; ---------------------------------------------------------------------------
122 " "*Header to place in Desktop file.")
123 ; ---------------------------------------------------------------------------
125 (string-lessp "19" emacs-version
)
126 "t is Emacs version 19 or later.")
128 (defun desktop-clear () "Empty the Desktop."
131 (setq kill-ring-yank-pointer nil
)
132 (mapcar (function kill-buffer
) (buffer-list)))
133 ; ---------------------------------------------------------------------------
134 (if (not (boundp 'desktop-kill
))
136 (add-hook 'kill-emacs-hook
'desktop-kill
)
137 (setq old-kill-emacs kill-emacs-hook
)
138 (setq kill-emacs-hook
139 (function (lambda () (progn (desktop-kill)
140 (run-hooks old-kill-emacs
)))))))
141 ; ---------------------------------------------------------------------------
142 (defun desktop-kill ()
145 (desktop-save desktop-dirname
))))
147 ;(defun kill-emacs (&optional query)
148 ; "End this Emacs session.
149 ;Prefix ARG or optional first ARG non-nil means exit with no questions asked,
150 ;even if there are unsaved buffers. If Emacs is running non-interactively
151 ;and ARG is an integer, then Emacs exits with ARG as its exit code.
153 ;If the variable `desktop-dirname' is non-nil,
154 ;the function desktop-save will be called first."
156 ; (if desktop-dirname (desktop-save desktop-dirname))
157 ; (original-kill-emacs query))
158 ; ---------------------------------------------------------------------------
159 (defun desktop-outvar (VAR)
160 "Output a setq statement for VAR to the desktop file."
164 (prin1 VAR
(current-buffer))
166 (prin1 (symbol-value VAR
) (current-buffer))
168 ; ---------------------------------------------------------------------------
169 (defun desktop-save-buffer-p (filename bufname mode
)
170 "Return t if should record a particular buffer for next startup.
171 FILENAME is the visited file name, BUFNAME is the buffer name, and
172 MODE is the major mode."
175 (not (string-match desktop-buffers-not-to-save bufname
)))
177 (memq mode
'(Info-mode dired-mode rmail-mode
)))))
178 ; ---------------------------------------------------------------------------
179 (defun desktop-save (dirname)
180 "Save the Desktop file. Parameter DIRNAME specifies where to save desktop."
181 (interactive "DDirectory to save desktop file in: ")
183 (let ((filename (expand-file-name
184 (concat dirname desktop-basefilename
)))
187 (function (lambda (b)
192 (list 'quote major-mode
)
210 (cond ((equal major-mode
'Info-mode
)
211 (list Info-current-file
213 ((equal major-mode
'dired-mode
)
214 (list default-directory
))
218 (buf (get-buffer-create "*desktop*")))
222 (insert desktop-header
223 "; Created " (current-time-string) "\n"
224 "; Emacs version " emacs-version
"\n\n"
225 "; Global section:\n")
226 (mapcar (function desktop-outvar
) desktop-globals-to-save
)
227 (if (memq 'kill-ring desktop-globals-to-save
)
228 (insert "(setq kill-ring-yank-pointer (nthcdr "
230 (- (length kill-ring
) (length kill-ring-yank-pointer
)))
233 (insert "\n; Buffer section:\n")
235 (function (lambda (l)
236 (if (desktop-save-buffer-p
241 (insert "(desktop-buffer")
243 (function (lambda (e)
245 (prin1 e
(current-buffer))))
249 (setq default-directory dirname
)
250 (if (file-exists-p filename
) (delete-file filename
))
251 (write-region (point-min) (point-max) filename nil
'nomessage
)))
252 (setq desktop-dirname dirname
))
253 ; ---------------------------------------------------------------------------
254 (defun desktop-remove ()
255 "Delete the Desktop file and inactivate the desktop system."
258 (let ((filename (concat desktop-dirname desktop-basefilename
)))
259 (if (file-exists-p filename
) (delete-file filename
))
260 (setq desktop-dirname nil
))))
261 ; ---------------------------------------------------------------------------
262 (defun desktop-read ()
263 "Read the Desktop file and the files it specifies."
266 (if (file-exists-p (concat "./" desktop-basefilename
))
267 (setq desktop-dirname
(expand-file-name "./"))
268 (if (file-exists-p (concat "~/" desktop-basefilename
))
269 (setq desktop-dirname
(expand-file-name "~/"))
270 (setq desktop-dirname nil
)))
273 (load (concat desktop-dirname desktop-basefilename
) t t t
)
274 (message "Desktop loaded."))
276 ; ---------------------------------------------------------------------------
277 (defun desktop-load-default ()
278 "Load the `default' start-up library manually.
279 Also inhibit further loading of it.
280 Call this from your `.emacs' file
281 provide correct modes for autoloaded files."
282 (if (not inhibit-default-init
)
285 (setq inhibit-default-init t
))))
286 ; ---------------------------------------------------------------------------
287 (defun desktop-buffer-info () "Load an info file."
288 (if (equal 'Info-mode mam
)
291 (Info-find-node (nth 0 misc
) (nth 1 misc
))
293 ; ---------------------------------------------------------------------------
294 (defun desktop-buffer-rmail () "Load a RMAIL file."
295 (if (equal 'rmail-mode mam
)
296 (progn (rmail-input fn
) t
)))
297 ; ---------------------------------------------------------------------------
298 (defun desktop-buffer-dired () "Load a directory using dired."
299 (if (equal 'dired-mode mam
)
300 (progn (dired (nth 0 misc
)) t
)))
301 ; ---------------------------------------------------------------------------
302 (defun desktop-buffer-file () "Load a file."
304 (if (or (file-exists-p fn
)
305 (and desktop-missing-file-warning
307 "File \"%s\" no longer exists. Re-create? "
309 (progn (find-file fn
) t
)
311 ; ---------------------------------------------------------------------------
312 ;;Create a buffer, load its file, set is mode, ...; called from Desktop file
314 (defun desktop-buffer (fn bn mam mim pt mk ro tl fc cfs cr misc
)
315 (let ((hlist desktop-buffer-handlers
)
318 (while (and (not result
) hlist
)
319 (setq handler
(car hlist
))
320 (setq result
(funcall handler
))
321 (setq hlist
(cdr hlist
)))
324 (if (not (equal (buffer-name) bn
))
334 (setq buffer-read-only ro
)
335 (setq truncate-lines tl
)
336 (setq fill-column fc
)
337 (setq case-fold-search cfs
)
338 (setq case-replace cr
)
340 ; ---------------------------------------------------------------------------
344 ;; desktop.el ends here.