; Fix wrong/duplicate ChangeLog entries
[emacs.git] / lisp / desktop.el
Commit [+]AuthorDateLineData
a912c016 Juanma Barranquero2013-08-08 00:54:08 +02001;;; desktop.el --- save partial status of Emacs when killed -*- lexical-binding: t -*-
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +00002
7e09ef09
PE
Paul Eggert2015-01-01 14:26:41 -08003;; Copyright (C) 1993-1995, 1997, 2000-2015 Free Software Foundation,
4;; Inc.
6343ed61
RS
Richard M. Stallman1993-06-01 20:09:25 +00005
6;; Author: Morten Welinder <terra@diku.dk>
3ea96cac Dave Love2000-02-02 14:05:36 +00007;; Keywords: convenience
c5e87d10 Paul Eggert2011-11-17 09:40:48 -08008;; Favorite-brand-of-beer: None, I hate beer.
6343ed61
RS
Richard M. Stallman1993-06-01 20:09:25 +00009
10;; This file is part of GNU Emacs.
11
eb3fa2cf Glenn Morris2008-05-06 08:06:51 +000012;; GNU Emacs is free software: you can redistribute it and/or modify
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +000013;; it under the terms of the GNU General Public License as published by
eb3fa2cf
GM
Glenn Morris2008-05-06 08:06:51 +000014;; the Free Software Foundation, either version 3 of the License, or
15;; (at your option) any later version.
6343ed61
RS
Richard M. Stallman1993-06-01 20:09:25 +000016
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
eb3fa2cf Glenn Morris2008-05-06 08:06:51 +000023;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
6343ed61
RS
Richard M. Stallman1993-06-01 20:09:25 +000024
25;;; Commentary:
26
0b9bd504
RS
Richard M. Stallman1993-10-07 16:50:26 +000027;; Save the Desktop, i.e.,
28;; - some global variables
29;; - the list of buffers with associated files. For each buffer also
30;; - the major mode
31;; - the default directory
32;; - the point
33;; - the mark & mark-active
34;; - buffer-read-only
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +000035;; - some local variables
b958c0ad Juanma Barranquero2013-07-15 02:07:51 +020036;; - frame and window configuration
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +000037
6b61353c Kenichi Handa2004-04-16 12:51:06 +000038;; To use this, use customize to turn on desktop-save-mode or add the
865fe16f Chong Yidong2012-09-17 13:41:04 +080039;; following line somewhere in your init file:
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +000040;;
6b61353c Kenichi Handa2004-04-16 12:51:06 +000041;; (desktop-save-mode 1)
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +000042;;
6b61353c Kenichi Handa2004-04-16 12:51:06 +000043;; For further usage information, look at the section
20535d5b Glenn Morris2009-03-22 20:09:34 +000044;; (info "(emacs)Saving Emacs Sessions") in the GNU Emacs Manual.
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +000045
46;; When the desktop module is loaded, the function `desktop-kill' is
341c2f07 Stefan Monnier2007-04-11 02:28:26 +000047;; added to the `kill-emacs-hook'. This function is responsible for
6b61353c Kenichi Handa2004-04-16 12:51:06 +000048;; saving the desktop when Emacs is killed. Furthermore an anonymous
341c2f07 Stefan Monnier2007-04-11 02:28:26 +000049;; function is added to the `after-init-hook'. This function is
6b61353c Kenichi Handa2004-04-16 12:51:06 +000050;; responsible for loading the desktop when Emacs is started.
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +000051
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +000052;; Special handling.
53;; -----------------
54;; Variables `desktop-buffer-mode-handlers' and `desktop-minor-mode-handlers'
55;; are supplied to handle special major and minor modes respectively.
56;; `desktop-buffer-mode-handlers' is an alist of major mode specific functions
341c2f07 Stefan Monnier2007-04-11 02:28:26 +000057;; to restore a desktop buffer. Elements must have the form
be617bbf Juanma Barranquero2006-02-10 11:07:50 +000058;;
0f4804e7 Lars Hansen2005-08-10 19:38:52 +000059;; (MAJOR-MODE . RESTORE-BUFFER-FUNCTION).
be617bbf Juanma Barranquero2006-02-10 11:07:50 +000060;;
0f4804e7 Lars Hansen2005-08-10 19:38:52 +000061;; Functions listed are called by `desktop-create-buffer' when `desktop-read'
341c2f07 Stefan Monnier2007-04-11 02:28:26 +000062;; evaluates the desktop file. Buffers with a major mode not specified here,
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +000063;; are restored by the default handler `desktop-restore-file-buffer'.
64;; `desktop-minor-mode-handlers' is an alist of functions to restore
65;; non-standard minor modes. Elements must have the form
be617bbf Juanma Barranquero2006-02-10 11:07:50 +000066;;
0f4804e7 Lars Hansen2005-08-10 19:38:52 +000067;; (MINOR-MODE . RESTORE-FUNCTION).
be617bbf Juanma Barranquero2006-02-10 11:07:50 +000068;;
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +000069;; Functions are called by `desktop-create-buffer' to restore minor modes.
70;; Minor modes not specified here, are restored by the standard minor mode
71;; function. If you write a module that defines a major or minor mode that
72;; needs a special handler, then place code like
73
74;; (defun foo-restore-desktop-buffer
75;; ...
76;; (add-to-list 'desktop-buffer-mode-handlers
77;; '(foo-mode . foo-restore-desktop-buffer))
78
79;; or
80
81;; (defun bar-desktop-restore
82;; ...
83;; (add-to-list 'desktop-minor-mode-handlers
84;; '(bar-mode . bar-desktop-restore))
85
db87b14e
GM
Glenn Morris2015-05-25 23:27:55 -070086;; in the module itself. The mode function must either be autoloaded,
87;; or of the form "foobar-mode" and defined in library "foobar", so that
88;; desktop can guess how to load its definition.
89;; See the docstrings of `desktop-buffer-mode-handlers' and
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +000090;; `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
341c2f07 Stefan Monnier2007-04-11 02:28:26 +0000104;; functions before writing `desktop-minor-modes'. If a minor mode has a
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000105;; 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;; ---------------------------------------------------------------------------
47640244 Gerd Moellmann2000-04-26 17:33:02 +0000114
ec4c6f22
RS
Richard M. Stallman1994-01-06 11:34:51 +0000115;; 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
117;; for buffers is an example of misuse.
118
0b9bd504
RS
Richard M. Stallman1993-10-07 16:50:26 +0000119;; PLEASE NOTE: The kill ring can be saved as specified by the variable
120;; `desktop-globals-to-save' (by default it isn't). This may result in saving
121;; things you did not mean to keep. Use M-x desktop-clear RET.
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +0000122
fa379636
KH
Karl Heuer1994-05-01 02:07:27 +0000123;; Thanks to hetrick@phys.uva.nl (Jim Hetrick) for useful ideas.
124;; avk@rtsg.mot.com (Andrew V. Klein) for a dired tip.
125;; chris@tecc.co.uk (Chris Boucher) for a mark tip.
126;; f89-kam@nada.kth.se (Klas Mellbourn) for a mh-e tip.
127;; kifer@sbkifer.cs.sunysb.edu (M. Kifer) for a bug hunt.
f4c73d07 Richard M. Stallman1995-04-06 20:05:39 +0000128;; treese@lcs.mit.edu (Win Treese) for ange-ftp tips.
8c106d17 Glenn Morris2013-10-12 17:31:19 -0700129;; pot@cnuce.cnr.it (Francesco Potortì) for misc. tips.
0b9bd504
RS
Richard M. Stallman1993-10-07 16:50:26 +0000130;; ---------------------------------------------------------------------------
131;; TODO:
132;;
0b9bd504
RS
Richard M. Stallman1993-10-07 16:50:26 +0000133;; Recognize more minor modes.
134;; Save mark rings.
6343ed61
RS
Richard M. Stallman1993-06-01 20:09:25 +0000135
136;;; Code:
137
a1c80d9d Juanma Barranquero2013-07-22 03:25:47 +0200138(require 'cl-lib)
9421876d Juanma Barranquero2013-08-02 06:33:58 +0200139(require 'frameset)
a1c80d9d Juanma Barranquero2013-07-22 03:25:47 +0200140
c96983ef Kelly Dean2015-02-09 13:25:53 +0000141(defvar desktop-file-version "208"
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000142 "Version number of desktop file format.
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000143Written into the desktop file and used at desktop read to provide
144backward compatibility.")
145
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +0000146;; ----------------------------------------------------------------------------
0b9bd504
RS
Richard M. Stallman1993-10-07 16:50:26 +0000147;; USER OPTIONS -- settings you might want to play with.
148;; ----------------------------------------------------------------------------
bbf5eb28
RS
Richard M. Stallman1997-04-12 03:18:33 +0000149
150(defgroup desktop nil
151 "Save status of Emacs when you exit."
152 :group 'frames)
153
e5bd0a28
SM
Stefan Monnier2012-05-12 23:05:06 -0400154;; Maintained for backward compatibility
155(define-obsolete-variable-alias 'desktop-enable 'desktop-save-mode "22.1")
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +0000156;;;###autoload
157(define-minor-mode desktop-save-mode
06e21633 Chong Yidong2011-10-19 08:54:24 -0400158 "Toggle desktop saving (Desktop Save mode).
c863b6ad
GM
Glenn Morris2014-02-17 17:33:30 -0800159With a prefix argument ARG, enable Desktop Save mode if ARG is positive,
160and disable it otherwise. If called from Lisp, enable the mode if ARG
161is omitted or nil.
06e21633 Chong Yidong2011-10-19 08:54:24 -0400162
c863b6ad
GM
Glenn Morris2014-02-17 17:33:30 -0800163When Desktop Save mode is enabled, the state of Emacs is saved from
164one session to another. In particular, Emacs will save the desktop when
165it exits (this may prompt you; see the option `desktop-save'). The next
166time Emacs starts, if this mode is active it will restore the desktop.
167
168To manually save the desktop at any time, use the command `M-x desktop-save'.
169To load it, use `M-x desktop-read'.
170
171Once a desktop file exists, Emacs will auto-save it according to the
172option `desktop-auto-save-timeout'.
173
174To see all the options you can set, browse the `desktop' customization group.
175
176For further details, see info node `(emacs)Saving Emacs Sessions'."
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000177 :global t
2b777cd9
JL
Juri Linkov2014-02-07 09:44:29 +0200178 :group 'desktop
179 (if desktop-save-mode
a4d8b73e
JL
Juri Linkov2014-06-25 02:23:41 +0300180 (desktop-auto-save-enable)
181 (desktop-auto-save-disable)))
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000182
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000183(defun desktop-save-mode-off ()
184 "Disable `desktop-save-mode'. Provided for use in hooks."
185 (desktop-save-mode 0))
186
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000187(defcustom desktop-save 'ask-if-new
9201cc28 Lute Kamstra2008-12-03 05:48:14 +0000188 "Specifies whether the desktop should be saved when it is killed.
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +0000189A desktop is killed when the user changes desktop or quits Emacs.
190Possible values are:
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000191 t -- always save.
192 ask -- always ask.
193 ask-if-new -- ask if no desktop file exists, otherwise just save.
194 ask-if-exists -- ask if desktop file exists, otherwise don't save.
195 if-exists -- save if desktop file exists, otherwise don't save.
196 nil -- never save.
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000197The desktop is never saved when `desktop-save-mode' is nil.
cc8b76bf Juanma Barranquero2005-07-19 09:54:05 +0000198The variables `desktop-dirname' and `desktop-base-file-name'
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000199determine where the desktop is saved."
11425834
LH
Lars Hansen2006-06-23 21:42:33 +0000200 :type
201 '(choice
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000202 (const :tag "Always save" t)
203 (const :tag "Always ask" ask)
204 (const :tag "Ask if desktop file is new, else do save" ask-if-new)
205 (const :tag "Ask if desktop file exists, else don't save" ask-if-exists)
206 (const :tag "Save if desktop file exists, else don't" if-exists)
207 (const :tag "Never save" nil))
af61551b Lars Hansen2004-11-11 19:02:56 +0000208 :group 'desktop
bf247b6e Kim F. Storm2005-02-09 15:50:47 +0000209 :version "22.1")
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000210
6c8e0ae6
JL
Juri Linkov2013-12-16 23:48:51 +0200211(defcustom desktop-auto-save-timeout auto-save-timeout
212 "Number of seconds idle time before auto-save of the desktop.
7f118009 Juri Linkov2014-06-07 02:38:40 +0300213The idle timer activates auto-saving only when window configuration changes.
c863b6ad Glenn Morris2014-02-17 17:33:30 -0800214This applies to an existing desktop file when `desktop-save-mode' is enabled.
6c8e0ae6 Juri Linkov2013-12-16 23:48:51 +0200215Zero or nil means disable auto-saving due to idleness."
5db9dace
JL
Juri Linkov2013-04-27 23:55:00 +0300216 :type '(choice (const :tag "Off" nil)
217 (integer :tag "Seconds"))
218 :set (lambda (symbol value)
219 (set-default symbol value)
7f118009
JL
Juri Linkov2014-06-07 02:38:40 +0300220 (ignore-errors
221 (if (and (integerp value) (> value 0))
a4d8b73e
JL
Juri Linkov2014-06-25 02:23:41 +0300222 (desktop-auto-save-enable value)
223 (desktop-auto-save-disable))))
5db9dace
JL
Juri Linkov2013-04-27 23:55:00 +0300224 :group 'desktop
225 :version "24.4")
226
1f7efe1b
JB
Juanma Barranquero2007-06-12 11:14:52 +0000227(defcustom desktop-load-locked-desktop 'ask
228 "Specifies whether the desktop should be loaded if locked.
229Possible values are:
230 t -- load anyway.
231 nil -- don't load.
232 ask -- ask the user.
233If the value is nil, or `ask' and the user chooses not to load the desktop,
234the normal hook `desktop-not-loaded-hook' is run."
235 :type
236 '(choice
237 (const :tag "Load anyway" t)
238 (const :tag "Don't load" nil)
239 (const :tag "Ask the user" ask))
240 :group 'desktop
8f3f313d Juanma Barranquero2007-10-27 17:14:37 +0000241 :version "22.2")
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000242
cd6ef82d
GM
Glenn Morris2008-04-12 03:17:19 +0000243(define-obsolete-variable-alias 'desktop-basefilename
244 'desktop-base-file-name "22.1")
245
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000246(defcustom desktop-base-file-name
fc715501 Richard M. Stallman1996-09-01 19:04:28 +0000247 (convert-standard-filename ".emacs.desktop")
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000248 "Name of file for Emacs desktop, excluding the directory part."
813dbb2d
RS
Richard M. Stallman1997-12-29 20:58:19 +0000249 :type 'file
250 :group 'desktop)
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +0000251
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000252(defcustom desktop-base-lock-name
253 (convert-standard-filename ".emacs.desktop.lock")
254 "Name of lock file for Emacs desktop, excluding the directory part."
255 :type 'file
256 :group 'desktop
8f3f313d Juanma Barranquero2007-10-27 17:14:37 +0000257 :version "22.2")
e88110db Juanma Barranquero2007-06-12 09:11:31 +0000258
e76f0800 Chong Yidong2012-06-21 15:15:42 +0800259(defcustom desktop-path (list user-emacs-directory "~")
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000260 "List of directories to search for the desktop file.
261The base name of the file is specified in `desktop-base-file-name'."
262 :type '(repeat directory)
af61551b Lars Hansen2004-11-11 19:02:56 +0000263 :group 'desktop
a3b337cd Glenn Morris2010-09-01 22:38:30 -0700264 :version "23.2") ; user-emacs-directory added
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000265
bbf5eb28 Richard M. Stallman1997-04-12 03:18:33 +0000266(defcustom desktop-missing-file-warning nil
6c27fdb9 Lars Hansen2006-05-14 20:26:37 +0000267 "If non-nil, offer to recreate the buffer of a deleted file.
ebb39555
LH
Lars Hansen2004-04-26 18:58:19 +0000268Also pause for a moment to display message about errors signaled in
269`desktop-buffer-mode-handlers'.
270
271If nil, just print error messages in the message buffer."
bbf5eb28 Richard M. Stallman1997-04-12 03:18:33 +0000272 :type 'boolean
af61551b Lars Hansen2004-11-11 19:02:56 +0000273 :group 'desktop
bf247b6e Kim F. Storm2005-02-09 15:50:47 +0000274 :version "22.1")
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +0000275
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000276(defcustom desktop-no-desktop-file-hook nil
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000277 "Normal hook run when `desktop-read' can't find a desktop file.
11425834 Lars Hansen2006-06-23 21:42:33 +0000278Run in the directory in which the desktop file was sought.
8649a87b Lute Kamstra2005-04-03 14:01:43 +0000279May be used to show a dired buffer."
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000280 :type 'hook
af61551b Lars Hansen2004-11-11 19:02:56 +0000281 :group 'desktop
bf247b6e Kim F. Storm2005-02-09 15:50:47 +0000282 :version "22.1")
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000283
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000284(defcustom desktop-not-loaded-hook nil
285 "Normal hook run when the user declines to re-use a desktop file.
286Run in the directory in which the desktop file was found.
287May be used to deal with accidental multiple Emacs jobs."
288 :type 'hook
289 :group 'desktop
290 :options '(desktop-save-mode-off save-buffers-kill-emacs)
8f3f313d Juanma Barranquero2007-10-27 17:14:37 +0000291 :version "22.2")
e88110db Juanma Barranquero2007-06-12 09:11:31 +0000292
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000293(defcustom desktop-after-read-hook nil
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000294 "Normal hook run after a successful `desktop-read'.
8649a87b Lute Kamstra2005-04-03 14:01:43 +0000295May be used to show a buffer list."
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000296 :type 'hook
af61551b Lars Hansen2004-11-11 19:02:56 +0000297 :group 'desktop
11425834 Lars Hansen2006-06-23 21:42:33 +0000298 :options '(list-buffers)
bf247b6e Kim F. Storm2005-02-09 15:50:47 +0000299 :version "22.1")
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000300
301(defcustom desktop-save-hook nil
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000302 "Normal hook run before the desktop is saved in a desktop file.
11425834
LH
Lars Hansen2006-06-23 21:42:33 +0000303Run with the desktop buffer current with only the header present.
304May be used to add to the desktop code or to truncate history lists,
305for example."
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000306 :type 'hook
307 :group 'desktop)
308
340db502
LH
Lars Hansen2004-09-09 19:45:03 +0000309(defcustom desktop-globals-to-save
310 '(desktop-missing-file-warning
311 tags-file-name
312 tags-table-list
313 search-ring
314 regexp-search-ring
c760f19e
CY
Chong Yidong2009-07-05 05:14:27 +0000315 register-alist
316 file-name-history)
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +0000317 "List of global variables saved by `desktop-save'.
318An element may be variable name (a symbol) or a cons cell of the form
319\(VAR . MAX-SIZE), which means to truncate VAR's value to at most
320MAX-SIZE elements (if the value is a list) before saving the value.
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000321Feature: Saving `kill-ring' implies saving `kill-ring-yank-pointer'."
322 :type '(repeat (restricted-sexp :match-alternatives (symbolp consp)))
323 :group 'desktop)
324
340db502
LH
Lars Hansen2004-09-09 19:45:03 +0000325(defcustom desktop-globals-to-clear
326 '(kill-ring
327 kill-ring-yank-pointer
328 search-ring
329 search-ring-yank-pointer
330 regexp-search-ring
331 regexp-search-ring-yank-pointer)
150f39ee Lars Hansen2005-01-07 20:18:59 +0000332 "List of global variables that `desktop-clear' will clear.
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000333An element may be variable name (a symbol) or a cons cell of the form
cc8b76bf
JB
Juanma Barranquero2005-07-19 09:54:05 +0000334\(VAR . FORM). Symbols are set to nil and for cons cells VAR is set
335to the value obtained by evaluating FORM."
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000336 :type '(repeat (restricted-sexp :match-alternatives (symbolp consp)))
af61551b Lars Hansen2004-11-11 19:02:56 +0000337 :group 'desktop
bf247b6e Kim F. Storm2005-02-09 15:50:47 +0000338 :version "22.1")
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000339
0f4804e7 Lars Hansen2005-08-10 19:38:52 +0000340(defcustom desktop-clear-preserve-buffers
3845c322
GM
Glenn Morris2010-06-02 23:07:39 -0700341 '("\\*scratch\\*" "\\*Messages\\*" "\\*server\\*" "\\*tramp/.+\\*"
342 "\\*Warnings\\*")
9201cc28 Lute Kamstra2008-12-03 05:48:14 +0000343 "List of buffers that `desktop-clear' should not delete.
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000344Each element is a regular expression. Buffers with a name matched by any of
345these won't be deleted."
3845c322 Glenn Morris2010-06-02 23:07:39 -0700346 :version "23.3" ; added Warnings - bug#6336
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000347 :type '(repeat string)
348 :group 'desktop)
340db502 Lars Hansen2004-09-09 19:45:03 +0000349
0f4804e7 Lars Hansen2005-08-10 19:38:52 +0000350;;;###autoload
340db502
LH
Lars Hansen2004-09-09 19:45:03 +0000351(defcustom desktop-locals-to-save
352 '(desktop-locals-to-save ; Itself! Think it over.
353 truncate-lines
354 case-fold-search
355 case-replace
356 fill-column
357 overwrite-mode
358 change-log-default-name
359 line-number-mode
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000360 column-number-mode
361 size-indication-mode
362 buffer-file-coding-system
363 indent-tabs-mode
11425834 Lars Hansen2006-06-23 21:42:33 +0000364 tab-width
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000365 indicate-buffer-boundaries
366 indicate-empty-lines
367 show-trailing-whitespace)
577ed2b2 Richard M. Stallman1995-01-30 06:14:33 +0000368 "List of local variables to save for each buffer.
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000369The variables are saved only when they really are local. Conventional minor
370modes are restored automatically; they should not be listed here."
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +0000371 :type '(repeat symbol)
372 :group 'desktop)
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +0000373
7d7a68d8 Juri Linkov2014-02-07 09:51:56 +0200374(defcustom desktop-buffers-not-to-save "\\` "
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000375 "Regexp identifying buffers that are to be excluded from saving."
a6c2c80c
EZ
Eli Zaretskii2009-07-18 11:59:04 +0000376 :type '(choice (const :tag "None" nil)
377 regexp)
7d7a68d8 Juri Linkov2014-02-07 09:51:56 +0200378 :version "24.4" ; skip invisible temporary buffers
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000379 :group 'desktop)
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +0000380
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000381;; Skip tramp and ange-ftp files
bbf5eb28 Richard M. Stallman1997-04-12 03:18:33 +0000382(defcustom desktop-files-not-to-save
a6c2c80c Eli Zaretskii2009-07-18 11:59:04 +0000383 "\\(^/[^/:]*:\\|(ftp)$\\)"
bbf5eb28 Richard M. Stallman1997-04-12 03:18:33 +0000384 "Regexp identifying files whose buffers are to be excluded from saving."
a6c2c80c
EZ
Eli Zaretskii2009-07-18 11:59:04 +0000385 :type '(choice (const :tag "None" nil)
386 regexp)
bbf5eb28 Richard M. Stallman1997-04-12 03:18:33 +0000387 :group 'desktop)
fa379636 Karl Heuer1994-05-01 02:07:27 +0000388
df410295
JL
Juri Linkov2005-10-21 08:48:53 +0000389;; We skip TAGS files to save time (tags-file-name is saved instead).
390(defcustom desktop-modes-not-to-save
391 '(tags-table-mode)
80f9f3db
SM
Stefan Monnier2000-10-10 16:42:37 +0000392 "List of major modes whose buffers should not be saved."
393 :type '(repeat symbol)
394 :group 'desktop)
395
b958c0ad Juanma Barranquero2013-07-15 02:07:51 +0200396(defcustom desktop-restore-frames t
46456005
GM
Glenn Morris2014-03-12 00:14:30 -0700397 "When non-nil, save and restore the frame and window configuration.
398See related options `desktop-restore-reuses-frames',
399`desktop-restore-in-current-display', and `desktop-restore-forces-onscreen'."
39c0e36f
JB
Juanma Barranquero2013-06-27 11:08:14 +0200400 :type 'boolean
401 :group 'desktop
402 :version "24.4")
403
2addf922 Juanma Barranquero2013-07-01 05:29:46 +0200404(defcustom desktop-restore-in-current-display nil
46456005
GM
Glenn Morris2014-03-12 00:14:30 -0700405 "Controls how restoring of frames treats displays.
406If t, restores frames into the current display.
407If nil, restores frames into their original displays (if possible).
408If `delete', deletes frames on other displays instead of restoring them."
b958c0ad
JB
Juanma Barranquero2013-07-15 02:07:51 +0200409 :type '(choice (const :tag "Restore in current display" t)
410 (const :tag "Restore in original display" nil)
9c61f806 Glenn Morris2013-12-27 17:24:15 -0800411 (const :tag "Delete frames in other displays" delete))
b958c0ad
JB
Juanma Barranquero2013-07-15 02:07:51 +0200412 :group 'desktop
413 :version "24.4")
414
ddeffb17 Juanma Barranquero2013-07-28 05:03:45 +0200415(defcustom desktop-restore-forces-onscreen t
46456005
GM
Glenn Morris2014-03-12 00:14:30 -0700416 "If t, restores frames that are fully offscreen onscreen instead.
417If `all', also restores frames that are partially offscreen onscreen.
418
419Note that checking of frame boundaries is only approximate.
420It can fail to reliably detect frames whose onscreen/offscreen state
421depends on a few pixels, especially near the right / bottom borders
422of the screen."
ddeffb17 Juanma Barranquero2013-07-28 05:03:45 +0200423 :type '(choice (const :tag "Only fully offscreen frames" t)
4538c058 Juanma Barranquero2014-03-11 01:46:07 +0100424 (const :tag "Also partially offscreen frames" all)
ddeffb17
JB
Juanma Barranquero2013-07-28 05:03:45 +0200425 (const :tag "Do not force frames onscreen" nil))
426 :group 'desktop
427 :version "24.4")
428
9421876d Juanma Barranquero2013-08-02 06:33:58 +0200429(defcustom desktop-restore-reuses-frames t
b958c0ad Juanma Barranquero2013-07-15 02:07:51 +0200430 "If t, restoring frames reuses existing frames.
46456005
GM
Glenn Morris2014-03-12 00:14:30 -0700431If nil, deletes existing frames.
432If `keep', keeps existing frames and does not reuse them."
b958c0ad
JB
Juanma Barranquero2013-07-15 02:07:51 +0200433 :type '(choice (const :tag "Reuse existing frames" t)
434 (const :tag "Delete existing frames" nil)
d5671a82 Juanma Barranquero2013-08-05 00:12:18 +0200435 (const :tag "Keep existing frames" :keep))
2addf922
JB
Juanma Barranquero2013-07-01 05:29:46 +0200436 :group 'desktop
437 :version "24.4")
438
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000439(defcustom desktop-file-name-format 'absolute
9201cc28 Lute Kamstra2008-12-03 05:48:14 +0000440 "Format in which desktop file names should be saved.
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000441Possible values are:
442 absolute -- Absolute file name.
443 tilde -- Relative to ~.
444 local -- Relative to directory of desktop file."
445 :type '(choice (const absolute) (const tilde) (const local))
af61551b Lars Hansen2004-11-11 19:02:56 +0000446 :group 'desktop
bf247b6e Kim F. Storm2005-02-09 15:50:47 +0000447 :version "22.1")
569c754e Richard M. Stallman1996-03-05 16:37:03 +0000448
150f39ee
LH
Lars Hansen2005-01-07 20:18:59 +0000449(defcustom desktop-restore-eager t
450 "Number of buffers to restore immediately.
451Remaining buffers are restored lazily (when Emacs is idle).
452If value is t, all buffers are restored immediately."
0ba9bc53 David Kastrup2005-01-09 13:31:53 +0000453 :type '(choice (const t) integer)
150f39ee Lars Hansen2005-01-07 20:18:59 +0000454 :group 'desktop
bf247b6e Kim F. Storm2005-02-09 15:50:47 +0000455 :version "22.1")
150f39ee
LH
Lars Hansen2005-01-07 20:18:59 +0000456
457(defcustom desktop-lazy-verbose t
458 "Verbose reporting of lazily created buffers."
459 :type 'boolean
460 :group 'desktop
bf247b6e Kim F. Storm2005-02-09 15:50:47 +0000461 :version "22.1")
150f39ee
LH
Lars Hansen2005-01-07 20:18:59 +0000462
463(defcustom desktop-lazy-idle-delay 5
464 "Idle delay before starting to create buffers.
465See `desktop-restore-eager'."
466 :type 'integer
467 :group 'desktop
bf247b6e Kim F. Storm2005-02-09 15:50:47 +0000468 :version "22.1")
150f39ee Lars Hansen2005-01-07 20:18:59 +0000469
e5780ae1 Lars Hansen2004-04-21 20:53:35 +0000470;;;###autoload
acfcc8c5 Juanma Barranquero2013-07-12 13:21:01 +0200471(defvar-local desktop-save-buffer nil
ebb39555 Lars Hansen2004-04-26 18:58:19 +0000472 "When non-nil, save buffer status in desktop file.
ebb39555 Lars Hansen2004-04-26 18:58:19 +0000473
b89c5a72
JB
Juanma Barranquero2005-07-29 10:25:15 +0000474If the value is a function, it is called by `desktop-save' with argument
475DESKTOP-DIRNAME to obtain auxiliary information to save in the desktop
ebb39555 Lars Hansen2004-04-26 18:58:19 +0000476file along with the state of the buffer for which it was called.
b6b70cda John Wiegley2000-10-13 09:11:16 +0000477
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000478When file names are returned, they should be formatted using the call
e5780ae1 Lars Hansen2004-04-21 20:53:35 +0000479\"(desktop-file-name FILE-NAME DESKTOP-DIRNAME)\".
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000480
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000481Later, when `desktop-read' evaluates the desktop file, auxiliary information
482is passed as the argument DESKTOP-BUFFER-MISC to functions in
483`desktop-buffer-mode-handlers'.")
ebb39555 Lars Hansen2004-04-26 18:58:19 +0000484(make-obsolete-variable 'desktop-buffer-modes-to-save
cc8b76bf Juanma Barranquero2005-07-19 09:54:05 +0000485 'desktop-save-buffer "22.1")
e5780ae1 Lars Hansen2004-04-21 20:53:35 +0000486(make-obsolete-variable 'desktop-buffer-misc-functions
cc8b76bf Juanma Barranquero2005-07-19 09:54:05 +0000487 'desktop-save-buffer "22.1")
b6b70cda John Wiegley2000-10-13 09:11:16 +0000488
0f4804e7 Lars Hansen2005-08-10 19:38:52 +0000489;;;###autoload
e76f0800 Chong Yidong2012-06-21 15:15:42 +0800490(defvar desktop-buffer-mode-handlers nil
e5780ae1 Lars Hansen2004-04-21 20:53:35 +0000491 "Alist of major mode specific functions to restore a desktop buffer.
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000492Functions listed are called by `desktop-create-buffer' when `desktop-read'
493evaluates the desktop file. List elements must have the form
494
495 (MAJOR-MODE . RESTORE-BUFFER-FUNCTION).
e5780ae1
LH
Lars Hansen2004-04-21 20:53:35 +0000496
497Buffers with a major mode not specified here, are restored by the default
498handler `desktop-restore-file-buffer'.
499
55775448 Lars Hansen2004-05-07 17:58:24 +0000500Handlers are called with argument list
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000501
9bcabb45 Lars Hansen2004-05-07 19:41:11 +0000502 (DESKTOP-BUFFER-FILE-NAME DESKTOP-BUFFER-NAME DESKTOP-BUFFER-MISC)
e5780ae1
LH
Lars Hansen2004-04-21 20:53:35 +0000503
504Furthermore, they may use the following variables:
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000505
ca70fe78
SM
Stefan Monnier2014-03-09 22:18:29 -0400506 `desktop-file-version'
507 `desktop-buffer-major-mode'
508 `desktop-buffer-minor-modes'
509 `desktop-buffer-point'
510 `desktop-buffer-mark'
511 `desktop-buffer-read-only'
512 `desktop-buffer-locals'
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000513
e5780ae1 Lars Hansen2004-04-21 20:53:35 +0000514If a handler returns a buffer, then the saved mode settings
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000515and variable values for that buffer are copied into it.
516
517Modules that define a major mode that needs a special handler should contain
518code like
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +0000519
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000520 (defun foo-restore-desktop-buffer
521 ...
522 (add-to-list 'desktop-buffer-mode-handlers
523 '(foo-mode . foo-restore-desktop-buffer))
524
db87b14e
GM
Glenn Morris2015-05-25 23:27:55 -0700525The major mode function must either be autoloaded, or of the form
526\"foobar-mode\" and defined in library \"foobar\", so that desktop
527can guess how to load the mode's definition.")
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +0000528
498eb267 Andreas Schwab2005-08-14 23:55:03 +0000529;;;###autoload
e5780ae1
LH
Lars Hansen2004-04-21 20:53:35 +0000530(put 'desktop-buffer-mode-handlers 'risky-local-variable t)
531(make-obsolete-variable 'desktop-buffer-handlers
cc8b76bf Juanma Barranquero2005-07-19 09:54:05 +0000532 'desktop-buffer-mode-handlers "22.1")
b6b70cda John Wiegley2000-10-13 09:11:16 +0000533
47640244
GM
Gerd Moellmann2000-04-26 17:33:02 +0000534(defcustom desktop-minor-mode-table
535 '((auto-fill-function auto-fill-mode)
8abe2042
JL
Juri Linkov2014-07-04 02:48:24 +0300536 (defining-kbd-macro nil)
537 (isearch-mode nil)
5fff0265 Juri Linkov2005-12-14 07:44:44 +0000538 (vc-mode nil)
f2168a4c Michael Olson2007-10-30 00:50:07 +0000539 (vc-dired-mode nil)
fb8a6326
JB
Juanma Barranquero2008-04-28 08:06:51 +0000540 (erc-track-minor-mode nil)
541 (savehist-mode nil))
47640244
GM
Gerd Moellmann2000-04-26 17:33:02 +0000542 "Table mapping minor mode variables to minor mode functions.
543Each entry has the form (NAME RESTORE-FUNCTION).
544NAME is the name of the buffer-local variable indicating that the minor
545mode is active. RESTORE-FUNCTION is the function to activate the minor mode.
7d6ee4df Juanma Barranquero2007-06-09 00:09:03 +0000546RESTORE-FUNCTION nil means don't try to restore the minor mode.
47640244 Gerd Moellmann2000-04-26 17:33:02 +0000547Only minor modes for which the name of the buffer-local variable
7bfa55b3 Lars Hansen2004-05-31 21:45:51 +0000548and the name of the minor mode function are different have to be added to
0f4804e7 Lars Hansen2005-08-10 19:38:52 +0000549this table. See also `desktop-minor-mode-handlers'."
47640244
GM
Gerd Moellmann2000-04-26 17:33:02 +0000550 :type 'sexp
551 :group 'desktop)
552
0f4804e7 Lars Hansen2005-08-10 19:38:52 +0000553;;;###autoload
e76f0800 Chong Yidong2012-06-21 15:15:42 +0800554(defvar desktop-minor-mode-handlers nil
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000555 "Alist of functions to restore non-standard minor modes.
556Functions are called by `desktop-create-buffer' to restore minor modes.
557List elements must have the form
558
559 (MINOR-MODE . RESTORE-FUNCTION).
560
561Minor modes not specified here, are restored by the standard minor mode
562function.
563
564Handlers are called with argument list
565
566 (DESKTOP-BUFFER-LOCALS)
567
568Furthermore, they may use the following variables:
569
ca70fe78
SM
Stefan Monnier2014-03-09 22:18:29 -0400570 `desktop-file-version'
571 `desktop-buffer-file-name'
572 `desktop-buffer-name'
573 `desktop-buffer-major-mode'
574 `desktop-buffer-minor-modes'
575 `desktop-buffer-point'
576 `desktop-buffer-mark'
577 `desktop-buffer-read-only'
578 `desktop-buffer-misc'
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000579
580When a handler is called, the buffer has been created and the major mode has
581been set, but local variables listed in desktop-buffer-locals has not yet been
582created and set.
583
584Modules that define a minor mode that needs a special handler should contain
585code like
586
587 (defun foo-desktop-restore
588 ...
589 (add-to-list 'desktop-minor-mode-handlers
590 '(foo-mode . foo-desktop-restore))
591
db87b14e
GM
Glenn Morris2015-05-25 23:27:55 -0700592The minor mode function must either be autoloaded, or of the form
593\"foobar-mode\" and defined in library \"foobar\", so that desktop
594can guess how to load the mode's definition.
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000595
596See also `desktop-minor-mode-table'.")
597
498eb267 Andreas Schwab2005-08-14 23:55:03 +0000598;;;###autoload
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000599(put 'desktop-minor-mode-handlers 'risky-local-variable t)
600
0b9bd504
RS
Richard M. Stallman1993-10-07 16:50:26 +0000601;; ----------------------------------------------------------------------------
602(defvar desktop-dirname nil
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000603 "The directory in which the desktop file should be saved.")
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +0000604
11425834
LH
Lars Hansen2006-06-23 21:42:33 +0000605(defun desktop-full-file-name (&optional dirname)
606 "Return the full name of the desktop file in DIRNAME.
607DIRNAME omitted or nil means use `desktop-dirname'."
608 (expand-file-name desktop-base-file-name (or dirname desktop-dirname)))
609
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000610(defun desktop-full-lock-name (&optional dirname)
611 "Return the full name of the desktop lock file in DIRNAME.
612DIRNAME omitted or nil means use `desktop-dirname'."
613 (expand-file-name desktop-base-lock-name (or dirname desktop-dirname)))
614
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +0000615(defconst desktop-header
0b9bd504
RS
Richard M. Stallman1993-10-07 16:50:26 +0000616";; --------------------------------------------------------------------------
617;; Desktop File for Emacs
618;; --------------------------------------------------------------------------
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +0000619" "*Header to place in Desktop file.")
de9e2828
RS
Richard M. Stallman1994-02-05 02:23:44 +0000620
621(defvar desktop-delay-hook nil
622 "Hooks run after all buffers are loaded; intended for internal use.")
813dbb2d Richard M. Stallman1997-12-29 20:58:19 +0000623
5db9dace
JL
Juri Linkov2013-04-27 23:55:00 +0300624(defvar desktop-file-checksum nil
625 "Checksum of the last auto-saved contents of the desktop file.
626Used to avoid writing contents unchanged between auto-saves.")
627
9421876d Juanma Barranquero2013-08-02 06:33:58 +0200628(defvar desktop-saved-frameset nil
56bc453c
JB
Juanma Barranquero2013-07-21 19:45:12 +0200629 "Saved state of all frames.
630Only valid during frame saving & restoring; intended for internal use.")
39c0e36f Juanma Barranquero2013-06-27 11:08:14 +0200631
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +0000632;; ----------------------------------------------------------------------------
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000633;; Desktop file conflict detection
634(defvar desktop-file-modtime nil
635 "When the desktop file was last modified to the knowledge of this Emacs.
636Used to detect desktop file conflicts.")
637
c96983ef
KD
Kelly Dean2015-02-09 13:25:53 +0000638(defvar desktop-var-serdes-funs
639 (list (list
640 'mark-ring
641 (lambda (mr)
642 (mapcar #'marker-position mr))
643 (lambda (mr)
644 (mapcar #'copy-marker mr))))
645 "Table of serialization/deserialization functions for variables.
646Each record is a list of form: (var serializer deserializer).
647These records can be freely reordered, deleted, or new ones added.
648However, for compatibility, don't modify the functions for existing records.")
649
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000650(defun desktop-owner (&optional dirname)
651 "Return the PID of the Emacs process that owns the desktop file in DIRNAME.
652Return nil if no desktop file found or no Emacs process is using it.
653DIRNAME omitted or nil means use `desktop-dirname'."
acfcc8c5
JB
Juanma Barranquero2013-07-12 13:21:01 +0200654 (let (owner
655 (file (desktop-full-lock-name dirname)))
656 (and (file-exists-p file)
657 (ignore-errors
658 (with-temp-buffer
659 (insert-file-contents-literally file)
660 (goto-char (point-min))
661 (setq owner (read (current-buffer)))
662 (integerp owner)))
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000663 owner)))
664
665(defun desktop-claim-lock (&optional dirname)
666 "Record this Emacs process as the owner of the desktop file in DIRNAME.
667DIRNAME omitted or nil means use `desktop-dirname'."
668 (write-region (number-to-string (emacs-pid)) nil
669 (desktop-full-lock-name dirname)))
670
671(defun desktop-release-lock (&optional dirname)
672 "Remove the lock file for the desktop in DIRNAME.
673DIRNAME omitted or nil means use `desktop-dirname'."
674 (let ((file (desktop-full-lock-name dirname)))
675 (when (file-exists-p file) (delete-file file))))
676
677;; ----------------------------------------------------------------------------
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000678(defun desktop-truncate (list n)
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +0000679 "Truncate LIST to at most N elements destructively."
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000680 (let ((here (nthcdr (1- n) list)))
1f7efe1b
JB
Juanma Barranquero2007-06-12 11:14:52 +0000681 (when (consp here)
682 (setcdr here nil))))
f9be4574 Richard M. Stallman1997-07-04 00:13:36 +0000683
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000684;; ----------------------------------------------------------------------------
11425834 Lars Hansen2006-06-23 21:42:33 +0000685;;;###autoload
f9be4574
RS
Richard M. Stallman1997-07-04 00:13:36 +0000686(defun desktop-clear ()
687 "Empty the Desktop.
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000688This kills all buffers except for internal ones and those with names matched by
689a regular expression in the list `desktop-clear-preserve-buffers'.
5414a283
JB
Juanma Barranquero2013-08-04 02:31:33 +0200690Furthermore, it clears the variables listed in `desktop-globals-to-clear'.
691When called interactively and `desktop-restore-frames' is non-nil, it also
692deletes all frames except the selected one (and its minibuffer frame,
693if different)."
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +0000694 (interactive)
150f39ee Lars Hansen2005-01-07 20:18:59 +0000695 (desktop-lazy-abort)
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000696 (dolist (var desktop-globals-to-clear)
697 (if (symbolp var)
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000698 (eval `(setq-default ,var nil))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000699 (eval `(setq-default ,(car var) ,(cdr var)))))
b61d71e4 Juanma Barranquero2013-07-23 03:10:54 +0200700 (let ((preserve-regexp (concat "^\\("
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000701 (mapconcat (lambda (regexp)
702 (concat "\\(" regexp "\\)"))
703 desktop-clear-preserve-buffers
704 "\\|")
705 "\\)$")))
b61d71e4
JB
Juanma Barranquero2013-07-23 03:10:54 +0200706 (dolist (buffer (buffer-list))
707 (let ((bufname (buffer-name buffer)))
da77a2e2 Juanma Barranquero2013-07-24 01:10:58 +0200708 (unless (or (eq (aref bufname 0) ?\s) ;; Don't kill internal buffers
b61d71e4
JB
Juanma Barranquero2013-07-23 03:10:54 +0200709 (string-match-p preserve-regexp bufname))
710 (kill-buffer buffer)))))
9421876d Juanma Barranquero2013-08-02 06:33:58 +0200711 (delete-other-windows)
5414a283
JB
Juanma Barranquero2013-08-04 02:31:33 +0200712 (when (and desktop-restore-frames
713 ;; Non-interactive calls to desktop-clear happen before desktop-read
714 ;; which already takes care of frame restoration and deletion.
715 (called-interactively-p 'any))
716 (let* ((this (selected-frame))
526e5233 Paul Eggert2013-08-15 22:15:51 -0700717 (mini (window-frame (minibuffer-window this)))) ; in case they differ
063233c3 Juanma Barranquero2013-08-05 06:45:17 +0200718 (dolist (frame (sort (frame-list) #'frameset-minibufferless-first-p))
5414a283
JB
Juanma Barranquero2013-08-04 02:31:33 +0200719 (condition-case err
720 (unless (or (eq frame this)
721 (eq frame mini)
722 (frame-parameter frame 'desktop-dont-clear))
723 (delete-frame frame))
724 (error
4538c058 Juanma Barranquero2014-03-11 01:46:07 +0100725 (delay-warning 'desktop (error-message-string err))))))))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000726
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +0000727;; ----------------------------------------------------------------------------
845fc5e5
JB
Juanma Barranquero2011-03-06 01:30:16 +0100728(unless noninteractive
729 (add-hook 'kill-emacs-hook 'desktop-kill))
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +0000730
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +0000731(defun desktop-kill ()
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000732 "If `desktop-save-mode' is non-nil, do what `desktop-save' says to do.
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000733If the desktop should be saved and `desktop-dirname'
734is nil, ask the user where to save the desktop."
11425834
LH
Lars Hansen2006-06-23 21:42:33 +0000735 (when (and desktop-save-mode
736 (let ((exists (file-exists-p (desktop-full-file-name))))
737 (or (eq desktop-save t)
7dd7fbb9
JD
Jan Djärv2010-04-27 08:45:43 +0200738 (and exists (eq desktop-save 'if-exists))
739 ;; If it exists, but we aren't using it, we are going
740 ;; to ask for a new directory below.
741 (and exists desktop-dirname (eq desktop-save 'ask-if-new))
11425834
LH
Lars Hansen2006-06-23 21:42:33 +0000742 (and
743 (or (memq desktop-save '(ask ask-if-new))
744 (and exists (eq desktop-save 'ask-if-exists)))
745 (y-or-n-p "Save desktop? ")))))
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000746 (unless desktop-dirname
747 (setq desktop-dirname
11425834
LH
Lars Hansen2006-06-23 21:42:33 +0000748 (file-name-as-directory
749 (expand-file-name
794855ca Juanma Barranquero2007-06-20 10:12:44 +0000750 (read-directory-name "Directory for desktop file: " nil nil t)))))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000751 (condition-case err
e88110db Juanma Barranquero2007-06-12 09:11:31 +0000752 (desktop-save desktop-dirname t)
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000753 (file-error
11425834 Lars Hansen2006-06-23 21:42:33 +0000754 (unless (yes-or-no-p "Error while saving the desktop. Ignore? ")
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000755 (signal (car err) (cdr err))))))
756 ;; If we own it, we don't anymore.
757 (when (eq (emacs-pid) (desktop-owner)) (desktop-release-lock)))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000758
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +0000759;; ----------------------------------------------------------------------------
ed2f7fc8 Richard M. Stallman1996-03-05 04:22:44 +0000760(defun desktop-list* (&rest args)
74d7f75a Juanma Barranquero2013-07-23 13:29:30 +0200761 (and args (apply #'cl-list* args)))
ed2f7fc8 Richard M. Stallman1996-03-05 04:22:44 +0000762
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000763;; ----------------------------------------------------------------------------
e88110db Juanma Barranquero2007-06-12 09:11:31 +0000764(defun desktop-buffer-info (buffer)
6065fbe0
AM
Artur Malabarba2015-03-05 13:37:23 +0000765 "Return information describing BUFFER.
766This function is not pure, as BUFFER is made current with
767`set-buffer'.
768
769Returns a list of all the necessary information to recreate the
770buffer, which is (in order):
771
772 `uniquify-buffer-base-name';
773 `buffer-file-name';
774 `buffer-name';
775 `major-mode';
776 list of minor-modes,;
777 `point';
778 `mark';
779 `buffer-read-only';
780 auxiliary information given by `desktop-save-buffer';
781 local variables;
782 auxiliary information given by `desktop-var-serdes-funs'."
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000783 (set-buffer buffer)
784 (list
a8049a30
JB
Juanma Barranquero2008-02-14 14:37:00 +0000785 ;; base name of the buffer; replaces the buffer name if managed by uniquify
786 (and (fboundp 'uniquify-buffer-base-name) (uniquify-buffer-base-name))
e88110db Juanma Barranquero2007-06-12 09:11:31 +0000787 ;; basic information
9e29c91c Juanma Barranquero2007-07-12 22:40:00 +0000788 (desktop-file-name (buffer-file-name) desktop-dirname)
a8049a30 Juanma Barranquero2008-02-14 14:37:00 +0000789 (buffer-name)
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000790 major-mode
791 ;; minor modes
792 (let (ret)
61e06b6c
AM
Artur Malabarba2015-03-05 13:43:27 +0000793 (dolist (minor-mode (mapcar #'car minor-mode-alist) ret)
794 (and (boundp minor-mode)
795 (symbol-value minor-mode)
796 (let* ((special (assq minor-mode desktop-minor-mode-table))
797 (value (cond (special (cadr special))
798 ((functionp minor-mode) minor-mode))))
799 (when value (cl-pushnew value ret))))))
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000800 ;; point and mark, and read-only status
801 (point)
802 (list (mark t) mark-active)
803 buffer-read-only
804 ;; auxiliary information
805 (when (functionp desktop-save-buffer)
9e29c91c Juanma Barranquero2007-07-12 22:40:00 +0000806 (funcall desktop-save-buffer desktop-dirname))
e88110db Juanma Barranquero2007-06-12 09:11:31 +0000807 ;; local variables
b61d71e4
JB
Juanma Barranquero2013-07-23 03:10:54 +0200808 (let ((loclist (buffer-local-variables))
809 (ll nil))
810 (dolist (local desktop-locals-to-save)
811 (let ((here (assq local loclist)))
812 (cond (here
813 (push here ll))
814 ((member local loclist)
815 (push local ll)))))
c96983ef
KD
Kelly Dean2015-02-09 13:25:53 +0000816 ll)
817 (mapcar (lambda (record)
818 (let ((var (car record)))
819 (list var
820 (funcall (cadr record) (symbol-value var)))))
821 desktop-var-serdes-funs)))
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000822
823;; ----------------------------------------------------------------------------
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400824(defun desktop--v2s (value)
825 "Convert VALUE to a pair (QUOTE . SEXP); (eval SEXP) gives VALUE.
826SEXP is an sexp that when evaluated yields VALUE.
577ed2b2 Richard M. Stallman1995-01-30 06:14:33 +0000827QUOTE may be `may' (value may be quoted),
60ff536c Juanma Barranquero2011-12-23 01:44:27 +0100828`must' (value must be quoted), or nil (value must not be quoted)."
de9e2828 Richard M. Stallman1994-02-05 02:23:44 +0000829 (cond
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000830 ((or (numberp value) (null value) (eq t value) (keywordp value))
69b2c07e Stefan Monnier2013-03-25 23:38:18 -0400831 (cons 'may value))
1f7efe1b
JB
Juanma Barranquero2007-06-12 11:14:52 +0000832 ((stringp value)
833 (let ((copy (copy-sequence value)))
834 (set-text-properties 0 (length copy) nil copy)
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400835 ;; Get rid of text properties because we cannot read them.
836 (cons 'may copy)))
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000837 ((symbolp value)
69b2c07e Stefan Monnier2013-03-25 23:38:18 -0400838 (cons 'must value))
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000839 ((vectorp value)
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400840 (let* ((pass1 (mapcar #'desktop--v2s value))
841 (special (assq nil pass1)))
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000842 (if special
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400843 (cons nil `(vector
844 ,@(mapcar (lambda (el)
845 (if (eq (car el) 'must)
846 `',(cdr el) (cdr el)))
847 pass1)))
848 (cons 'may `[,@(mapcar #'cdr pass1)]))))
1f7efe1b
JB
Juanma Barranquero2007-06-12 11:14:52 +0000849 ((consp value)
850 (let ((p value)
851 newlist
acfcc8c5 Juanma Barranquero2013-07-12 13:21:01 +0200852 use-list*)
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000853 (while (consp p)
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400854 (let ((q.sexp (desktop--v2s (car p))))
855 (push q.sexp newlist))
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000856 (setq p (cdr p)))
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400857 (when p
858 (let ((last (desktop--v2s p)))
859 (setq use-list* t)
860 (push last newlist)))
861 (if (assq nil newlist)
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000862 (cons nil
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400863 `(,(if use-list* 'desktop-list* 'list)
864 ,@(mapcar (lambda (el)
865 (if (eq (car el) 'must)
866 `',(cdr el) (cdr el)))
867 (nreverse newlist))))
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000868 (cons 'must
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400869 `(,@(mapcar #'cdr
870 (nreverse (if use-list* (cdr newlist) newlist)))
871 ,@(if use-list* (cdar newlist)))))))
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000872 ((subrp value)
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400873 (cons nil `(symbol-function
874 ',(intern-soft (substring (prin1-to-string value) 7 -1)))))
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000875 ((markerp value)
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400876 (let ((pos (marker-position value))
877 (buf (buffer-name (marker-buffer value))))
878 (cons nil
879 `(let ((mk (make-marker)))
880 (add-hook 'desktop-delay-hook
881 `(lambda ()
882 (set-marker ,mk ,,pos (get-buffer ,,buf))))
883 mk))))
884 (t ; Save as text.
885 (cons 'may "Unprintable entity"))))
de9e2828 Richard M. Stallman1994-02-05 02:23:44 +0000886
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000887;; ----------------------------------------------------------------------------
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000888(defun desktop-value-to-string (value)
577ed2b2
RS
Richard M. Stallman1995-01-30 06:14:33 +0000889 "Convert VALUE to a string that when read evaluates to the same value.
890Not all types of values are supported."
de9e2828 Richard M. Stallman1994-02-05 02:23:44 +0000891 (let* ((print-escape-newlines t)
8e554df0
JL
Juri Linkov2014-04-27 11:22:11 +0300892 (print-length nil)
893 (print-level nil)
de9e2828 Richard M. Stallman1994-02-05 02:23:44 +0000894 (float-output-format nil)
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400895 (quote.sexp (desktop--v2s value))
896 (quote (car quote.sexp))
8e554df0
JL
Juri Linkov2014-04-27 11:22:11 +0300897 (print-quoted t)
898 (txt (prin1-to-string (cdr quote.sexp))))
de9e2828
RS
Richard M. Stallman1994-02-05 02:23:44 +0000899 (if (eq quote 'must)
900 (concat "'" txt)
901 txt)))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000902
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +0000903;; ----------------------------------------------------------------------------
0e7c8611
RS
Richard M. Stallman1995-10-08 19:37:04 +0000904(defun desktop-outvar (varspec)
905 "Output a setq statement for variable VAR to the desktop file.
906The argument VARSPEC may be the variable name VAR (a symbol),
be617bbf Juanma Barranquero2006-02-10 11:07:50 +0000907or a cons cell of the form (VAR . MAX-SIZE),
0e7c8611
RS
Richard M. Stallman1995-10-08 19:37:04 +0000908which means to truncate VAR's value to at most MAX-SIZE elements
909\(if the value is a list) before saving the value."
910 (let (var size)
911 (if (consp varspec)
912 (setq var (car varspec) size (cdr varspec))
913 (setq var varspec))
1f7efe1b
JB
Juanma Barranquero2007-06-12 11:14:52 +0000914 (when (boundp var)
915 (when (and (integerp size)
916 (> size 0)
917 (listp (eval var)))
918 (desktop-truncate (eval var) size))
919 (insert "(setq "
920 (symbol-name var)
921 " "
922 (desktop-value-to-string (symbol-value var))
923 ")\n"))))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000924
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +0000925;; ----------------------------------------------------------------------------
06b60517 Juanma Barranquero2011-04-19 15:44:55 +0200926(defun desktop-save-buffer-p (filename bufname mode &rest _dummy)
ebb39555 Lars Hansen2004-04-26 18:58:19 +0000927 "Return t if buffer should have its state saved in the desktop file.
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +0000928FILENAME is the visited file name, BUFNAME is the buffer name, and
be617bbf
JB
Juanma Barranquero2006-02-10 11:07:50 +0000929MODE is the major mode.
930\n\(fn FILENAME BUFNAME MODE)"
b23caf75 Glenn Morris2010-03-24 23:18:17 -0700931 (let ((case-fold-search nil)
e59fa9ad
JB
Juanma Barranquero2014-02-22 03:10:49 +0100932 (no-regexp-to-check (not (stringp desktop-files-not-to-save)))
933 dired-skip)
934 (and (or filename
935 (not (stringp desktop-buffers-not-to-save))
936 (not (string-match-p desktop-buffers-not-to-save bufname)))
937 (not (memq mode desktop-modes-not-to-save))
938 (or (and filename
939 (or no-regexp-to-check
940 (not (string-match-p desktop-files-not-to-save filename))))
941 (and (memq mode '(dired-mode vc-dir-mode))
942 (or no-regexp-to-check
943 (not (setq dired-skip
944 (with-current-buffer bufname
945 (string-match-p desktop-files-not-to-save
946 default-directory))))))
947 (and (null filename)
948 (null dired-skip) ; bug#5755
949 (with-current-buffer bufname desktop-save-buffer)))
950 t)))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000951
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +0000952;; ----------------------------------------------------------------------------
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000953(defun desktop-file-name (filename dirname)
954 "Convert FILENAME to format specified in `desktop-file-name-format'.
955DIRNAME must be the directory in which the desktop file will be saved."
956 (cond
957 ((not filename) nil)
958 ((eq desktop-file-name-format 'tilde)
959 (let ((relative-name (file-relative-name (expand-file-name filename) "~")))
960 (cond
961 ((file-name-absolute-p relative-name) relative-name)
962 ((string= "./" relative-name) "~/")
963 ((string= "." relative-name) "~")
964 (t (concat "~/" relative-name)))))
965 ((eq desktop-file-name-format 'local) (file-relative-name filename dirname))
966 (t (expand-file-name filename))))
e5714620 Juanma Barranquero2002-11-04 08:21:51 +0000967
b3615392 Miles Bader2007-06-16 22:32:13 +0000968
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000969;; ----------------------------------------------------------------------------
9421876d
JB
Juanma Barranquero2013-08-02 06:33:58 +0200970(defun desktop--check-dont-save (frame)
971 (not (frame-parameter frame 'desktop-dont-save)))
972
973(defconst desktop--app-id `(desktop . ,desktop-file-version))
974
975(defun desktop-save-frameset ()
976 "Save the state of existing frames in `desktop-saved-frameset'.
a1c80d9d Juanma Barranquero2013-07-22 03:25:47 +0200977Frames with a non-nil `desktop-dont-save' parameter are not saved."
9421876d Juanma Barranquero2013-08-02 06:33:58 +0200978 (setq desktop-saved-frameset
2addf922 Juanma Barranquero2013-07-01 05:29:46 +0200979 (and desktop-restore-frames
a912c016
JB
Juanma Barranquero2013-08-08 00:54:08 +0200980 (frameset-save nil
981 :app desktop--app-id
f9acac75 Paul Eggert2014-12-29 12:37:53 -0800982 :name (concat user-login-name "@" (system-name))
a912c016 Juanma Barranquero2013-08-08 00:54:08 +0200983 :predicate #'desktop--check-dont-save))))
39c0e36f Juanma Barranquero2013-06-27 11:08:14 +0200984
11425834 Lars Hansen2006-06-23 21:42:33 +0000985;;;###autoload
cbb6a7ae Juri Linkov2014-07-03 02:45:12 +0300986(defun desktop-save (dirname &optional release only-if-changed)
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +0000987 "Save the desktop in a desktop file.
988Parameter DIRNAME specifies where to save the desktop file.
e88110db Juanma Barranquero2007-06-12 09:11:31 +0000989Optional parameter RELEASE says whether we're done with this desktop.
cbb6a7ae
JL
Juri Linkov2014-07-03 02:45:12 +0300990If ONLY-IF-CHANGED is non-nil, compare the current desktop information
991to that in the desktop file, and if the desktop information has not
992changed since it was last saved then do not rewrite the file."
9271e90e
GM
Glenn Morris2013-10-09 21:03:11 -0400993 (interactive (list
994 ;; Or should we just use (car desktop-path)?
995 (let ((default (if (member "." desktop-path)
996 default-directory
997 user-emacs-directory)))
998 (read-directory-name "Directory to save desktop file in: "
999 default default t))))
e88110db Juanma Barranquero2007-06-12 09:11:31 +00001000 (setq desktop-dirname (file-name-as-directory (expand-file-name dirname)))
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +00001001 (save-excursion
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +00001002 (let ((eager desktop-restore-eager)
1003 (new-modtime (nth 5 (file-attributes (desktop-full-file-name)))))
1004 (when
1005 (or (not new-modtime) ; nothing to overwrite
1006 (equal desktop-file-modtime new-modtime)
1007 (yes-or-no-p (if desktop-file-modtime
1008 (if (> (float-time new-modtime) (float-time desktop-file-modtime))
1009 "Desktop file is more recent than the one loaded. Save anyway? "
1010 "Desktop file isn't the one loaded. Overwrite it? ")
1011 "Current desktop was not loaded from a file. Overwrite this desktop file? "))
1012 (unless release (error "Desktop file conflict")))
1013
1014 ;; If we're done with it, release the lock.
1015 ;; Otherwise, claim it if it's unclaimed or if we created it.
1016 (if release
1017 (desktop-release-lock)
1018 (unless (and new-modtime (desktop-owner)) (desktop-claim-lock)))
1019
1020 (with-temp-buffer
1021 (insert
1022 ";; -*- mode: emacs-lisp; coding: emacs-mule; -*-\n"
1023 desktop-header
1024 ";; Created " (current-time-string) "\n"
1025 ";; Desktop file format version " desktop-file-version "\n"
1026 ";; Emacs version " emacs-version "\n")
1027 (save-excursion (run-hooks 'desktop-save-hook))
1028 (goto-char (point-max))
1029 (insert "\n;; Global section:\n")
39c0e36f
JB
Juanma Barranquero2013-06-27 11:08:14 +02001030 ;; Called here because we save the window/frame state as a global
1031 ;; variable for compatibility with previous Emacsen.
9421876d
JB
Juanma Barranquero2013-08-02 06:33:58 +02001032 (desktop-save-frameset)
1033 (unless (memq 'desktop-saved-frameset desktop-globals-to-save)
1034 (desktop-outvar 'desktop-saved-frameset))
e88110db Juanma Barranquero2007-06-12 09:11:31 +00001035 (mapc (function desktop-outvar) desktop-globals-to-save)
9421876d Juanma Barranquero2013-08-02 06:33:58 +02001036 (setq desktop-saved-frameset nil) ; after saving desktop-globals-to-save
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +00001037 (when (memq 'kill-ring desktop-globals-to-save)
1038 (insert
1039 "(setq kill-ring-yank-pointer (nthcdr "
1040 (int-to-string (- (length kill-ring) (length kill-ring-yank-pointer)))
1041 " kill-ring))\n"))
1042
1043 (insert "\n;; Buffer section -- buffers listed in same order as in buffer list:\n")
1044 (dolist (l (mapcar 'desktop-buffer-info (buffer-list)))
a8049a30
JB
Juanma Barranquero2008-02-14 14:37:00 +00001045 (let ((base (pop l)))
1046 (when (apply 'desktop-save-buffer-p l)
1047 (insert "("
1048 (if (or (not (integerp eager))
1049 (if (zerop eager)
1050 nil
1051 (setq eager (1- eager))))
1052 "desktop-create-buffer"
1053 "desktop-append-buffer-args")
1054 " "
1055 desktop-file-version)
ae4370a8
JB
Juanma Barranquero2008-02-29 03:03:57 +00001056 ;; If there's a non-empty base name, we save it instead of the buffer name
1057 (when (and base (not (string= base "")))
1058 (setcar (nthcdr 1 l) base))
a8049a30
JB
Juanma Barranquero2008-02-14 14:37:00 +00001059 (dolist (e l)
1060 (insert "\n " (desktop-value-to-string e)))
1061 (insert ")\n\n"))))
e88110db Juanma Barranquero2007-06-12 09:11:31 +00001062
9e29c91c Juanma Barranquero2007-07-12 22:40:00 +00001063 (setq default-directory desktop-dirname)
6c8e0ae6 Juri Linkov2013-12-16 23:48:51 +02001064 ;; When auto-saving, avoid writing if nothing has changed since the last write.
cbb6a7ae Juri Linkov2014-07-03 02:45:12 +03001065 (let* ((beg (and only-if-changed
6c8e0ae6
JL
Juri Linkov2013-12-16 23:48:51 +02001066 (save-excursion
1067 (goto-char (point-min))
1068 ;; Don't check the header with changing timestamp
1069 (and (search-forward "Global section" nil t)
1070 ;; Also skip the timestamp in desktop-saved-frameset
1071 ;; if it's saved in the first non-header line
1072 (search-forward "desktop-saved-frameset"
1073 (line-beginning-position 3) t)
1074 ;; This is saved after the timestamp
1075 (search-forward (format "%S" desktop--app-id) nil t))
1076 (point))))
1077 (checksum (and beg (md5 (current-buffer) beg (point-max) 'emacs-mule))))
1078 (unless (and checksum (equal checksum desktop-file-checksum))
5db9dace
JL
Juri Linkov2013-04-27 23:55:00 +03001079 (let ((coding-system-for-write 'emacs-mule))
1080 (write-region (point-min) (point-max) (desktop-full-file-name) nil 'nomessage))
1081 (setq desktop-file-checksum checksum)
1082 ;; We remember when it was modified (which is presumably just now).
1083 (setq desktop-file-modtime (nth 5 (file-attributes (desktop-full-file-name)))))))))))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +00001084
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +00001085;; ----------------------------------------------------------------------------
11425834 Lars Hansen2006-06-23 21:42:33 +00001086;;;###autoload
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +00001087(defun desktop-remove ()
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +00001088 "Delete desktop file in `desktop-dirname'.
1089This function also sets `desktop-dirname' to nil."
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +00001090 (interactive)
6b61353c Kenichi Handa2004-04-16 12:51:06 +00001091 (when desktop-dirname
11425834 Lars Hansen2006-06-23 21:42:33 +00001092 (let ((filename (desktop-full-file-name)))
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +00001093 (setq desktop-dirname nil)
1094 (when (file-exists-p filename)
73b0b745 Juanma Barranquero2003-06-03 23:35:20 +00001095 (delete-file filename)))))
6b61353c Kenichi Handa2004-04-16 12:51:06 +00001096
150f39ee
LH
Lars Hansen2005-01-07 20:18:59 +00001097(defvar desktop-buffer-args-list nil
1098 "List of args for `desktop-create-buffer'.")
1099
1100(defvar desktop-lazy-timer nil)
1101
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +00001102;; ----------------------------------------------------------------------------
9421876d
JB
Juanma Barranquero2013-08-02 06:33:58 +02001103(defun desktop-restoring-frameset-p ()
1104 "True if calling `desktop-restore-frameset' will actually restore it."
1105 (and desktop-restore-frames desktop-saved-frameset t))
1106
1107(defun desktop-restore-frameset ()
1108 "Restore the state of a set of frames.
1109This function depends on the value of `desktop-saved-frameset'
56bc453c Juanma Barranquero2013-07-21 19:45:12 +02001110being set (usually, by reading it from the desktop)."
9421876d
JB
Juanma Barranquero2013-08-02 06:33:58 +02001111 (when (desktop-restoring-frameset-p)
1112 (frameset-restore desktop-saved-frameset
4538c058
JB
Juanma Barranquero2014-03-11 01:46:07 +01001113 :reuse-frames (eq desktop-restore-reuses-frames t)
1114 :cleanup-frames (not (eq desktop-restore-reuses-frames 'keep))
9421876d
JB
Juanma Barranquero2013-08-02 06:33:58 +02001115 :force-display desktop-restore-in-current-display
1116 :force-onscreen desktop-restore-forces-onscreen)))
1117
1118;; Just to silence the byte compiler.
526e5233 Paul Eggert2013-08-15 22:15:51 -07001119;; Dynamically bound in `desktop-read'.
9421876d
JB
Juanma Barranquero2013-08-02 06:33:58 +02001120(defvar desktop-first-buffer)
1121(defvar desktop-buffer-ok-count)
1122(defvar desktop-buffer-fail-count)
39c0e36f Juanma Barranquero2013-06-27 11:08:14 +02001123
c863b6ad Glenn Morris2014-02-17 17:33:30 -08001124;; FIXME Interactively, this should have the option to prompt for dirname.
478653c9 Richard M. Stallman1998-03-28 07:32:50 +00001125;;;###autoload
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +00001126(defun desktop-read (&optional dirname)
1127 "Read and process the desktop file in directory DIRNAME.
1128Look for a desktop file in DIRNAME, or if DIRNAME is omitted, look in
1129directories listed in `desktop-path'. If a desktop file is found, it
cc8b76bf Juanma Barranquero2005-07-19 09:54:05 +00001130is processed and `desktop-after-read-hook' is run. If no desktop file
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +00001131is found, clear the desktop and run `desktop-no-desktop-file-hook'.
1132This function is a no-op when Emacs is running in batch mode.
1133It returns t if a desktop file was loaded, nil otherwise."
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +00001134 (interactive)
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +00001135 (unless noninteractive
6b61353c Kenichi Handa2004-04-16 12:51:06 +00001136 (setq desktop-dirname
11425834
LH
Lars Hansen2006-06-23 21:42:33 +00001137 (file-name-as-directory
1138 (expand-file-name
1139 (or
1140 ;; If DIRNAME is specified, use it.
1141 (and (< 0 (length dirname)) dirname)
1142 ;; Otherwise search desktop file in desktop-path.
1143 (let ((dirs desktop-path))
1144 (while (and dirs
1145 (not (file-exists-p
1146 (desktop-full-file-name (car dirs)))))
1147 (setq dirs (cdr dirs)))
1148 (and dirs (car dirs)))
1149 ;; If not found and `desktop-path' is non-nil, use its first element.
1150 (and desktop-path (car desktop-path))
6b67c0d4
CY
Chong Yidong2012-06-21 15:25:56 +08001151 ;; Default: .emacs.d.
1152 user-emacs-directory))))
11425834 Lars Hansen2006-06-23 21:42:33 +00001153 (if (file-exists-p (desktop-full-file-name))
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +00001154 ;; Desktop file found, but is it already in use?
1155 (let ((desktop-first-buffer nil)
1156 (desktop-buffer-ok-count 0)
1157 (desktop-buffer-fail-count 0)
1158 (owner (desktop-owner))
1159 ;; Avoid desktop saving during evaluation of desktop buffer.
1e00ee24
KD
Kelly Dean2015-02-16 04:18:25 +00001160 (desktop-save nil)
1161 (desktop-autosave-was-enabled))
e88110db Juanma Barranquero2007-06-12 09:11:31 +00001162 (if (and owner
1f7efe1b
JB
Juanma Barranquero2007-06-12 11:14:52 +00001163 (memq desktop-load-locked-desktop '(nil ask))
1164 (or (null desktop-load-locked-desktop)
e76f0800 Chong Yidong2012-06-21 15:15:42 +08001165 (daemonp)
1f7efe1b
JB
Juanma Barranquero2007-06-12 11:14:52 +00001166 (not (y-or-n-p (format "Warning: desktop file appears to be in use by PID %s.\n\
1167Using it may cause conflicts. Use it anyway? " owner)))))
c41cf130 Juanma Barranquero2008-03-01 14:17:41 +00001168 (let ((default-directory desktop-dirname))
794855ca Juanma Barranquero2007-06-20 10:12:44 +00001169 (setq desktop-dirname nil)
c41cf130
JB
Juanma Barranquero2008-03-01 14:17:41 +00001170 (run-hooks 'desktop-not-loaded-hook)
1171 (unless desktop-dirname
1172 (message "Desktop file in use; not loaded.")))
e88110db Juanma Barranquero2007-06-12 09:11:31 +00001173 (desktop-lazy-abort)
a4d8b73e
JL
Juri Linkov2014-06-25 02:23:41 +03001174 ;; Temporarily disable the autosave that will leave it
1175 ;; disabled when loading the desktop fails with errors,
1176 ;; thus not overwriting the desktop with broken contents.
1e00ee24
KD
Kelly Dean2015-02-16 04:18:25 +00001177 (setq desktop-autosave-was-enabled
1178 (memq 'desktop-auto-save-set-timer window-configuration-change-hook))
a4d8b73e Juri Linkov2014-06-25 02:23:41 +03001179 (desktop-auto-save-disable)
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +00001180 ;; Evaluate desktop buffer and remember when it was modified.
1181 (load (desktop-full-file-name) t t t)
1182 (setq desktop-file-modtime (nth 5 (file-attributes (desktop-full-file-name))))
1183 ;; If it wasn't already, mark it as in-use, to bother other
1184 ;; desktop instances.
c99cf5ee Juri Linkov2014-02-07 09:58:10 +02001185 (unless (eq (emacs-pid) owner)
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +00001186 (condition-case nil
1187 (desktop-claim-lock)
1188 (file-error (message "Couldn't record use of desktop file")
1189 (sit-for 1))))
1190
9421876d Juanma Barranquero2013-08-02 06:33:58 +02001191 (unless (desktop-restoring-frameset-p)
56bc453c
JB
Juanma Barranquero2013-07-21 19:45:12 +02001192 ;; `desktop-create-buffer' puts buffers at end of the buffer list.
1193 ;; We want buffers existing prior to evaluating the desktop (and
1194 ;; not reused) to be placed at the end of the buffer list, so we
1195 ;; move them here.
1196 (mapc 'bury-buffer
1197 (nreverse (cdr (memq desktop-first-buffer (nreverse (buffer-list))))))
1198 (switch-to-buffer (car (buffer-list))))
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +00001199 (run-hooks 'desktop-delay-hook)
1200 (setq desktop-delay-hook nil)
9421876d Juanma Barranquero2013-08-02 06:33:58 +02001201 (desktop-restore-frameset)
e88110db Juanma Barranquero2007-06-12 09:11:31 +00001202 (run-hooks 'desktop-after-read-hook)
9421876d
JB
Juanma Barranquero2013-08-02 06:33:58 +02001203 (message "Desktop: %s%d buffer%s restored%s%s."
1204 (if desktop-saved-frameset
1205 (let ((fn (length (frameset-states desktop-saved-frameset))))
1206 (format "%d frame%s, "
1207 fn (if (= fn 1) "" "s")))
1208 "")
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +00001209 desktop-buffer-ok-count
1210 (if (= 1 desktop-buffer-ok-count) "" "s")
1211 (if (< 0 desktop-buffer-fail-count)
1212 (format ", %d failed to restore" desktop-buffer-fail-count)
1213 "")
1214 (if desktop-buffer-args-list
1215 (format ", %d to restore lazily"
1216 (length desktop-buffer-args-list))
1217 ""))
9421876d Juanma Barranquero2013-08-02 06:33:58 +02001218 (unless (desktop-restoring-frameset-p)
56bc453c
JB
Juanma Barranquero2013-07-21 19:45:12 +02001219 ;; Bury the *Messages* buffer to not reshow it when burying
1220 ;; the buffer we switched to above.
1221 (when (buffer-live-p (get-buffer "*Messages*"))
1222 (bury-buffer "*Messages*"))
1223 ;; Clear all windows' previous and next buffers, these have
1224 ;; been corrupted by the `switch-to-buffer' calls in
1225 ;; `desktop-restore-file-buffer' (bug#11556). This is a
1226 ;; brute force fix and should be replaced by a more subtle
1227 ;; strategy eventually.
1228 (walk-window-tree (lambda (window)
1229 (set-window-prev-buffers window nil)
1230 (set-window-next-buffers window nil))))
5414a283 Juanma Barranquero2013-08-04 02:31:33 +02001231 (setq desktop-saved-frameset nil)
1e00ee24 Kelly Dean2015-02-16 04:18:25 +00001232 (if desktop-autosave-was-enabled (desktop-auto-save-enable))
e88110db Juanma Barranquero2007-06-12 09:11:31 +00001233 t))
6b61353c Kenichi Handa2004-04-16 12:51:06 +00001234 ;; No desktop file found.
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +00001235 (let ((default-directory desktop-dirname))
1236 (run-hooks 'desktop-no-desktop-file-hook))
1237 (message "No desktop file.")
1238 nil)))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +00001239
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +00001240;; ----------------------------------------------------------------------------
6b61353c Kenichi Handa2004-04-16 12:51:06 +00001241;; Maintained for backward compatibility
478653c9 Richard M. Stallman1998-03-28 07:32:50 +00001242;;;###autoload
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +00001243(defun desktop-load-default ()
577ed2b2 Richard M. Stallman1995-01-30 06:14:33 +00001244 "Load the `default' start-up library manually.
6b61353c Kenichi Handa2004-04-16 12:51:06 +00001245Also inhibit further loading of it."
59f7af81 Chong Yidong2012-09-25 12:13:02 +08001246 (declare (obsolete desktop-save-mode "22.1"))
b89c5a72
JB
Juanma Barranquero2005-07-29 10:25:15 +00001247 (unless inhibit-default-init ; safety check
1248 (load "default" t t)
1249 (setq inhibit-default-init t)))
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +00001250
1251;; ----------------------------------------------------------------------------
1252;;;###autoload
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +00001253(defun desktop-change-dir (dirname)
1254 "Change to desktop saved in DIRNAME.
1255Kill the desktop as specified by variables `desktop-save-mode' and
1256`desktop-save', then clear the desktop and load the desktop file in
1257directory DIRNAME."
1258 (interactive "DChange to directory: ")
1259 (setq dirname (file-name-as-directory (expand-file-name dirname desktop-dirname)))
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +00001260 (desktop-kill)
1261 (desktop-clear)
6b61353c Kenichi Handa2004-04-16 12:51:06 +00001262 (desktop-read dirname))
bf247b6e Kim F. Storm2005-02-09 15:50:47 +00001263
6b61353c Kenichi Handa2004-04-16 12:51:06 +00001264;; ----------------------------------------------------------------------------
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +00001265;;;###autoload
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +00001266(defun desktop-save-in-desktop-dir ()
1267 "Save the desktop in directory `desktop-dirname'."
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +00001268 (interactive)
1269 (if desktop-dirname
b89c5a72 Juanma Barranquero2005-07-29 10:25:15 +00001270 (desktop-save desktop-dirname)
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +00001271 (call-interactively 'desktop-save))
a609d13b Juanma Barranquero2009-01-05 02:49:31 +00001272 (message "Desktop saved in %s" (abbreviate-file-name desktop-dirname)))
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +00001273
1274;; ----------------------------------------------------------------------------
5db9dace
JL
Juri Linkov2013-04-27 23:55:00 +03001275;; Auto-Saving.
1276(defvar desktop-auto-save-timer nil)
1277
a4d8b73e
JL
Juri Linkov2014-06-25 02:23:41 +03001278(defun desktop-auto-save-enable (&optional timeout)
1279 (when (and (integerp (or timeout desktop-auto-save-timeout))
1280 (> (or timeout desktop-auto-save-timeout) 0))
1281 (add-hook 'window-configuration-change-hook 'desktop-auto-save-set-timer)))
1282
1283(defun desktop-auto-save-disable ()
1284 (remove-hook 'window-configuration-change-hook 'desktop-auto-save-set-timer)
1285 (desktop-auto-save-cancel-timer))
1286
5db9dace
JL
Juri Linkov2013-04-27 23:55:00 +03001287(defun desktop-auto-save ()
1288 "Save the desktop periodically.
1289Called by the timer created in `desktop-auto-save-set-timer'."
1290 (when (and desktop-save-mode
1291 (integerp desktop-auto-save-timeout)
1292 (> desktop-auto-save-timeout 0)
1293 ;; Avoid desktop saving during lazy loading.
1294 (not desktop-lazy-timer)
1295 ;; Save only to own desktop file.
1296 (eq (emacs-pid) (desktop-owner))
1297 desktop-dirname)
6c8e0ae6 Juri Linkov2013-12-16 23:48:51 +02001298 (desktop-save desktop-dirname nil t)))
5db9dace
JL
Juri Linkov2013-04-27 23:55:00 +03001299
1300(defun desktop-auto-save-set-timer ()
6c8e0ae6 Juri Linkov2013-12-16 23:48:51 +02001301 "Set the auto-save timer.
5db9dace Juri Linkov2013-04-27 23:55:00 +03001302Cancel any previous timer. When `desktop-auto-save-timeout' is a positive
6c8e0ae6
JL
Juri Linkov2013-12-16 23:48:51 +02001303integer, start a new idle timer to call `desktop-auto-save' repeatedly
1304after that many seconds of idle time."
2b777cd9 Juri Linkov2014-02-07 09:44:29 +02001305 (desktop-auto-save-cancel-timer)
5db9dace
JL
Juri Linkov2013-04-27 23:55:00 +03001306 (when (and (integerp desktop-auto-save-timeout)
1307 (> desktop-auto-save-timeout 0))
1308 (setq desktop-auto-save-timer
7f118009 Juri Linkov2014-06-07 02:38:40 +03001309 (run-with-idle-timer desktop-auto-save-timeout nil
6c8e0ae6 Juri Linkov2013-12-16 23:48:51 +02001310 'desktop-auto-save))))
5db9dace Juri Linkov2013-04-27 23:55:00 +03001311
2b777cd9
JL
Juri Linkov2014-02-07 09:44:29 +02001312(defun desktop-auto-save-cancel-timer ()
1313 (when desktop-auto-save-timer
1314 (cancel-timer desktop-auto-save-timer)
1315 (setq desktop-auto-save-timer nil)))
1316
5db9dace Juri Linkov2013-04-27 23:55:00 +03001317;; ----------------------------------------------------------------------------
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +00001318;;;###autoload
1319(defun desktop-revert ()
1320 "Revert to the last loaded desktop."
1321 (interactive)
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +00001322 (unless desktop-dirname
1323 (error "Unknown desktop directory"))
11425834 Lars Hansen2006-06-23 21:42:33 +00001324 (unless (file-exists-p (desktop-full-file-name))
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +00001325 (error "No desktop file found"))
1326 (desktop-clear)
1327 (desktop-read desktop-dirname))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +00001328
341c2f07
SM
Stefan Monnier2007-04-11 02:28:26 +00001329(defvar desktop-buffer-major-mode)
1330(defvar desktop-buffer-locals)
06b60517 Juanma Barranquero2011-04-19 15:44:55 +02001331(defvar auto-insert) ; from autoinsert.el
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +00001332;; ----------------------------------------------------------------------------
06b60517
JB
Juanma Barranquero2011-04-19 15:44:55 +02001333(defun desktop-restore-file-buffer (buffer-filename
1334 _buffer-name
1335 _buffer-misc)
e5780ae1 Lars Hansen2004-04-21 20:53:35 +00001336 "Restore a file buffer."
06b60517
JB
Juanma Barranquero2011-04-19 15:44:55 +02001337 (when buffer-filename
1338 (if (or (file-exists-p buffer-filename)
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +00001339 (let ((msg (format "Desktop: File \"%s\" no longer exists."
06b60517 Juanma Barranquero2011-04-19 15:44:55 +02001340 buffer-filename)))
1f7efe1b
JB
Juanma Barranquero2007-06-12 11:14:52 +00001341 (if desktop-missing-file-warning
1342 (y-or-n-p (concat msg " Re-create buffer? "))
1343 (message "%s" msg)
1344 nil)))
1345 (let* ((auto-insert nil) ; Disable auto insertion
1346 (coding-system-for-read
1347 (or coding-system-for-read
1348 (cdr (assq 'buffer-file-coding-system
1349 desktop-buffer-locals))))
06b60517 Juanma Barranquero2011-04-19 15:44:55 +02001350 (buf (find-file-noselect buffer-filename)))
1f7efe1b
JB
Juanma Barranquero2007-06-12 11:14:52 +00001351 (condition-case nil
1352 (switch-to-buffer buf)
1353 (error (pop-to-buffer buf)))
1354 (and (not (eq major-mode desktop-buffer-major-mode))
1355 (functionp desktop-buffer-major-mode)
1356 (funcall desktop-buffer-major-mode))
1357 buf)
1358 nil)))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +00001359
0f4804e7 Lars Hansen2005-08-10 19:38:52 +00001360(defun desktop-load-file (function)
db87b14e
GM
Glenn Morris2015-05-25 23:27:55 -07001361 "Load the file where auto loaded FUNCTION is defined.
1362If FUNCTION is not currently defined, guess the library that defines it
1363and try to load that."
1364 (if (fboundp function)
1365 (autoload-do-load (symbol-function function) function)
1366 ;; Guess that foobar-mode is defined in foobar.
1367 ;; TODO rather than guessing or requiring an autoload, the desktop
1368 ;; file should record the name of the library.
1369 (let ((name (symbol-name function)))
1370 (if (string-match "\\`\\(.*\\)-mode\\'" name)
1371 (with-demoted-errors "Require error in desktop-load-file: %S"
1372 (require (intern (match-string 1 name)) nil t))))))
0f4804e7 Lars Hansen2005-08-10 19:38:52 +00001373
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +00001374;; ----------------------------------------------------------------------------
eb982898
JL
Juri Linkov2004-04-27 06:52:35 +00001375;; Create a buffer, load its file, set its mode, ...;
1376;; called from Desktop file only.
1d500ca6 Gerd Moellmann2001-10-23 13:52:45 +00001377
340db502 Lars Hansen2004-09-09 19:45:03 +00001378(defun desktop-create-buffer
06b60517
JB
Juanma Barranquero2011-04-19 15:44:55 +02001379 (file-version
1380 buffer-filename
1381 buffer-name
1382 buffer-majormode
1383 buffer-minormodes
1384 buffer-point
1385 buffer-mark
1386 buffer-readonly
1387 buffer-misc
1388 &optional
c96983ef
KD
Kelly Dean2015-02-09 13:25:53 +00001389 buffer-locals
1390 compacted-vars
1391 &rest _unsupported)
06b60517
JB
Juanma Barranquero2011-04-19 15:44:55 +02001392
1393 (let ((desktop-file-version file-version)
1394 (desktop-buffer-file-name buffer-filename)
1395 (desktop-buffer-name buffer-name)
1396 (desktop-buffer-major-mode buffer-majormode)
1397 (desktop-buffer-minor-modes buffer-minormodes)
1398 (desktop-buffer-point buffer-point)
1399 (desktop-buffer-mark buffer-mark)
1400 (desktop-buffer-read-only buffer-readonly)
1401 (desktop-buffer-misc buffer-misc)
1402 (desktop-buffer-locals buffer-locals))
1403 ;; To make desktop files with relative file names possible, we cannot
1404 ;; allow `default-directory' to change. Therefore we save current buffer.
1405 (save-current-buffer
1406 ;; Give major mode module a chance to add a handler.
1407 (desktop-load-file desktop-buffer-major-mode)
1408 (let ((buffer-list (buffer-list))
1409 (result
1be3ca5a Leo Liu2012-02-10 23:59:29 +08001410 (condition-case-unless-debug err
06b60517
JB
Juanma Barranquero2011-04-19 15:44:55 +02001411 (funcall (or (cdr (assq desktop-buffer-major-mode
1412 desktop-buffer-mode-handlers))
1413 'desktop-restore-file-buffer)
1414 desktop-buffer-file-name
1415 desktop-buffer-name
1416 desktop-buffer-misc)
1417 (error
1418 (message "Desktop: Can't load buffer %s: %s"
1419 desktop-buffer-name
1420 (error-message-string err))
1421 (when desktop-missing-file-warning (sit-for 1))
1422 nil))))
1423 (if (bufferp result)
1424 (setq desktop-buffer-ok-count (1+ desktop-buffer-ok-count))
1425 (setq desktop-buffer-fail-count (1+ desktop-buffer-fail-count))
1426 (setq result nil))
1427 ;; Restore buffer list order with new buffer at end. Don't change
91af3942 Paul Eggert2011-11-14 15:59:56 -08001428 ;; the order for old desktop files (old desktop module behavior).
06b60517 Juanma Barranquero2011-04-19 15:44:55 +02001429 (unless (< desktop-file-version 206)
2776a650
IS
Ivan Shmakov2014-09-09 20:47:20 -04001430 (dolist (buf buffer-list)
1431 (and (buffer-live-p buf)
1432 (bury-buffer buf)))
06b60517
JB
Juanma Barranquero2011-04-19 15:44:55 +02001433 (when result (bury-buffer result)))
1434 (when result
1435 (unless (or desktop-first-buffer (< desktop-file-version 206))
1436 (setq desktop-first-buffer result))
1437 (set-buffer result)
1438 (unless (equal (buffer-name) desktop-buffer-name)
1439 (rename-buffer desktop-buffer-name t))
1440 ;; minor modes
1441 (cond ((equal '(t) desktop-buffer-minor-modes) ; backwards compatible
1442 (auto-fill-mode 1))
1443 ((equal '(nil) desktop-buffer-minor-modes) ; backwards compatible
1444 (auto-fill-mode 0))
1445 (t
1446 (dolist (minor-mode desktop-buffer-minor-modes)
1447 ;; Give minor mode module a chance to add a handler.
1448 (desktop-load-file minor-mode)
1449 (let ((handler (cdr (assq minor-mode desktop-minor-mode-handlers))))
1450 (if handler
1451 (funcall handler desktop-buffer-locals)
1452 (when (functionp minor-mode)
1453 (funcall minor-mode 1)))))))
1454 ;; Even though point and mark are non-nil when written by
1455 ;; `desktop-save', they may be modified by handlers wanting to set
1456 ;; point or mark themselves.
1457 (when desktop-buffer-point
1458 (goto-char
1459 (condition-case err
1460 ;; Evaluate point. Thus point can be something like
1461 ;; '(search-forward ...
1462 (eval desktop-buffer-point)
1463 (error (message "%s" (error-message-string err)) 1))))
1464 (when desktop-buffer-mark
ca70fe78
SM
Stefan Monnier2014-03-09 22:18:29 -04001465 (if (consp desktop-buffer-mark)
1466 (progn
1467 (move-marker (mark-marker) (car desktop-buffer-mark))
bf642130
SM
Stefan Monnier2014-11-21 13:01:40 -05001468 (if (car (cdr desktop-buffer-mark))
1469 (activate-mark 'dont-touch-tmm)))
ca70fe78 Stefan Monnier2014-03-09 22:18:29 -04001470 (move-marker (mark-marker) desktop-buffer-mark)))
06b60517
JB
Juanma Barranquero2011-04-19 15:44:55 +02001471 ;; Never override file system if the file really is read-only marked.
1472 (when desktop-buffer-read-only (setq buffer-read-only desktop-buffer-read-only))
b61d71e4
JB
Juanma Barranquero2013-07-23 03:10:54 +02001473 (dolist (this desktop-buffer-locals)
1474 (if (consp this)
ca70fe78 Stefan Monnier2014-03-09 22:18:29 -04001475 ;; An entry of this form `(symbol . value)'.
b61d71e4
JB
Juanma Barranquero2013-07-23 03:10:54 +02001476 (progn
1477 (make-local-variable (car this))
1478 (set (car this) (cdr this)))
ca70fe78 Stefan Monnier2014-03-09 22:18:29 -04001479 ;; An entry of the form `symbol'.
b61d71e4 Juanma Barranquero2013-07-23 03:10:54 +02001480 (make-local-variable this)
c96983ef
KD
Kelly Dean2015-02-09 13:25:53 +00001481 (makunbound this)))
1482 (unless (< desktop-file-version 208) ; Don't misinterpret any old custom args
1483 (dolist (record compacted-vars)
1484 (let*
1485 ((var (car record))
26f8a384 Stefan Monnier2015-04-10 01:50:22 -04001486 (deser-fun (nth 2 (assq var desktop-var-serdes-funs))))
c96983ef
KD
Kelly Dean2015-02-09 13:25:53 +00001487 (if deser-fun (set var (funcall deser-fun (cadr record))))))))
1488 result))))
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +00001489
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +00001490;; ----------------------------------------------------------------------------
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +00001491;; Backward compatibility -- update parameters to 205 standards.
06b60517
JB
Juanma Barranquero2011-04-19 15:44:55 +02001492(defun desktop-buffer (buffer-filename buffer-name buffer-majormode
1493 mim pt mk ro tl fc cfs cr buffer-misc)
1494 (desktop-create-buffer 205 buffer-filename buffer-name
1495 buffer-majormode (cdr mim) pt mk ro
1496 buffer-misc
ec4c6f22
RS
Richard M. Stallman1994-01-06 11:34:51 +00001497 (list (cons 'truncate-lines tl)
1498 (cons 'fill-column fc)
1499 (cons 'case-fold-search cfs)
1500 (cons 'case-replace cr)
1501 (cons 'overwrite-mode (car mim)))))
84b538ec Juanma Barranquero2003-04-10 16:26:12 +00001502
150f39ee Lars Hansen2005-01-07 20:18:59 +00001503(defun desktop-append-buffer-args (&rest args)
cc8b76bf Juanma Barranquero2005-07-19 09:54:05 +00001504 "Append ARGS at end of `desktop-buffer-args-list'.
150f39ee
LH
Lars Hansen2005-01-07 20:18:59 +00001505ARGS must be an argument list for `desktop-create-buffer'."
1506 (setq desktop-buffer-args-list (nconc desktop-buffer-args-list (list args)))
1507 (unless desktop-lazy-timer
1508 (setq desktop-lazy-timer
1509 (run-with-idle-timer desktop-lazy-idle-delay t 'desktop-idle-create-buffers))))
1510
1511(defun desktop-lazy-create-buffer ()
1512 "Pop args from `desktop-buffer-args-list', create buffer and bury it."
1513 (when desktop-buffer-args-list
1514 (let* ((remaining (length desktop-buffer-args-list))
1515 (args (pop desktop-buffer-args-list))
1516 (buffer-name (nth 2 args))
1517 (msg (format "Desktop lazily opening %s (%s remaining)..."
1518 buffer-name remaining)))
1519 (when desktop-lazy-verbose
8a26c165 Deepak Goel2005-09-18 12:25:02 +00001520 (message "%s" msg))
150f39ee
LH
Lars Hansen2005-01-07 20:18:59 +00001521 (let ((desktop-first-buffer nil)
1522 (desktop-buffer-ok-count 0)
1523 (desktop-buffer-fail-count 0))
1524 (apply 'desktop-create-buffer args)
1525 (run-hooks 'desktop-delay-hook)
1526 (setq desktop-delay-hook nil)
1527 (bury-buffer (get-buffer buffer-name))
1528 (when desktop-lazy-verbose
1529 (message "%s%s" msg (if (> desktop-buffer-ok-count 0) "done" "failed")))))))
1530
1531(defun desktop-idle-create-buffers ()
1532 "Create buffers until the user does something, then stop.
1533If there are no buffers left to create, kill the timer."
1534 (let ((repeat 1))
1535 (while (and repeat desktop-buffer-args-list)
1536 (save-window-excursion
1537 (desktop-lazy-create-buffer))
1538 (setq repeat (sit-for 0.2))
1539 (unless desktop-buffer-args-list
1540 (cancel-timer desktop-lazy-timer)
1541 (setq desktop-lazy-timer nil)
1542 (message "Lazy desktop load complete")
1543 (sit-for 3)
1544 (message "")))))
1545
1546(defun desktop-lazy-complete ()
1547 "Run the desktop load to completion."
1548 (interactive)
1549 (let ((desktop-lazy-verbose t))
1550 (while desktop-buffer-args-list
1551 (save-window-excursion
1552 (desktop-lazy-create-buffer)))
1553 (message "Lazy desktop load complete")))
1554
1555(defun desktop-lazy-abort ()
1556 "Abort lazy loading of the desktop."
1557 (interactive)
1558 (when desktop-lazy-timer
1559 (cancel-timer desktop-lazy-timer)
1560 (setq desktop-lazy-timer nil))
1561 (when desktop-buffer-args-list
1562 (setq desktop-buffer-args-list nil)
32226619 Juanma Barranquero2009-10-02 03:48:36 +00001563 (when (called-interactively-p 'interactive)
150f39ee
LH
Lars Hansen2005-01-07 20:18:59 +00001564 (message "Lazy desktop load aborted"))))
1565
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +00001566;; ----------------------------------------------------------------------------
6b61353c Kenichi Handa2004-04-16 12:51:06 +00001567;; When `desktop-save-mode' is non-nil and "--no-desktop" is not specified on the
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +00001568;; command line, we do the rest of what it takes to use desktop, but do it
1569;; after finishing loading the init file.
1570;; We cannot use `command-switch-alist' to process "--no-desktop" because these
1571;; functions are processed after `after-init-hook'.
1572(add-hook
1573 'after-init-hook
341c2f07 Stefan Monnier2007-04-11 02:28:26 +00001574 (lambda ()
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +00001575 (let ((key "--no-desktop"))
4b217d46
LH
Lars Hansen2005-04-18 18:27:39 +00001576 (when (member key command-line-args)
1577 (setq command-line-args (delete key command-line-args))
2b777cd9 Juri Linkov2014-02-07 09:44:29 +02001578 (desktop-save-mode 0)))
54d22a6f Juri Linkov2008-02-12 23:41:19 +00001579 (when desktop-save-mode
61dcf9bc
GM
Glenn Morris2014-07-15 21:28:42 -07001580 ;; People don't expect emacs -nw, or --daemon,
1581 ;; to create graphical frames (bug#17693).
1582 ;; TODO perhaps there should be a separate value
1583 ;; for desktop-restore-frames to control this startup behavior?
1584 (let ((desktop-restore-frames (and desktop-restore-frames
1585 initial-window-system
1586 (not (daemonp)))))
1587 (desktop-read)
1588 (setq inhibit-startup-screen t)))))
813dbb2d Richard M. Stallman1997-12-29 20:58:19 +00001589
ab1d55ea Richard M. Stallman1993-06-01 20:11:54 +00001590(provide 'desktop)
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +00001591
80f9f3db Stefan Monnier2000-10-10 16:42:37 +00001592;;; desktop.el ends here
8c106d17
GM
Glenn Morris2013-10-12 17:31:19 -07001593
1594;; Local Variables:
1595;; coding: utf-8
1596;; End: