Support the biblatex journaltitle field
[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
fb8a6326 Juanma Barranquero2008-04-28 08:06:51 +000086;; in the module itself, and make sure that the mode function is
341c2f07 Stefan Monnier2007-04-11 02:28:26 +000087;; autoloaded. See the docstrings of `desktop-buffer-mode-handlers' and
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +000088;; `desktop-minor-mode-handlers' for more info.
89
90;; Minor modes.
91;; ------------
92;; Conventional minor modes (see node "Minor Mode Conventions" in the elisp
93;; manual) are handled in the following way:
94;; When `desktop-save' saves the state of a buffer to the desktop file, it
95;; saves as `desktop-minor-modes' the list of names of those variables in
96;; `minor-mode-alist' that have a non-nil value.
97;; When `desktop-create' restores the buffer, each of the symbols in
98;; `desktop-minor-modes' is called as function with parameter 1.
99;; The variables `desktop-minor-mode-table' and `desktop-minor-mode-handlers'
100;; are used to handle non-conventional minor modes. `desktop-save' uses
101;; `desktop-minor-mode-table' to map minor mode variables to minor mode
341c2f07 Stefan Monnier2007-04-11 02:28:26 +0000102;; functions before writing `desktop-minor-modes'. If a minor mode has a
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000103;; variable name that is different form its function name, an entry
104
105;; (NAME RESTORE-FUNCTION)
106
107;; should be added to `desktop-minor-mode-table'. If a minor mode should not
108;; be restored, RESTORE-FUNCTION should be set to nil. `desktop-create' uses
109;; `desktop-minor-mode-handlers' to lookup minor modes that needs a restore
110;; function different from the usual minor mode function.
111;; ---------------------------------------------------------------------------
47640244 Gerd Moellmann2000-04-26 17:33:02 +0000112
ec4c6f22
RS
Richard M. Stallman1994-01-06 11:34:51 +0000113;; By the way: don't use desktop.el to customize Emacs -- the file .emacs
114;; in your home directory is used for that. Saving global default values
115;; for buffers is an example of misuse.
116
0b9bd504
RS
Richard M. Stallman1993-10-07 16:50:26 +0000117;; PLEASE NOTE: The kill ring can be saved as specified by the variable
118;; `desktop-globals-to-save' (by default it isn't). This may result in saving
119;; things you did not mean to keep. Use M-x desktop-clear RET.
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +0000120
fa379636
KH
Karl Heuer1994-05-01 02:07:27 +0000121;; Thanks to hetrick@phys.uva.nl (Jim Hetrick) for useful ideas.
122;; avk@rtsg.mot.com (Andrew V. Klein) for a dired tip.
123;; chris@tecc.co.uk (Chris Boucher) for a mark tip.
124;; f89-kam@nada.kth.se (Klas Mellbourn) for a mh-e tip.
125;; kifer@sbkifer.cs.sunysb.edu (M. Kifer) for a bug hunt.
f4c73d07 Richard M. Stallman1995-04-06 20:05:39 +0000126;; treese@lcs.mit.edu (Win Treese) for ange-ftp tips.
8c106d17 Glenn Morris2013-10-12 17:31:19 -0700127;; pot@cnuce.cnr.it (Francesco Potortì) for misc. tips.
0b9bd504
RS
Richard M. Stallman1993-10-07 16:50:26 +0000128;; ---------------------------------------------------------------------------
129;; TODO:
130;;
0b9bd504
RS
Richard M. Stallman1993-10-07 16:50:26 +0000131;; Recognize more minor modes.
132;; Save mark rings.
6343ed61
RS
Richard M. Stallman1993-06-01 20:09:25 +0000133
134;;; Code:
135
a1c80d9d Juanma Barranquero2013-07-22 03:25:47 +0200136(require 'cl-lib)
9421876d Juanma Barranquero2013-08-02 06:33:58 +0200137(require 'frameset)
a1c80d9d Juanma Barranquero2013-07-22 03:25:47 +0200138
c96983ef Kelly Dean2015-02-09 13:25:53 +0000139(defvar desktop-file-version "208"
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000140 "Version number of desktop file format.
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000141Written into the desktop file and used at desktop read to provide
142backward compatibility.")
143
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +0000144;; ----------------------------------------------------------------------------
0b9bd504
RS
Richard M. Stallman1993-10-07 16:50:26 +0000145;; USER OPTIONS -- settings you might want to play with.
146;; ----------------------------------------------------------------------------
bbf5eb28
RS
Richard M. Stallman1997-04-12 03:18:33 +0000147
148(defgroup desktop nil
149 "Save status of Emacs when you exit."
150 :group 'frames)
151
e5bd0a28
SM
Stefan Monnier2012-05-12 23:05:06 -0400152;; Maintained for backward compatibility
153(define-obsolete-variable-alias 'desktop-enable 'desktop-save-mode "22.1")
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +0000154;;;###autoload
155(define-minor-mode desktop-save-mode
06e21633 Chong Yidong2011-10-19 08:54:24 -0400156 "Toggle desktop saving (Desktop Save mode).
c863b6ad
GM
Glenn Morris2014-02-17 17:33:30 -0800157With a prefix argument ARG, enable Desktop Save mode if ARG is positive,
158and disable it otherwise. If called from Lisp, enable the mode if ARG
159is omitted or nil.
06e21633 Chong Yidong2011-10-19 08:54:24 -0400160
c863b6ad
GM
Glenn Morris2014-02-17 17:33:30 -0800161When Desktop Save mode is enabled, the state of Emacs is saved from
162one session to another. In particular, Emacs will save the desktop when
163it exits (this may prompt you; see the option `desktop-save'). The next
164time Emacs starts, if this mode is active it will restore the desktop.
165
166To manually save the desktop at any time, use the command `M-x desktop-save'.
167To load it, use `M-x desktop-read'.
168
169Once a desktop file exists, Emacs will auto-save it according to the
170option `desktop-auto-save-timeout'.
171
172To see all the options you can set, browse the `desktop' customization group.
173
174For further details, see info node `(emacs)Saving Emacs Sessions'."
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000175 :global t
2b777cd9
JL
Juri Linkov2014-02-07 09:44:29 +0200176 :group 'desktop
177 (if desktop-save-mode
a4d8b73e
JL
Juri Linkov2014-06-25 02:23:41 +0300178 (desktop-auto-save-enable)
179 (desktop-auto-save-disable)))
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000180
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000181(defun desktop-save-mode-off ()
182 "Disable `desktop-save-mode'. Provided for use in hooks."
183 (desktop-save-mode 0))
184
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000185(defcustom desktop-save 'ask-if-new
9201cc28 Lute Kamstra2008-12-03 05:48:14 +0000186 "Specifies whether the desktop should be saved when it is killed.
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +0000187A desktop is killed when the user changes desktop or quits Emacs.
188Possible values are:
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000189 t -- always save.
190 ask -- always ask.
191 ask-if-new -- ask if no desktop file exists, otherwise just save.
192 ask-if-exists -- ask if desktop file exists, otherwise don't save.
193 if-exists -- save if desktop file exists, otherwise don't save.
194 nil -- never save.
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000195The desktop is never saved when `desktop-save-mode' is nil.
cc8b76bf Juanma Barranquero2005-07-19 09:54:05 +0000196The variables `desktop-dirname' and `desktop-base-file-name'
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000197determine where the desktop is saved."
11425834
LH
Lars Hansen2006-06-23 21:42:33 +0000198 :type
199 '(choice
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000200 (const :tag "Always save" t)
201 (const :tag "Always ask" ask)
202 (const :tag "Ask if desktop file is new, else do save" ask-if-new)
203 (const :tag "Ask if desktop file exists, else don't save" ask-if-exists)
204 (const :tag "Save if desktop file exists, else don't" if-exists)
205 (const :tag "Never save" nil))
af61551b Lars Hansen2004-11-11 19:02:56 +0000206 :group 'desktop
bf247b6e Kim F. Storm2005-02-09 15:50:47 +0000207 :version "22.1")
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000208
6c8e0ae6
JL
Juri Linkov2013-12-16 23:48:51 +0200209(defcustom desktop-auto-save-timeout auto-save-timeout
210 "Number of seconds idle time before auto-save of the desktop.
7f118009 Juri Linkov2014-06-07 02:38:40 +0300211The idle timer activates auto-saving only when window configuration changes.
c863b6ad Glenn Morris2014-02-17 17:33:30 -0800212This applies to an existing desktop file when `desktop-save-mode' is enabled.
6c8e0ae6 Juri Linkov2013-12-16 23:48:51 +0200213Zero or nil means disable auto-saving due to idleness."
5db9dace
JL
Juri Linkov2013-04-27 23:55:00 +0300214 :type '(choice (const :tag "Off" nil)
215 (integer :tag "Seconds"))
216 :set (lambda (symbol value)
217 (set-default symbol value)
7f118009
JL
Juri Linkov2014-06-07 02:38:40 +0300218 (ignore-errors
219 (if (and (integerp value) (> value 0))
a4d8b73e
JL
Juri Linkov2014-06-25 02:23:41 +0300220 (desktop-auto-save-enable value)
221 (desktop-auto-save-disable))))
5db9dace
JL
Juri Linkov2013-04-27 23:55:00 +0300222 :group 'desktop
223 :version "24.4")
224
1f7efe1b
JB
Juanma Barranquero2007-06-12 11:14:52 +0000225(defcustom desktop-load-locked-desktop 'ask
226 "Specifies whether the desktop should be loaded if locked.
227Possible values are:
228 t -- load anyway.
229 nil -- don't load.
230 ask -- ask the user.
231If the value is nil, or `ask' and the user chooses not to load the desktop,
232the normal hook `desktop-not-loaded-hook' is run."
233 :type
234 '(choice
235 (const :tag "Load anyway" t)
236 (const :tag "Don't load" nil)
237 (const :tag "Ask the user" ask))
238 :group 'desktop
8f3f313d Juanma Barranquero2007-10-27 17:14:37 +0000239 :version "22.2")
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000240
cd6ef82d
GM
Glenn Morris2008-04-12 03:17:19 +0000241(define-obsolete-variable-alias 'desktop-basefilename
242 'desktop-base-file-name "22.1")
243
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000244(defcustom desktop-base-file-name
fc715501 Richard M. Stallman1996-09-01 19:04:28 +0000245 (convert-standard-filename ".emacs.desktop")
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000246 "Name of file for Emacs desktop, excluding the directory part."
813dbb2d
RS
Richard M. Stallman1997-12-29 20:58:19 +0000247 :type 'file
248 :group 'desktop)
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +0000249
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000250(defcustom desktop-base-lock-name
251 (convert-standard-filename ".emacs.desktop.lock")
252 "Name of lock file for Emacs desktop, excluding the directory part."
253 :type 'file
254 :group 'desktop
8f3f313d Juanma Barranquero2007-10-27 17:14:37 +0000255 :version "22.2")
e88110db Juanma Barranquero2007-06-12 09:11:31 +0000256
e76f0800 Chong Yidong2012-06-21 15:15:42 +0800257(defcustom desktop-path (list user-emacs-directory "~")
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000258 "List of directories to search for the desktop file.
259The base name of the file is specified in `desktop-base-file-name'."
260 :type '(repeat directory)
af61551b Lars Hansen2004-11-11 19:02:56 +0000261 :group 'desktop
a3b337cd Glenn Morris2010-09-01 22:38:30 -0700262 :version "23.2") ; user-emacs-directory added
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000263
bbf5eb28 Richard M. Stallman1997-04-12 03:18:33 +0000264(defcustom desktop-missing-file-warning nil
6c27fdb9 Lars Hansen2006-05-14 20:26:37 +0000265 "If non-nil, offer to recreate the buffer of a deleted file.
ebb39555
LH
Lars Hansen2004-04-26 18:58:19 +0000266Also pause for a moment to display message about errors signaled in
267`desktop-buffer-mode-handlers'.
268
269If nil, just print error messages in the message buffer."
bbf5eb28 Richard M. Stallman1997-04-12 03:18:33 +0000270 :type 'boolean
af61551b Lars Hansen2004-11-11 19:02:56 +0000271 :group 'desktop
bf247b6e Kim F. Storm2005-02-09 15:50:47 +0000272 :version "22.1")
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +0000273
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000274(defcustom desktop-no-desktop-file-hook nil
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000275 "Normal hook run when `desktop-read' can't find a desktop file.
11425834 Lars Hansen2006-06-23 21:42:33 +0000276Run in the directory in which the desktop file was sought.
8649a87b Lute Kamstra2005-04-03 14:01:43 +0000277May be used to show a dired buffer."
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000278 :type 'hook
af61551b Lars Hansen2004-11-11 19:02:56 +0000279 :group 'desktop
bf247b6e Kim F. Storm2005-02-09 15:50:47 +0000280 :version "22.1")
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000281
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000282(defcustom desktop-not-loaded-hook nil
283 "Normal hook run when the user declines to re-use a desktop file.
284Run in the directory in which the desktop file was found.
285May be used to deal with accidental multiple Emacs jobs."
286 :type 'hook
287 :group 'desktop
288 :options '(desktop-save-mode-off save-buffers-kill-emacs)
8f3f313d Juanma Barranquero2007-10-27 17:14:37 +0000289 :version "22.2")
e88110db Juanma Barranquero2007-06-12 09:11:31 +0000290
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000291(defcustom desktop-after-read-hook nil
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000292 "Normal hook run after a successful `desktop-read'.
8649a87b Lute Kamstra2005-04-03 14:01:43 +0000293May be used to show a buffer list."
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000294 :type 'hook
af61551b Lars Hansen2004-11-11 19:02:56 +0000295 :group 'desktop
11425834 Lars Hansen2006-06-23 21:42:33 +0000296 :options '(list-buffers)
bf247b6e Kim F. Storm2005-02-09 15:50:47 +0000297 :version "22.1")
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000298
299(defcustom desktop-save-hook nil
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000300 "Normal hook run before the desktop is saved in a desktop file.
11425834
LH
Lars Hansen2006-06-23 21:42:33 +0000301Run with the desktop buffer current with only the header present.
302May be used to add to the desktop code or to truncate history lists,
303for example."
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000304 :type 'hook
305 :group 'desktop)
306
340db502
LH
Lars Hansen2004-09-09 19:45:03 +0000307(defcustom desktop-globals-to-save
308 '(desktop-missing-file-warning
309 tags-file-name
310 tags-table-list
311 search-ring
312 regexp-search-ring
c760f19e
CY
Chong Yidong2009-07-05 05:14:27 +0000313 register-alist
314 file-name-history)
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +0000315 "List of global variables saved by `desktop-save'.
316An element may be variable name (a symbol) or a cons cell of the form
317\(VAR . MAX-SIZE), which means to truncate VAR's value to at most
318MAX-SIZE elements (if the value is a list) before saving the value.
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000319Feature: Saving `kill-ring' implies saving `kill-ring-yank-pointer'."
320 :type '(repeat (restricted-sexp :match-alternatives (symbolp consp)))
321 :group 'desktop)
322
340db502
LH
Lars Hansen2004-09-09 19:45:03 +0000323(defcustom desktop-globals-to-clear
324 '(kill-ring
325 kill-ring-yank-pointer
326 search-ring
327 search-ring-yank-pointer
328 regexp-search-ring
329 regexp-search-ring-yank-pointer)
150f39ee Lars Hansen2005-01-07 20:18:59 +0000330 "List of global variables that `desktop-clear' will clear.
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000331An element may be variable name (a symbol) or a cons cell of the form
cc8b76bf
JB
Juanma Barranquero2005-07-19 09:54:05 +0000332\(VAR . FORM). Symbols are set to nil and for cons cells VAR is set
333to the value obtained by evaluating FORM."
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000334 :type '(repeat (restricted-sexp :match-alternatives (symbolp consp)))
af61551b Lars Hansen2004-11-11 19:02:56 +0000335 :group 'desktop
bf247b6e Kim F. Storm2005-02-09 15:50:47 +0000336 :version "22.1")
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000337
0f4804e7 Lars Hansen2005-08-10 19:38:52 +0000338(defcustom desktop-clear-preserve-buffers
3845c322
GM
Glenn Morris2010-06-02 23:07:39 -0700339 '("\\*scratch\\*" "\\*Messages\\*" "\\*server\\*" "\\*tramp/.+\\*"
340 "\\*Warnings\\*")
9201cc28 Lute Kamstra2008-12-03 05:48:14 +0000341 "List of buffers that `desktop-clear' should not delete.
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000342Each element is a regular expression. Buffers with a name matched by any of
343these won't be deleted."
3845c322 Glenn Morris2010-06-02 23:07:39 -0700344 :version "23.3" ; added Warnings - bug#6336
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000345 :type '(repeat string)
346 :group 'desktop)
340db502 Lars Hansen2004-09-09 19:45:03 +0000347
0f4804e7 Lars Hansen2005-08-10 19:38:52 +0000348;;;###autoload
340db502
LH
Lars Hansen2004-09-09 19:45:03 +0000349(defcustom desktop-locals-to-save
350 '(desktop-locals-to-save ; Itself! Think it over.
351 truncate-lines
352 case-fold-search
353 case-replace
354 fill-column
355 overwrite-mode
356 change-log-default-name
357 line-number-mode
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000358 column-number-mode
359 size-indication-mode
360 buffer-file-coding-system
361 indent-tabs-mode
11425834 Lars Hansen2006-06-23 21:42:33 +0000362 tab-width
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000363 indicate-buffer-boundaries
364 indicate-empty-lines
365 show-trailing-whitespace)
577ed2b2 Richard M. Stallman1995-01-30 06:14:33 +0000366 "List of local variables to save for each buffer.
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000367The variables are saved only when they really are local. Conventional minor
368modes are restored automatically; they should not be listed here."
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +0000369 :type '(repeat symbol)
370 :group 'desktop)
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +0000371
7d7a68d8 Juri Linkov2014-02-07 09:51:56 +0200372(defcustom desktop-buffers-not-to-save "\\` "
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000373 "Regexp identifying buffers that are to be excluded from saving."
a6c2c80c
EZ
Eli Zaretskii2009-07-18 11:59:04 +0000374 :type '(choice (const :tag "None" nil)
375 regexp)
7d7a68d8 Juri Linkov2014-02-07 09:51:56 +0200376 :version "24.4" ; skip invisible temporary buffers
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000377 :group 'desktop)
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +0000378
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000379;; Skip tramp and ange-ftp files
bbf5eb28 Richard M. Stallman1997-04-12 03:18:33 +0000380(defcustom desktop-files-not-to-save
a6c2c80c Eli Zaretskii2009-07-18 11:59:04 +0000381 "\\(^/[^/:]*:\\|(ftp)$\\)"
bbf5eb28 Richard M. Stallman1997-04-12 03:18:33 +0000382 "Regexp identifying files whose buffers are to be excluded from saving."
a6c2c80c
EZ
Eli Zaretskii2009-07-18 11:59:04 +0000383 :type '(choice (const :tag "None" nil)
384 regexp)
bbf5eb28 Richard M. Stallman1997-04-12 03:18:33 +0000385 :group 'desktop)
fa379636 Karl Heuer1994-05-01 02:07:27 +0000386
df410295
JL
Juri Linkov2005-10-21 08:48:53 +0000387;; We skip TAGS files to save time (tags-file-name is saved instead).
388(defcustom desktop-modes-not-to-save
389 '(tags-table-mode)
80f9f3db
SM
Stefan Monnier2000-10-10 16:42:37 +0000390 "List of major modes whose buffers should not be saved."
391 :type '(repeat symbol)
392 :group 'desktop)
393
b958c0ad Juanma Barranquero2013-07-15 02:07:51 +0200394(defcustom desktop-restore-frames t
46456005
GM
Glenn Morris2014-03-12 00:14:30 -0700395 "When non-nil, save and restore the frame and window configuration.
396See related options `desktop-restore-reuses-frames',
397`desktop-restore-in-current-display', and `desktop-restore-forces-onscreen'."
39c0e36f
JB
Juanma Barranquero2013-06-27 11:08:14 +0200398 :type 'boolean
399 :group 'desktop
400 :version "24.4")
401
2addf922 Juanma Barranquero2013-07-01 05:29:46 +0200402(defcustom desktop-restore-in-current-display nil
46456005
GM
Glenn Morris2014-03-12 00:14:30 -0700403 "Controls how restoring of frames treats displays.
404If t, restores frames into the current display.
405If nil, restores frames into their original displays (if possible).
406If `delete', deletes frames on other displays instead of restoring them."
b958c0ad
JB
Juanma Barranquero2013-07-15 02:07:51 +0200407 :type '(choice (const :tag "Restore in current display" t)
408 (const :tag "Restore in original display" nil)
9c61f806 Glenn Morris2013-12-27 17:24:15 -0800409 (const :tag "Delete frames in other displays" delete))
b958c0ad
JB
Juanma Barranquero2013-07-15 02:07:51 +0200410 :group 'desktop
411 :version "24.4")
412
ddeffb17 Juanma Barranquero2013-07-28 05:03:45 +0200413(defcustom desktop-restore-forces-onscreen t
46456005
GM
Glenn Morris2014-03-12 00:14:30 -0700414 "If t, restores frames that are fully offscreen onscreen instead.
415If `all', also restores frames that are partially offscreen onscreen.
416
417Note that checking of frame boundaries is only approximate.
418It can fail to reliably detect frames whose onscreen/offscreen state
419depends on a few pixels, especially near the right / bottom borders
420of the screen."
ddeffb17 Juanma Barranquero2013-07-28 05:03:45 +0200421 :type '(choice (const :tag "Only fully offscreen frames" t)
4538c058 Juanma Barranquero2014-03-11 01:46:07 +0100422 (const :tag "Also partially offscreen frames" all)
ddeffb17
JB
Juanma Barranquero2013-07-28 05:03:45 +0200423 (const :tag "Do not force frames onscreen" nil))
424 :group 'desktop
425 :version "24.4")
426
9421876d Juanma Barranquero2013-08-02 06:33:58 +0200427(defcustom desktop-restore-reuses-frames t
b958c0ad Juanma Barranquero2013-07-15 02:07:51 +0200428 "If t, restoring frames reuses existing frames.
46456005
GM
Glenn Morris2014-03-12 00:14:30 -0700429If nil, deletes existing frames.
430If `keep', keeps existing frames and does not reuse them."
b958c0ad
JB
Juanma Barranquero2013-07-15 02:07:51 +0200431 :type '(choice (const :tag "Reuse existing frames" t)
432 (const :tag "Delete existing frames" nil)
d5671a82 Juanma Barranquero2013-08-05 00:12:18 +0200433 (const :tag "Keep existing frames" :keep))
2addf922
JB
Juanma Barranquero2013-07-01 05:29:46 +0200434 :group 'desktop
435 :version "24.4")
436
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000437(defcustom desktop-file-name-format 'absolute
9201cc28 Lute Kamstra2008-12-03 05:48:14 +0000438 "Format in which desktop file names should be saved.
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000439Possible values are:
440 absolute -- Absolute file name.
441 tilde -- Relative to ~.
442 local -- Relative to directory of desktop file."
443 :type '(choice (const absolute) (const tilde) (const local))
af61551b Lars Hansen2004-11-11 19:02:56 +0000444 :group 'desktop
bf247b6e Kim F. Storm2005-02-09 15:50:47 +0000445 :version "22.1")
569c754e Richard M. Stallman1996-03-05 16:37:03 +0000446
150f39ee
LH
Lars Hansen2005-01-07 20:18:59 +0000447(defcustom desktop-restore-eager t
448 "Number of buffers to restore immediately.
449Remaining buffers are restored lazily (when Emacs is idle).
450If value is t, all buffers are restored immediately."
0ba9bc53 David Kastrup2005-01-09 13:31:53 +0000451 :type '(choice (const t) integer)
150f39ee Lars Hansen2005-01-07 20:18:59 +0000452 :group 'desktop
bf247b6e Kim F. Storm2005-02-09 15:50:47 +0000453 :version "22.1")
150f39ee
LH
Lars Hansen2005-01-07 20:18:59 +0000454
455(defcustom desktop-lazy-verbose t
456 "Verbose reporting of lazily created buffers."
457 :type 'boolean
458 :group 'desktop
bf247b6e Kim F. Storm2005-02-09 15:50:47 +0000459 :version "22.1")
150f39ee
LH
Lars Hansen2005-01-07 20:18:59 +0000460
461(defcustom desktop-lazy-idle-delay 5
462 "Idle delay before starting to create buffers.
463See `desktop-restore-eager'."
464 :type 'integer
465 :group 'desktop
bf247b6e Kim F. Storm2005-02-09 15:50:47 +0000466 :version "22.1")
150f39ee Lars Hansen2005-01-07 20:18:59 +0000467
e5780ae1 Lars Hansen2004-04-21 20:53:35 +0000468;;;###autoload
acfcc8c5 Juanma Barranquero2013-07-12 13:21:01 +0200469(defvar-local desktop-save-buffer nil
ebb39555 Lars Hansen2004-04-26 18:58:19 +0000470 "When non-nil, save buffer status in desktop file.
ebb39555 Lars Hansen2004-04-26 18:58:19 +0000471
b89c5a72
JB
Juanma Barranquero2005-07-29 10:25:15 +0000472If the value is a function, it is called by `desktop-save' with argument
473DESKTOP-DIRNAME to obtain auxiliary information to save in the desktop
ebb39555 Lars Hansen2004-04-26 18:58:19 +0000474file along with the state of the buffer for which it was called.
b6b70cda John Wiegley2000-10-13 09:11:16 +0000475
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000476When file names are returned, they should be formatted using the call
e5780ae1 Lars Hansen2004-04-21 20:53:35 +0000477\"(desktop-file-name FILE-NAME DESKTOP-DIRNAME)\".
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000478
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000479Later, when `desktop-read' evaluates the desktop file, auxiliary information
480is passed as the argument DESKTOP-BUFFER-MISC to functions in
481`desktop-buffer-mode-handlers'.")
ebb39555 Lars Hansen2004-04-26 18:58:19 +0000482(make-obsolete-variable 'desktop-buffer-modes-to-save
cc8b76bf Juanma Barranquero2005-07-19 09:54:05 +0000483 'desktop-save-buffer "22.1")
e5780ae1 Lars Hansen2004-04-21 20:53:35 +0000484(make-obsolete-variable 'desktop-buffer-misc-functions
cc8b76bf Juanma Barranquero2005-07-19 09:54:05 +0000485 'desktop-save-buffer "22.1")
b6b70cda John Wiegley2000-10-13 09:11:16 +0000486
0f4804e7 Lars Hansen2005-08-10 19:38:52 +0000487;;;###autoload
e76f0800 Chong Yidong2012-06-21 15:15:42 +0800488(defvar desktop-buffer-mode-handlers nil
e5780ae1 Lars Hansen2004-04-21 20:53:35 +0000489 "Alist of major mode specific functions to restore a desktop buffer.
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000490Functions listed are called by `desktop-create-buffer' when `desktop-read'
491evaluates the desktop file. List elements must have the form
492
493 (MAJOR-MODE . RESTORE-BUFFER-FUNCTION).
e5780ae1
LH
Lars Hansen2004-04-21 20:53:35 +0000494
495Buffers with a major mode not specified here, are restored by the default
496handler `desktop-restore-file-buffer'.
497
55775448 Lars Hansen2004-05-07 17:58:24 +0000498Handlers are called with argument list
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000499
9bcabb45 Lars Hansen2004-05-07 19:41:11 +0000500 (DESKTOP-BUFFER-FILE-NAME DESKTOP-BUFFER-NAME DESKTOP-BUFFER-MISC)
e5780ae1
LH
Lars Hansen2004-04-21 20:53:35 +0000501
502Furthermore, they may use the following variables:
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000503
ca70fe78
SM
Stefan Monnier2014-03-09 22:18:29 -0400504 `desktop-file-version'
505 `desktop-buffer-major-mode'
506 `desktop-buffer-minor-modes'
507 `desktop-buffer-point'
508 `desktop-buffer-mark'
509 `desktop-buffer-read-only'
510 `desktop-buffer-locals'
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000511
e5780ae1 Lars Hansen2004-04-21 20:53:35 +0000512If a handler returns a buffer, then the saved mode settings
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000513and variable values for that buffer are copied into it.
514
515Modules that define a major mode that needs a special handler should contain
516code like
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +0000517
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000518 (defun foo-restore-desktop-buffer
519 ...
520 (add-to-list 'desktop-buffer-mode-handlers
521 '(foo-mode . foo-restore-desktop-buffer))
522
523Furthermore the major mode function must be autoloaded.")
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +0000524
498eb267 Andreas Schwab2005-08-14 23:55:03 +0000525;;;###autoload
e5780ae1
LH
Lars Hansen2004-04-21 20:53:35 +0000526(put 'desktop-buffer-mode-handlers 'risky-local-variable t)
527(make-obsolete-variable 'desktop-buffer-handlers
cc8b76bf Juanma Barranquero2005-07-19 09:54:05 +0000528 'desktop-buffer-mode-handlers "22.1")
b6b70cda John Wiegley2000-10-13 09:11:16 +0000529
47640244
GM
Gerd Moellmann2000-04-26 17:33:02 +0000530(defcustom desktop-minor-mode-table
531 '((auto-fill-function auto-fill-mode)
8abe2042
JL
Juri Linkov2014-07-04 02:48:24 +0300532 (defining-kbd-macro nil)
533 (isearch-mode nil)
5fff0265 Juri Linkov2005-12-14 07:44:44 +0000534 (vc-mode nil)
f2168a4c Michael Olson2007-10-30 00:50:07 +0000535 (vc-dired-mode nil)
fb8a6326
JB
Juanma Barranquero2008-04-28 08:06:51 +0000536 (erc-track-minor-mode nil)
537 (savehist-mode nil))
47640244
GM
Gerd Moellmann2000-04-26 17:33:02 +0000538 "Table mapping minor mode variables to minor mode functions.
539Each entry has the form (NAME RESTORE-FUNCTION).
540NAME is the name of the buffer-local variable indicating that the minor
541mode is active. RESTORE-FUNCTION is the function to activate the minor mode.
7d6ee4df Juanma Barranquero2007-06-09 00:09:03 +0000542RESTORE-FUNCTION nil means don't try to restore the minor mode.
47640244 Gerd Moellmann2000-04-26 17:33:02 +0000543Only minor modes for which the name of the buffer-local variable
7bfa55b3 Lars Hansen2004-05-31 21:45:51 +0000544and the name of the minor mode function are different have to be added to
0f4804e7 Lars Hansen2005-08-10 19:38:52 +0000545this table. See also `desktop-minor-mode-handlers'."
47640244
GM
Gerd Moellmann2000-04-26 17:33:02 +0000546 :type 'sexp
547 :group 'desktop)
548
0f4804e7 Lars Hansen2005-08-10 19:38:52 +0000549;;;###autoload
e76f0800 Chong Yidong2012-06-21 15:15:42 +0800550(defvar desktop-minor-mode-handlers nil
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000551 "Alist of functions to restore non-standard minor modes.
552Functions are called by `desktop-create-buffer' to restore minor modes.
553List elements must have the form
554
555 (MINOR-MODE . RESTORE-FUNCTION).
556
557Minor modes not specified here, are restored by the standard minor mode
558function.
559
560Handlers are called with argument list
561
562 (DESKTOP-BUFFER-LOCALS)
563
564Furthermore, they may use the following variables:
565
ca70fe78
SM
Stefan Monnier2014-03-09 22:18:29 -0400566 `desktop-file-version'
567 `desktop-buffer-file-name'
568 `desktop-buffer-name'
569 `desktop-buffer-major-mode'
570 `desktop-buffer-minor-modes'
571 `desktop-buffer-point'
572 `desktop-buffer-mark'
573 `desktop-buffer-read-only'
574 `desktop-buffer-misc'
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000575
576When a handler is called, the buffer has been created and the major mode has
577been set, but local variables listed in desktop-buffer-locals has not yet been
578created and set.
579
580Modules that define a minor mode that needs a special handler should contain
581code like
582
583 (defun foo-desktop-restore
584 ...
585 (add-to-list 'desktop-minor-mode-handlers
586 '(foo-mode . foo-desktop-restore))
587
588Furthermore the minor mode function must be autoloaded.
589
590See also `desktop-minor-mode-table'.")
591
498eb267 Andreas Schwab2005-08-14 23:55:03 +0000592;;;###autoload
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000593(put 'desktop-minor-mode-handlers 'risky-local-variable t)
594
0b9bd504
RS
Richard M. Stallman1993-10-07 16:50:26 +0000595;; ----------------------------------------------------------------------------
596(defvar desktop-dirname nil
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000597 "The directory in which the desktop file should be saved.")
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +0000598
11425834
LH
Lars Hansen2006-06-23 21:42:33 +0000599(defun desktop-full-file-name (&optional dirname)
600 "Return the full name of the desktop file in DIRNAME.
601DIRNAME omitted or nil means use `desktop-dirname'."
602 (expand-file-name desktop-base-file-name (or dirname desktop-dirname)))
603
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000604(defun desktop-full-lock-name (&optional dirname)
605 "Return the full name of the desktop lock file in DIRNAME.
606DIRNAME omitted or nil means use `desktop-dirname'."
607 (expand-file-name desktop-base-lock-name (or dirname desktop-dirname)))
608
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +0000609(defconst desktop-header
0b9bd504
RS
Richard M. Stallman1993-10-07 16:50:26 +0000610";; --------------------------------------------------------------------------
611;; Desktop File for Emacs
612;; --------------------------------------------------------------------------
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +0000613" "*Header to place in Desktop file.")
de9e2828
RS
Richard M. Stallman1994-02-05 02:23:44 +0000614
615(defvar desktop-delay-hook nil
616 "Hooks run after all buffers are loaded; intended for internal use.")
813dbb2d Richard M. Stallman1997-12-29 20:58:19 +0000617
5db9dace
JL
Juri Linkov2013-04-27 23:55:00 +0300618(defvar desktop-file-checksum nil
619 "Checksum of the last auto-saved contents of the desktop file.
620Used to avoid writing contents unchanged between auto-saves.")
621
9421876d Juanma Barranquero2013-08-02 06:33:58 +0200622(defvar desktop-saved-frameset nil
56bc453c
JB
Juanma Barranquero2013-07-21 19:45:12 +0200623 "Saved state of all frames.
624Only valid during frame saving & restoring; intended for internal use.")
39c0e36f Juanma Barranquero2013-06-27 11:08:14 +0200625
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +0000626;; ----------------------------------------------------------------------------
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000627;; Desktop file conflict detection
628(defvar desktop-file-modtime nil
629 "When the desktop file was last modified to the knowledge of this Emacs.
630Used to detect desktop file conflicts.")
631
c96983ef
KD
Kelly Dean2015-02-09 13:25:53 +0000632(defvar desktop-var-serdes-funs
633 (list (list
634 'mark-ring
635 (lambda (mr)
636 (mapcar #'marker-position mr))
637 (lambda (mr)
638 (mapcar #'copy-marker mr))))
639 "Table of serialization/deserialization functions for variables.
640Each record is a list of form: (var serializer deserializer).
641These records can be freely reordered, deleted, or new ones added.
642However, for compatibility, don't modify the functions for existing records.")
643
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000644(defun desktop-owner (&optional dirname)
645 "Return the PID of the Emacs process that owns the desktop file in DIRNAME.
646Return nil if no desktop file found or no Emacs process is using it.
647DIRNAME omitted or nil means use `desktop-dirname'."
acfcc8c5
JB
Juanma Barranquero2013-07-12 13:21:01 +0200648 (let (owner
649 (file (desktop-full-lock-name dirname)))
650 (and (file-exists-p file)
651 (ignore-errors
652 (with-temp-buffer
653 (insert-file-contents-literally file)
654 (goto-char (point-min))
655 (setq owner (read (current-buffer)))
656 (integerp owner)))
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000657 owner)))
658
659(defun desktop-claim-lock (&optional dirname)
660 "Record this Emacs process as the owner of the desktop file in DIRNAME.
661DIRNAME omitted or nil means use `desktop-dirname'."
662 (write-region (number-to-string (emacs-pid)) nil
663 (desktop-full-lock-name dirname)))
664
665(defun desktop-release-lock (&optional dirname)
666 "Remove the lock file for the desktop in DIRNAME.
667DIRNAME omitted or nil means use `desktop-dirname'."
668 (let ((file (desktop-full-lock-name dirname)))
669 (when (file-exists-p file) (delete-file file))))
670
671;; ----------------------------------------------------------------------------
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000672(defun desktop-truncate (list n)
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +0000673 "Truncate LIST to at most N elements destructively."
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000674 (let ((here (nthcdr (1- n) list)))
1f7efe1b
JB
Juanma Barranquero2007-06-12 11:14:52 +0000675 (when (consp here)
676 (setcdr here nil))))
f9be4574 Richard M. Stallman1997-07-04 00:13:36 +0000677
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000678;; ----------------------------------------------------------------------------
11425834 Lars Hansen2006-06-23 21:42:33 +0000679;;;###autoload
f9be4574
RS
Richard M. Stallman1997-07-04 00:13:36 +0000680(defun desktop-clear ()
681 "Empty the Desktop.
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000682This kills all buffers except for internal ones and those with names matched by
683a regular expression in the list `desktop-clear-preserve-buffers'.
5414a283
JB
Juanma Barranquero2013-08-04 02:31:33 +0200684Furthermore, it clears the variables listed in `desktop-globals-to-clear'.
685When called interactively and `desktop-restore-frames' is non-nil, it also
686deletes all frames except the selected one (and its minibuffer frame,
687if different)."
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +0000688 (interactive)
150f39ee Lars Hansen2005-01-07 20:18:59 +0000689 (desktop-lazy-abort)
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000690 (dolist (var desktop-globals-to-clear)
691 (if (symbolp var)
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000692 (eval `(setq-default ,var nil))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000693 (eval `(setq-default ,(car var) ,(cdr var)))))
b61d71e4 Juanma Barranquero2013-07-23 03:10:54 +0200694 (let ((preserve-regexp (concat "^\\("
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +0000695 (mapconcat (lambda (regexp)
696 (concat "\\(" regexp "\\)"))
697 desktop-clear-preserve-buffers
698 "\\|")
699 "\\)$")))
b61d71e4
JB
Juanma Barranquero2013-07-23 03:10:54 +0200700 (dolist (buffer (buffer-list))
701 (let ((bufname (buffer-name buffer)))
da77a2e2 Juanma Barranquero2013-07-24 01:10:58 +0200702 (unless (or (eq (aref bufname 0) ?\s) ;; Don't kill internal buffers
b61d71e4
JB
Juanma Barranquero2013-07-23 03:10:54 +0200703 (string-match-p preserve-regexp bufname))
704 (kill-buffer buffer)))))
9421876d Juanma Barranquero2013-08-02 06:33:58 +0200705 (delete-other-windows)
5414a283
JB
Juanma Barranquero2013-08-04 02:31:33 +0200706 (when (and desktop-restore-frames
707 ;; Non-interactive calls to desktop-clear happen before desktop-read
708 ;; which already takes care of frame restoration and deletion.
709 (called-interactively-p 'any))
710 (let* ((this (selected-frame))
526e5233 Paul Eggert2013-08-15 22:15:51 -0700711 (mini (window-frame (minibuffer-window this)))) ; in case they differ
063233c3 Juanma Barranquero2013-08-05 06:45:17 +0200712 (dolist (frame (sort (frame-list) #'frameset-minibufferless-first-p))
5414a283
JB
Juanma Barranquero2013-08-04 02:31:33 +0200713 (condition-case err
714 (unless (or (eq frame this)
715 (eq frame mini)
716 (frame-parameter frame 'desktop-dont-clear))
717 (delete-frame frame))
718 (error
4538c058 Juanma Barranquero2014-03-11 01:46:07 +0100719 (delay-warning 'desktop (error-message-string err))))))))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000720
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +0000721;; ----------------------------------------------------------------------------
845fc5e5
JB
Juanma Barranquero2011-03-06 01:30:16 +0100722(unless noninteractive
723 (add-hook 'kill-emacs-hook 'desktop-kill))
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +0000724
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +0000725(defun desktop-kill ()
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000726 "If `desktop-save-mode' is non-nil, do what `desktop-save' says to do.
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000727If the desktop should be saved and `desktop-dirname'
728is nil, ask the user where to save the desktop."
11425834
LH
Lars Hansen2006-06-23 21:42:33 +0000729 (when (and desktop-save-mode
730 (let ((exists (file-exists-p (desktop-full-file-name))))
731 (or (eq desktop-save t)
7dd7fbb9
JD
Jan Djärv2010-04-27 08:45:43 +0200732 (and exists (eq desktop-save 'if-exists))
733 ;; If it exists, but we aren't using it, we are going
734 ;; to ask for a new directory below.
735 (and exists desktop-dirname (eq desktop-save 'ask-if-new))
11425834
LH
Lars Hansen2006-06-23 21:42:33 +0000736 (and
737 (or (memq desktop-save '(ask ask-if-new))
738 (and exists (eq desktop-save 'ask-if-exists)))
739 (y-or-n-p "Save desktop? ")))))
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000740 (unless desktop-dirname
741 (setq desktop-dirname
11425834
LH
Lars Hansen2006-06-23 21:42:33 +0000742 (file-name-as-directory
743 (expand-file-name
794855ca Juanma Barranquero2007-06-20 10:12:44 +0000744 (read-directory-name "Directory for desktop file: " nil nil t)))))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000745 (condition-case err
e88110db Juanma Barranquero2007-06-12 09:11:31 +0000746 (desktop-save desktop-dirname t)
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000747 (file-error
11425834 Lars Hansen2006-06-23 21:42:33 +0000748 (unless (yes-or-no-p "Error while saving the desktop. Ignore? ")
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000749 (signal (car err) (cdr err))))))
750 ;; If we own it, we don't anymore.
751 (when (eq (emacs-pid) (desktop-owner)) (desktop-release-lock)))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000752
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +0000753;; ----------------------------------------------------------------------------
ed2f7fc8 Richard M. Stallman1996-03-05 04:22:44 +0000754(defun desktop-list* (&rest args)
74d7f75a Juanma Barranquero2013-07-23 13:29:30 +0200755 (and args (apply #'cl-list* args)))
ed2f7fc8 Richard M. Stallman1996-03-05 04:22:44 +0000756
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000757;; ----------------------------------------------------------------------------
e88110db Juanma Barranquero2007-06-12 09:11:31 +0000758(defun desktop-buffer-info (buffer)
6065fbe0
AM
Artur Malabarba2015-03-05 13:37:23 +0000759 "Return information describing BUFFER.
760This function is not pure, as BUFFER is made current with
761`set-buffer'.
762
763Returns a list of all the necessary information to recreate the
764buffer, which is (in order):
765
766 `uniquify-buffer-base-name';
767 `buffer-file-name';
768 `buffer-name';
769 `major-mode';
770 list of minor-modes,;
771 `point';
772 `mark';
773 `buffer-read-only';
774 auxiliary information given by `desktop-save-buffer';
775 local variables;
776 auxiliary information given by `desktop-var-serdes-funs'."
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000777 (set-buffer buffer)
778 (list
a8049a30
JB
Juanma Barranquero2008-02-14 14:37:00 +0000779 ;; base name of the buffer; replaces the buffer name if managed by uniquify
780 (and (fboundp 'uniquify-buffer-base-name) (uniquify-buffer-base-name))
e88110db Juanma Barranquero2007-06-12 09:11:31 +0000781 ;; basic information
9e29c91c Juanma Barranquero2007-07-12 22:40:00 +0000782 (desktop-file-name (buffer-file-name) desktop-dirname)
a8049a30 Juanma Barranquero2008-02-14 14:37:00 +0000783 (buffer-name)
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000784 major-mode
785 ;; minor modes
786 (let (ret)
61e06b6c
AM
Artur Malabarba2015-03-05 13:43:27 +0000787 (dolist (minor-mode (mapcar #'car minor-mode-alist) ret)
788 (and (boundp minor-mode)
789 (symbol-value minor-mode)
790 (let* ((special (assq minor-mode desktop-minor-mode-table))
791 (value (cond (special (cadr special))
792 ((functionp minor-mode) minor-mode))))
793 (when value (cl-pushnew value ret))))))
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000794 ;; point and mark, and read-only status
795 (point)
796 (list (mark t) mark-active)
797 buffer-read-only
798 ;; auxiliary information
799 (when (functionp desktop-save-buffer)
9e29c91c Juanma Barranquero2007-07-12 22:40:00 +0000800 (funcall desktop-save-buffer desktop-dirname))
e88110db Juanma Barranquero2007-06-12 09:11:31 +0000801 ;; local variables
b61d71e4
JB
Juanma Barranquero2013-07-23 03:10:54 +0200802 (let ((loclist (buffer-local-variables))
803 (ll nil))
804 (dolist (local desktop-locals-to-save)
805 (let ((here (assq local loclist)))
806 (cond (here
807 (push here ll))
808 ((member local loclist)
809 (push local ll)))))
c96983ef
KD
Kelly Dean2015-02-09 13:25:53 +0000810 ll)
811 (mapcar (lambda (record)
812 (let ((var (car record)))
813 (list var
814 (funcall (cadr record) (symbol-value var)))))
815 desktop-var-serdes-funs)))
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000816
817;; ----------------------------------------------------------------------------
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400818(defun desktop--v2s (value)
819 "Convert VALUE to a pair (QUOTE . SEXP); (eval SEXP) gives VALUE.
820SEXP is an sexp that when evaluated yields VALUE.
577ed2b2 Richard M. Stallman1995-01-30 06:14:33 +0000821QUOTE may be `may' (value may be quoted),
60ff536c Juanma Barranquero2011-12-23 01:44:27 +0100822`must' (value must be quoted), or nil (value must not be quoted)."
de9e2828 Richard M. Stallman1994-02-05 02:23:44 +0000823 (cond
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000824 ((or (numberp value) (null value) (eq t value) (keywordp value))
69b2c07e Stefan Monnier2013-03-25 23:38:18 -0400825 (cons 'may value))
1f7efe1b
JB
Juanma Barranquero2007-06-12 11:14:52 +0000826 ((stringp value)
827 (let ((copy (copy-sequence value)))
828 (set-text-properties 0 (length copy) nil copy)
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400829 ;; Get rid of text properties because we cannot read them.
830 (cons 'may copy)))
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000831 ((symbolp value)
69b2c07e Stefan Monnier2013-03-25 23:38:18 -0400832 (cons 'must value))
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000833 ((vectorp value)
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400834 (let* ((pass1 (mapcar #'desktop--v2s value))
835 (special (assq nil pass1)))
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000836 (if special
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400837 (cons nil `(vector
838 ,@(mapcar (lambda (el)
839 (if (eq (car el) 'must)
840 `',(cdr el) (cdr el)))
841 pass1)))
842 (cons 'may `[,@(mapcar #'cdr pass1)]))))
1f7efe1b
JB
Juanma Barranquero2007-06-12 11:14:52 +0000843 ((consp value)
844 (let ((p value)
845 newlist
acfcc8c5 Juanma Barranquero2013-07-12 13:21:01 +0200846 use-list*)
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000847 (while (consp p)
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400848 (let ((q.sexp (desktop--v2s (car p))))
849 (push q.sexp newlist))
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000850 (setq p (cdr p)))
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400851 (when p
852 (let ((last (desktop--v2s p)))
853 (setq use-list* t)
854 (push last newlist)))
855 (if (assq nil newlist)
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000856 (cons nil
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400857 `(,(if use-list* 'desktop-list* 'list)
858 ,@(mapcar (lambda (el)
859 (if (eq (car el) 'must)
860 `',(cdr el) (cdr el)))
861 (nreverse newlist))))
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000862 (cons 'must
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400863 `(,@(mapcar #'cdr
864 (nreverse (if use-list* (cdr newlist) newlist)))
865 ,@(if use-list* (cdar newlist)))))))
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000866 ((subrp value)
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400867 (cons nil `(symbol-function
868 ',(intern-soft (substring (prin1-to-string value) 7 -1)))))
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +0000869 ((markerp value)
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400870 (let ((pos (marker-position value))
871 (buf (buffer-name (marker-buffer value))))
872 (cons nil
873 `(let ((mk (make-marker)))
874 (add-hook 'desktop-delay-hook
875 `(lambda ()
876 (set-marker ,mk ,,pos (get-buffer ,,buf))))
877 mk))))
878 (t ; Save as text.
879 (cons 'may "Unprintable entity"))))
de9e2828 Richard M. Stallman1994-02-05 02:23:44 +0000880
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000881;; ----------------------------------------------------------------------------
6b61353c Kenichi Handa2004-04-16 12:51:06 +0000882(defun desktop-value-to-string (value)
577ed2b2
RS
Richard M. Stallman1995-01-30 06:14:33 +0000883 "Convert VALUE to a string that when read evaluates to the same value.
884Not all types of values are supported."
de9e2828 Richard M. Stallman1994-02-05 02:23:44 +0000885 (let* ((print-escape-newlines t)
8e554df0
JL
Juri Linkov2014-04-27 11:22:11 +0300886 (print-length nil)
887 (print-level nil)
de9e2828 Richard M. Stallman1994-02-05 02:23:44 +0000888 (float-output-format nil)
69b2c07e
SM
Stefan Monnier2013-03-25 23:38:18 -0400889 (quote.sexp (desktop--v2s value))
890 (quote (car quote.sexp))
8e554df0
JL
Juri Linkov2014-04-27 11:22:11 +0300891 (print-quoted t)
892 (txt (prin1-to-string (cdr quote.sexp))))
de9e2828
RS
Richard M. Stallman1994-02-05 02:23:44 +0000893 (if (eq quote 'must)
894 (concat "'" txt)
895 txt)))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000896
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +0000897;; ----------------------------------------------------------------------------
0e7c8611
RS
Richard M. Stallman1995-10-08 19:37:04 +0000898(defun desktop-outvar (varspec)
899 "Output a setq statement for variable VAR to the desktop file.
900The argument VARSPEC may be the variable name VAR (a symbol),
be617bbf Juanma Barranquero2006-02-10 11:07:50 +0000901or a cons cell of the form (VAR . MAX-SIZE),
0e7c8611
RS
Richard M. Stallman1995-10-08 19:37:04 +0000902which means to truncate VAR's value to at most MAX-SIZE elements
903\(if the value is a list) before saving the value."
904 (let (var size)
905 (if (consp varspec)
906 (setq var (car varspec) size (cdr varspec))
907 (setq var varspec))
1f7efe1b
JB
Juanma Barranquero2007-06-12 11:14:52 +0000908 (when (boundp var)
909 (when (and (integerp size)
910 (> size 0)
911 (listp (eval var)))
912 (desktop-truncate (eval var) size))
913 (insert "(setq "
914 (symbol-name var)
915 " "
916 (desktop-value-to-string (symbol-value var))
917 ")\n"))))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000918
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +0000919;; ----------------------------------------------------------------------------
06b60517 Juanma Barranquero2011-04-19 15:44:55 +0200920(defun desktop-save-buffer-p (filename bufname mode &rest _dummy)
ebb39555 Lars Hansen2004-04-26 18:58:19 +0000921 "Return t if buffer should have its state saved in the desktop file.
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +0000922FILENAME is the visited file name, BUFNAME is the buffer name, and
be617bbf
JB
Juanma Barranquero2006-02-10 11:07:50 +0000923MODE is the major mode.
924\n\(fn FILENAME BUFNAME MODE)"
b23caf75 Glenn Morris2010-03-24 23:18:17 -0700925 (let ((case-fold-search nil)
e59fa9ad
JB
Juanma Barranquero2014-02-22 03:10:49 +0100926 (no-regexp-to-check (not (stringp desktop-files-not-to-save)))
927 dired-skip)
928 (and (or filename
929 (not (stringp desktop-buffers-not-to-save))
930 (not (string-match-p desktop-buffers-not-to-save bufname)))
931 (not (memq mode desktop-modes-not-to-save))
932 (or (and filename
933 (or no-regexp-to-check
934 (not (string-match-p desktop-files-not-to-save filename))))
935 (and (memq mode '(dired-mode vc-dir-mode))
936 (or no-regexp-to-check
937 (not (setq dired-skip
938 (with-current-buffer bufname
939 (string-match-p desktop-files-not-to-save
940 default-directory))))))
941 (and (null filename)
942 (null dired-skip) ; bug#5755
943 (with-current-buffer bufname desktop-save-buffer)))
944 t)))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000945
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +0000946;; ----------------------------------------------------------------------------
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +0000947(defun desktop-file-name (filename dirname)
948 "Convert FILENAME to format specified in `desktop-file-name-format'.
949DIRNAME must be the directory in which the desktop file will be saved."
950 (cond
951 ((not filename) nil)
952 ((eq desktop-file-name-format 'tilde)
953 (let ((relative-name (file-relative-name (expand-file-name filename) "~")))
954 (cond
955 ((file-name-absolute-p relative-name) relative-name)
956 ((string= "./" relative-name) "~/")
957 ((string= "." relative-name) "~")
958 (t (concat "~/" relative-name)))))
959 ((eq desktop-file-name-format 'local) (file-relative-name filename dirname))
960 (t (expand-file-name filename))))
e5714620 Juanma Barranquero2002-11-04 08:21:51 +0000961
b3615392 Miles Bader2007-06-16 22:32:13 +0000962
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +0000963;; ----------------------------------------------------------------------------
9421876d
JB
Juanma Barranquero2013-08-02 06:33:58 +0200964(defun desktop--check-dont-save (frame)
965 (not (frame-parameter frame 'desktop-dont-save)))
966
967(defconst desktop--app-id `(desktop . ,desktop-file-version))
968
969(defun desktop-save-frameset ()
970 "Save the state of existing frames in `desktop-saved-frameset'.
a1c80d9d Juanma Barranquero2013-07-22 03:25:47 +0200971Frames with a non-nil `desktop-dont-save' parameter are not saved."
9421876d Juanma Barranquero2013-08-02 06:33:58 +0200972 (setq desktop-saved-frameset
2addf922 Juanma Barranquero2013-07-01 05:29:46 +0200973 (and desktop-restore-frames
a912c016
JB
Juanma Barranquero2013-08-08 00:54:08 +0200974 (frameset-save nil
975 :app desktop--app-id
f9acac75 Paul Eggert2014-12-29 12:37:53 -0800976 :name (concat user-login-name "@" (system-name))
a912c016 Juanma Barranquero2013-08-08 00:54:08 +0200977 :predicate #'desktop--check-dont-save))))
39c0e36f Juanma Barranquero2013-06-27 11:08:14 +0200978
11425834 Lars Hansen2006-06-23 21:42:33 +0000979;;;###autoload
cbb6a7ae Juri Linkov2014-07-03 02:45:12 +0300980(defun desktop-save (dirname &optional release only-if-changed)
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +0000981 "Save the desktop in a desktop file.
982Parameter DIRNAME specifies where to save the desktop file.
e88110db Juanma Barranquero2007-06-12 09:11:31 +0000983Optional parameter RELEASE says whether we're done with this desktop.
cbb6a7ae
JL
Juri Linkov2014-07-03 02:45:12 +0300984If ONLY-IF-CHANGED is non-nil, compare the current desktop information
985to that in the desktop file, and if the desktop information has not
986changed since it was last saved then do not rewrite the file."
9271e90e
GM
Glenn Morris2013-10-09 21:03:11 -0400987 (interactive (list
988 ;; Or should we just use (car desktop-path)?
989 (let ((default (if (member "." desktop-path)
990 default-directory
991 user-emacs-directory)))
992 (read-directory-name "Directory to save desktop file in: "
993 default default t))))
e88110db Juanma Barranquero2007-06-12 09:11:31 +0000994 (setq desktop-dirname (file-name-as-directory (expand-file-name dirname)))
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +0000995 (save-excursion
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +0000996 (let ((eager desktop-restore-eager)
997 (new-modtime (nth 5 (file-attributes (desktop-full-file-name)))))
998 (when
999 (or (not new-modtime) ; nothing to overwrite
1000 (equal desktop-file-modtime new-modtime)
1001 (yes-or-no-p (if desktop-file-modtime
1002 (if (> (float-time new-modtime) (float-time desktop-file-modtime))
1003 "Desktop file is more recent than the one loaded. Save anyway? "
1004 "Desktop file isn't the one loaded. Overwrite it? ")
1005 "Current desktop was not loaded from a file. Overwrite this desktop file? "))
1006 (unless release (error "Desktop file conflict")))
1007
1008 ;; If we're done with it, release the lock.
1009 ;; Otherwise, claim it if it's unclaimed or if we created it.
1010 (if release
1011 (desktop-release-lock)
1012 (unless (and new-modtime (desktop-owner)) (desktop-claim-lock)))
1013
1014 (with-temp-buffer
1015 (insert
1016 ";; -*- mode: emacs-lisp; coding: emacs-mule; -*-\n"
1017 desktop-header
1018 ";; Created " (current-time-string) "\n"
1019 ";; Desktop file format version " desktop-file-version "\n"
1020 ";; Emacs version " emacs-version "\n")
1021 (save-excursion (run-hooks 'desktop-save-hook))
1022 (goto-char (point-max))
1023 (insert "\n;; Global section:\n")
39c0e36f
JB
Juanma Barranquero2013-06-27 11:08:14 +02001024 ;; Called here because we save the window/frame state as a global
1025 ;; variable for compatibility with previous Emacsen.
9421876d
JB
Juanma Barranquero2013-08-02 06:33:58 +02001026 (desktop-save-frameset)
1027 (unless (memq 'desktop-saved-frameset desktop-globals-to-save)
1028 (desktop-outvar 'desktop-saved-frameset))
e88110db Juanma Barranquero2007-06-12 09:11:31 +00001029 (mapc (function desktop-outvar) desktop-globals-to-save)
9421876d Juanma Barranquero2013-08-02 06:33:58 +02001030 (setq desktop-saved-frameset nil) ; after saving desktop-globals-to-save
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +00001031 (when (memq 'kill-ring desktop-globals-to-save)
1032 (insert
1033 "(setq kill-ring-yank-pointer (nthcdr "
1034 (int-to-string (- (length kill-ring) (length kill-ring-yank-pointer)))
1035 " kill-ring))\n"))
1036
1037 (insert "\n;; Buffer section -- buffers listed in same order as in buffer list:\n")
1038 (dolist (l (mapcar 'desktop-buffer-info (buffer-list)))
a8049a30
JB
Juanma Barranquero2008-02-14 14:37:00 +00001039 (let ((base (pop l)))
1040 (when (apply 'desktop-save-buffer-p l)
1041 (insert "("
1042 (if (or (not (integerp eager))
1043 (if (zerop eager)
1044 nil
1045 (setq eager (1- eager))))
1046 "desktop-create-buffer"
1047 "desktop-append-buffer-args")
1048 " "
1049 desktop-file-version)
ae4370a8
JB
Juanma Barranquero2008-02-29 03:03:57 +00001050 ;; If there's a non-empty base name, we save it instead of the buffer name
1051 (when (and base (not (string= base "")))
1052 (setcar (nthcdr 1 l) base))
a8049a30
JB
Juanma Barranquero2008-02-14 14:37:00 +00001053 (dolist (e l)
1054 (insert "\n " (desktop-value-to-string e)))
1055 (insert ")\n\n"))))
e88110db Juanma Barranquero2007-06-12 09:11:31 +00001056
9e29c91c Juanma Barranquero2007-07-12 22:40:00 +00001057 (setq default-directory desktop-dirname)
6c8e0ae6 Juri Linkov2013-12-16 23:48:51 +02001058 ;; When auto-saving, avoid writing if nothing has changed since the last write.
cbb6a7ae Juri Linkov2014-07-03 02:45:12 +03001059 (let* ((beg (and only-if-changed
6c8e0ae6
JL
Juri Linkov2013-12-16 23:48:51 +02001060 (save-excursion
1061 (goto-char (point-min))
1062 ;; Don't check the header with changing timestamp
1063 (and (search-forward "Global section" nil t)
1064 ;; Also skip the timestamp in desktop-saved-frameset
1065 ;; if it's saved in the first non-header line
1066 (search-forward "desktop-saved-frameset"
1067 (line-beginning-position 3) t)
1068 ;; This is saved after the timestamp
1069 (search-forward (format "%S" desktop--app-id) nil t))
1070 (point))))
1071 (checksum (and beg (md5 (current-buffer) beg (point-max) 'emacs-mule))))
1072 (unless (and checksum (equal checksum desktop-file-checksum))
5db9dace
JL
Juri Linkov2013-04-27 23:55:00 +03001073 (let ((coding-system-for-write 'emacs-mule))
1074 (write-region (point-min) (point-max) (desktop-full-file-name) nil 'nomessage))
1075 (setq desktop-file-checksum checksum)
1076 ;; We remember when it was modified (which is presumably just now).
1077 (setq desktop-file-modtime (nth 5 (file-attributes (desktop-full-file-name)))))))))))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +00001078
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +00001079;; ----------------------------------------------------------------------------
11425834 Lars Hansen2006-06-23 21:42:33 +00001080;;;###autoload
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +00001081(defun desktop-remove ()
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +00001082 "Delete desktop file in `desktop-dirname'.
1083This function also sets `desktop-dirname' to nil."
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +00001084 (interactive)
6b61353c Kenichi Handa2004-04-16 12:51:06 +00001085 (when desktop-dirname
11425834 Lars Hansen2006-06-23 21:42:33 +00001086 (let ((filename (desktop-full-file-name)))
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +00001087 (setq desktop-dirname nil)
1088 (when (file-exists-p filename)
73b0b745 Juanma Barranquero2003-06-03 23:35:20 +00001089 (delete-file filename)))))
6b61353c Kenichi Handa2004-04-16 12:51:06 +00001090
150f39ee
LH
Lars Hansen2005-01-07 20:18:59 +00001091(defvar desktop-buffer-args-list nil
1092 "List of args for `desktop-create-buffer'.")
1093
1094(defvar desktop-lazy-timer nil)
1095
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +00001096;; ----------------------------------------------------------------------------
9421876d
JB
Juanma Barranquero2013-08-02 06:33:58 +02001097(defun desktop-restoring-frameset-p ()
1098 "True if calling `desktop-restore-frameset' will actually restore it."
1099 (and desktop-restore-frames desktop-saved-frameset t))
1100
1101(defun desktop-restore-frameset ()
1102 "Restore the state of a set of frames.
1103This function depends on the value of `desktop-saved-frameset'
56bc453c Juanma Barranquero2013-07-21 19:45:12 +02001104being set (usually, by reading it from the desktop)."
9421876d
JB
Juanma Barranquero2013-08-02 06:33:58 +02001105 (when (desktop-restoring-frameset-p)
1106 (frameset-restore desktop-saved-frameset
4538c058
JB
Juanma Barranquero2014-03-11 01:46:07 +01001107 :reuse-frames (eq desktop-restore-reuses-frames t)
1108 :cleanup-frames (not (eq desktop-restore-reuses-frames 'keep))
9421876d
JB
Juanma Barranquero2013-08-02 06:33:58 +02001109 :force-display desktop-restore-in-current-display
1110 :force-onscreen desktop-restore-forces-onscreen)))
1111
1112;; Just to silence the byte compiler.
526e5233 Paul Eggert2013-08-15 22:15:51 -07001113;; Dynamically bound in `desktop-read'.
9421876d
JB
Juanma Barranquero2013-08-02 06:33:58 +02001114(defvar desktop-first-buffer)
1115(defvar desktop-buffer-ok-count)
1116(defvar desktop-buffer-fail-count)
39c0e36f Juanma Barranquero2013-06-27 11:08:14 +02001117
c863b6ad Glenn Morris2014-02-17 17:33:30 -08001118;; FIXME Interactively, this should have the option to prompt for dirname.
478653c9 Richard M. Stallman1998-03-28 07:32:50 +00001119;;;###autoload
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +00001120(defun desktop-read (&optional dirname)
1121 "Read and process the desktop file in directory DIRNAME.
1122Look for a desktop file in DIRNAME, or if DIRNAME is omitted, look in
1123directories listed in `desktop-path'. If a desktop file is found, it
cc8b76bf Juanma Barranquero2005-07-19 09:54:05 +00001124is processed and `desktop-after-read-hook' is run. If no desktop file
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +00001125is found, clear the desktop and run `desktop-no-desktop-file-hook'.
1126This function is a no-op when Emacs is running in batch mode.
1127It returns t if a desktop file was loaded, nil otherwise."
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +00001128 (interactive)
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +00001129 (unless noninteractive
6b61353c Kenichi Handa2004-04-16 12:51:06 +00001130 (setq desktop-dirname
11425834
LH
Lars Hansen2006-06-23 21:42:33 +00001131 (file-name-as-directory
1132 (expand-file-name
1133 (or
1134 ;; If DIRNAME is specified, use it.
1135 (and (< 0 (length dirname)) dirname)
1136 ;; Otherwise search desktop file in desktop-path.
1137 (let ((dirs desktop-path))
1138 (while (and dirs
1139 (not (file-exists-p
1140 (desktop-full-file-name (car dirs)))))
1141 (setq dirs (cdr dirs)))
1142 (and dirs (car dirs)))
1143 ;; If not found and `desktop-path' is non-nil, use its first element.
1144 (and desktop-path (car desktop-path))
6b67c0d4
CY
Chong Yidong2012-06-21 15:25:56 +08001145 ;; Default: .emacs.d.
1146 user-emacs-directory))))
11425834 Lars Hansen2006-06-23 21:42:33 +00001147 (if (file-exists-p (desktop-full-file-name))
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +00001148 ;; Desktop file found, but is it already in use?
1149 (let ((desktop-first-buffer nil)
1150 (desktop-buffer-ok-count 0)
1151 (desktop-buffer-fail-count 0)
1152 (owner (desktop-owner))
1153 ;; Avoid desktop saving during evaluation of desktop buffer.
1e00ee24
KD
Kelly Dean2015-02-16 04:18:25 +00001154 (desktop-save nil)
1155 (desktop-autosave-was-enabled))
e88110db Juanma Barranquero2007-06-12 09:11:31 +00001156 (if (and owner
1f7efe1b
JB
Juanma Barranquero2007-06-12 11:14:52 +00001157 (memq desktop-load-locked-desktop '(nil ask))
1158 (or (null desktop-load-locked-desktop)
e76f0800 Chong Yidong2012-06-21 15:15:42 +08001159 (daemonp)
1f7efe1b
JB
Juanma Barranquero2007-06-12 11:14:52 +00001160 (not (y-or-n-p (format "Warning: desktop file appears to be in use by PID %s.\n\
1161Using it may cause conflicts. Use it anyway? " owner)))))
c41cf130 Juanma Barranquero2008-03-01 14:17:41 +00001162 (let ((default-directory desktop-dirname))
794855ca Juanma Barranquero2007-06-20 10:12:44 +00001163 (setq desktop-dirname nil)
c41cf130
JB
Juanma Barranquero2008-03-01 14:17:41 +00001164 (run-hooks 'desktop-not-loaded-hook)
1165 (unless desktop-dirname
1166 (message "Desktop file in use; not loaded.")))
e88110db Juanma Barranquero2007-06-12 09:11:31 +00001167 (desktop-lazy-abort)
a4d8b73e
JL
Juri Linkov2014-06-25 02:23:41 +03001168 ;; Temporarily disable the autosave that will leave it
1169 ;; disabled when loading the desktop fails with errors,
1170 ;; thus not overwriting the desktop with broken contents.
1e00ee24
KD
Kelly Dean2015-02-16 04:18:25 +00001171 (setq desktop-autosave-was-enabled
1172 (memq 'desktop-auto-save-set-timer window-configuration-change-hook))
a4d8b73e Juri Linkov2014-06-25 02:23:41 +03001173 (desktop-auto-save-disable)
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +00001174 ;; Evaluate desktop buffer and remember when it was modified.
1175 (load (desktop-full-file-name) t t t)
1176 (setq desktop-file-modtime (nth 5 (file-attributes (desktop-full-file-name))))
1177 ;; If it wasn't already, mark it as in-use, to bother other
1178 ;; desktop instances.
c99cf5ee Juri Linkov2014-02-07 09:58:10 +02001179 (unless (eq (emacs-pid) owner)
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +00001180 (condition-case nil
1181 (desktop-claim-lock)
1182 (file-error (message "Couldn't record use of desktop file")
1183 (sit-for 1))))
1184
9421876d Juanma Barranquero2013-08-02 06:33:58 +02001185 (unless (desktop-restoring-frameset-p)
56bc453c
JB
Juanma Barranquero2013-07-21 19:45:12 +02001186 ;; `desktop-create-buffer' puts buffers at end of the buffer list.
1187 ;; We want buffers existing prior to evaluating the desktop (and
1188 ;; not reused) to be placed at the end of the buffer list, so we
1189 ;; move them here.
1190 (mapc 'bury-buffer
1191 (nreverse (cdr (memq desktop-first-buffer (nreverse (buffer-list))))))
1192 (switch-to-buffer (car (buffer-list))))
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +00001193 (run-hooks 'desktop-delay-hook)
1194 (setq desktop-delay-hook nil)
9421876d Juanma Barranquero2013-08-02 06:33:58 +02001195 (desktop-restore-frameset)
e88110db Juanma Barranquero2007-06-12 09:11:31 +00001196 (run-hooks 'desktop-after-read-hook)
9421876d
JB
Juanma Barranquero2013-08-02 06:33:58 +02001197 (message "Desktop: %s%d buffer%s restored%s%s."
1198 (if desktop-saved-frameset
1199 (let ((fn (length (frameset-states desktop-saved-frameset))))
1200 (format "%d frame%s, "
1201 fn (if (= fn 1) "" "s")))
1202 "")
e88110db
JB
Juanma Barranquero2007-06-12 09:11:31 +00001203 desktop-buffer-ok-count
1204 (if (= 1 desktop-buffer-ok-count) "" "s")
1205 (if (< 0 desktop-buffer-fail-count)
1206 (format ", %d failed to restore" desktop-buffer-fail-count)
1207 "")
1208 (if desktop-buffer-args-list
1209 (format ", %d to restore lazily"
1210 (length desktop-buffer-args-list))
1211 ""))
9421876d Juanma Barranquero2013-08-02 06:33:58 +02001212 (unless (desktop-restoring-frameset-p)
56bc453c
JB
Juanma Barranquero2013-07-21 19:45:12 +02001213 ;; Bury the *Messages* buffer to not reshow it when burying
1214 ;; the buffer we switched to above.
1215 (when (buffer-live-p (get-buffer "*Messages*"))
1216 (bury-buffer "*Messages*"))
1217 ;; Clear all windows' previous and next buffers, these have
1218 ;; been corrupted by the `switch-to-buffer' calls in
1219 ;; `desktop-restore-file-buffer' (bug#11556). This is a
1220 ;; brute force fix and should be replaced by a more subtle
1221 ;; strategy eventually.
1222 (walk-window-tree (lambda (window)
1223 (set-window-prev-buffers window nil)
1224 (set-window-next-buffers window nil))))
5414a283 Juanma Barranquero2013-08-04 02:31:33 +02001225 (setq desktop-saved-frameset nil)
1e00ee24 Kelly Dean2015-02-16 04:18:25 +00001226 (if desktop-autosave-was-enabled (desktop-auto-save-enable))
e88110db Juanma Barranquero2007-06-12 09:11:31 +00001227 t))
6b61353c Kenichi Handa2004-04-16 12:51:06 +00001228 ;; No desktop file found.
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +00001229 (let ((default-directory desktop-dirname))
1230 (run-hooks 'desktop-no-desktop-file-hook))
1231 (message "No desktop file.")
1232 nil)))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +00001233
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +00001234;; ----------------------------------------------------------------------------
6b61353c Kenichi Handa2004-04-16 12:51:06 +00001235;; Maintained for backward compatibility
478653c9 Richard M. Stallman1998-03-28 07:32:50 +00001236;;;###autoload
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +00001237(defun desktop-load-default ()
577ed2b2 Richard M. Stallman1995-01-30 06:14:33 +00001238 "Load the `default' start-up library manually.
6b61353c Kenichi Handa2004-04-16 12:51:06 +00001239Also inhibit further loading of it."
59f7af81 Chong Yidong2012-09-25 12:13:02 +08001240 (declare (obsolete desktop-save-mode "22.1"))
b89c5a72
JB
Juanma Barranquero2005-07-29 10:25:15 +00001241 (unless inhibit-default-init ; safety check
1242 (load "default" t t)
1243 (setq inhibit-default-init t)))
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +00001244
1245;; ----------------------------------------------------------------------------
1246;;;###autoload
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +00001247(defun desktop-change-dir (dirname)
1248 "Change to desktop saved in DIRNAME.
1249Kill the desktop as specified by variables `desktop-save-mode' and
1250`desktop-save', then clear the desktop and load the desktop file in
1251directory DIRNAME."
1252 (interactive "DChange to directory: ")
1253 (setq dirname (file-name-as-directory (expand-file-name dirname desktop-dirname)))
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +00001254 (desktop-kill)
1255 (desktop-clear)
6b61353c Kenichi Handa2004-04-16 12:51:06 +00001256 (desktop-read dirname))
bf247b6e Kim F. Storm2005-02-09 15:50:47 +00001257
6b61353c Kenichi Handa2004-04-16 12:51:06 +00001258;; ----------------------------------------------------------------------------
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +00001259;;;###autoload
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +00001260(defun desktop-save-in-desktop-dir ()
1261 "Save the desktop in directory `desktop-dirname'."
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +00001262 (interactive)
1263 (if desktop-dirname
b89c5a72 Juanma Barranquero2005-07-29 10:25:15 +00001264 (desktop-save desktop-dirname)
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +00001265 (call-interactively 'desktop-save))
a609d13b Juanma Barranquero2009-01-05 02:49:31 +00001266 (message "Desktop saved in %s" (abbreviate-file-name desktop-dirname)))
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +00001267
1268;; ----------------------------------------------------------------------------
5db9dace
JL
Juri Linkov2013-04-27 23:55:00 +03001269;; Auto-Saving.
1270(defvar desktop-auto-save-timer nil)
1271
a4d8b73e
JL
Juri Linkov2014-06-25 02:23:41 +03001272(defun desktop-auto-save-enable (&optional timeout)
1273 (when (and (integerp (or timeout desktop-auto-save-timeout))
1274 (> (or timeout desktop-auto-save-timeout) 0))
1275 (add-hook 'window-configuration-change-hook 'desktop-auto-save-set-timer)))
1276
1277(defun desktop-auto-save-disable ()
1278 (remove-hook 'window-configuration-change-hook 'desktop-auto-save-set-timer)
1279 (desktop-auto-save-cancel-timer))
1280
5db9dace
JL
Juri Linkov2013-04-27 23:55:00 +03001281(defun desktop-auto-save ()
1282 "Save the desktop periodically.
1283Called by the timer created in `desktop-auto-save-set-timer'."
1284 (when (and desktop-save-mode
1285 (integerp desktop-auto-save-timeout)
1286 (> desktop-auto-save-timeout 0)
1287 ;; Avoid desktop saving during lazy loading.
1288 (not desktop-lazy-timer)
1289 ;; Save only to own desktop file.
1290 (eq (emacs-pid) (desktop-owner))
1291 desktop-dirname)
6c8e0ae6 Juri Linkov2013-12-16 23:48:51 +02001292 (desktop-save desktop-dirname nil t)))
5db9dace
JL
Juri Linkov2013-04-27 23:55:00 +03001293
1294(defun desktop-auto-save-set-timer ()
6c8e0ae6 Juri Linkov2013-12-16 23:48:51 +02001295 "Set the auto-save timer.
5db9dace Juri Linkov2013-04-27 23:55:00 +03001296Cancel any previous timer. When `desktop-auto-save-timeout' is a positive
6c8e0ae6
JL
Juri Linkov2013-12-16 23:48:51 +02001297integer, start a new idle timer to call `desktop-auto-save' repeatedly
1298after that many seconds of idle time."
2b777cd9 Juri Linkov2014-02-07 09:44:29 +02001299 (desktop-auto-save-cancel-timer)
5db9dace
JL
Juri Linkov2013-04-27 23:55:00 +03001300 (when (and (integerp desktop-auto-save-timeout)
1301 (> desktop-auto-save-timeout 0))
1302 (setq desktop-auto-save-timer
7f118009 Juri Linkov2014-06-07 02:38:40 +03001303 (run-with-idle-timer desktop-auto-save-timeout nil
6c8e0ae6 Juri Linkov2013-12-16 23:48:51 +02001304 'desktop-auto-save))))
5db9dace Juri Linkov2013-04-27 23:55:00 +03001305
2b777cd9
JL
Juri Linkov2014-02-07 09:44:29 +02001306(defun desktop-auto-save-cancel-timer ()
1307 (when desktop-auto-save-timer
1308 (cancel-timer desktop-auto-save-timer)
1309 (setq desktop-auto-save-timer nil)))
1310
5db9dace Juri Linkov2013-04-27 23:55:00 +03001311;; ----------------------------------------------------------------------------
4a2fce7a
RS
Richard M. Stallman2003-04-09 01:37:56 +00001312;;;###autoload
1313(defun desktop-revert ()
1314 "Revert to the last loaded desktop."
1315 (interactive)
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +00001316 (unless desktop-dirname
1317 (error "Unknown desktop directory"))
11425834 Lars Hansen2006-06-23 21:42:33 +00001318 (unless (file-exists-p (desktop-full-file-name))
6b61353c
KH
Kenichi Handa2004-04-16 12:51:06 +00001319 (error "No desktop file found"))
1320 (desktop-clear)
1321 (desktop-read desktop-dirname))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +00001322
341c2f07
SM
Stefan Monnier2007-04-11 02:28:26 +00001323(defvar desktop-buffer-major-mode)
1324(defvar desktop-buffer-locals)
06b60517 Juanma Barranquero2011-04-19 15:44:55 +02001325(defvar auto-insert) ; from autoinsert.el
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +00001326;; ----------------------------------------------------------------------------
06b60517
JB
Juanma Barranquero2011-04-19 15:44:55 +02001327(defun desktop-restore-file-buffer (buffer-filename
1328 _buffer-name
1329 _buffer-misc)
e5780ae1 Lars Hansen2004-04-21 20:53:35 +00001330 "Restore a file buffer."
06b60517
JB
Juanma Barranquero2011-04-19 15:44:55 +02001331 (when buffer-filename
1332 (if (or (file-exists-p buffer-filename)
1f7efe1b Juanma Barranquero2007-06-12 11:14:52 +00001333 (let ((msg (format "Desktop: File \"%s\" no longer exists."
06b60517 Juanma Barranquero2011-04-19 15:44:55 +02001334 buffer-filename)))
1f7efe1b
JB
Juanma Barranquero2007-06-12 11:14:52 +00001335 (if desktop-missing-file-warning
1336 (y-or-n-p (concat msg " Re-create buffer? "))
1337 (message "%s" msg)
1338 nil)))
1339 (let* ((auto-insert nil) ; Disable auto insertion
1340 (coding-system-for-read
1341 (or coding-system-for-read
1342 (cdr (assq 'buffer-file-coding-system
1343 desktop-buffer-locals))))
06b60517 Juanma Barranquero2011-04-19 15:44:55 +02001344 (buf (find-file-noselect buffer-filename)))
1f7efe1b
JB
Juanma Barranquero2007-06-12 11:14:52 +00001345 (condition-case nil
1346 (switch-to-buffer buf)
1347 (error (pop-to-buffer buf)))
1348 (and (not (eq major-mode desktop-buffer-major-mode))
1349 (functionp desktop-buffer-major-mode)
1350 (funcall desktop-buffer-major-mode))
1351 buf)
1352 nil)))
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +00001353
0f4804e7
LH
Lars Hansen2005-08-10 19:38:52 +00001354(defun desktop-load-file (function)
1355 "Load the file where auto loaded FUNCTION is defined."
7abaf5cc
SM
Stefan Monnier2012-07-25 21:27:33 -04001356 (when (fboundp function)
1357 (autoload-do-load (symbol-function function) function)))
0f4804e7 Lars Hansen2005-08-10 19:38:52 +00001358
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +00001359;; ----------------------------------------------------------------------------
eb982898
JL
Juri Linkov2004-04-27 06:52:35 +00001360;; Create a buffer, load its file, set its mode, ...;
1361;; called from Desktop file only.
1d500ca6 Gerd Moellmann2001-10-23 13:52:45 +00001362
340db502 Lars Hansen2004-09-09 19:45:03 +00001363(defun desktop-create-buffer
06b60517
JB
Juanma Barranquero2011-04-19 15:44:55 +02001364 (file-version
1365 buffer-filename
1366 buffer-name
1367 buffer-majormode
1368 buffer-minormodes
1369 buffer-point
1370 buffer-mark
1371 buffer-readonly
1372 buffer-misc
1373 &optional
c96983ef
KD
Kelly Dean2015-02-09 13:25:53 +00001374 buffer-locals
1375 compacted-vars
1376 &rest _unsupported)
06b60517
JB
Juanma Barranquero2011-04-19 15:44:55 +02001377
1378 (let ((desktop-file-version file-version)
1379 (desktop-buffer-file-name buffer-filename)
1380 (desktop-buffer-name buffer-name)
1381 (desktop-buffer-major-mode buffer-majormode)
1382 (desktop-buffer-minor-modes buffer-minormodes)
1383 (desktop-buffer-point buffer-point)
1384 (desktop-buffer-mark buffer-mark)
1385 (desktop-buffer-read-only buffer-readonly)
1386 (desktop-buffer-misc buffer-misc)
1387 (desktop-buffer-locals buffer-locals))
1388 ;; To make desktop files with relative file names possible, we cannot
1389 ;; allow `default-directory' to change. Therefore we save current buffer.
1390 (save-current-buffer
1391 ;; Give major mode module a chance to add a handler.
1392 (desktop-load-file desktop-buffer-major-mode)
1393 (let ((buffer-list (buffer-list))
1394 (result
1be3ca5a Leo Liu2012-02-10 23:59:29 +08001395 (condition-case-unless-debug err
06b60517
JB
Juanma Barranquero2011-04-19 15:44:55 +02001396 (funcall (or (cdr (assq desktop-buffer-major-mode
1397 desktop-buffer-mode-handlers))
1398 'desktop-restore-file-buffer)
1399 desktop-buffer-file-name
1400 desktop-buffer-name
1401 desktop-buffer-misc)
1402 (error
1403 (message "Desktop: Can't load buffer %s: %s"
1404 desktop-buffer-name
1405 (error-message-string err))
1406 (when desktop-missing-file-warning (sit-for 1))
1407 nil))))
1408 (if (bufferp result)
1409 (setq desktop-buffer-ok-count (1+ desktop-buffer-ok-count))
1410 (setq desktop-buffer-fail-count (1+ desktop-buffer-fail-count))
1411 (setq result nil))
1412 ;; Restore buffer list order with new buffer at end. Don't change
91af3942 Paul Eggert2011-11-14 15:59:56 -08001413 ;; the order for old desktop files (old desktop module behavior).
06b60517 Juanma Barranquero2011-04-19 15:44:55 +02001414 (unless (< desktop-file-version 206)
2776a650
IS
Ivan Shmakov2014-09-09 20:47:20 -04001415 (dolist (buf buffer-list)
1416 (and (buffer-live-p buf)
1417 (bury-buffer buf)))
06b60517
JB
Juanma Barranquero2011-04-19 15:44:55 +02001418 (when result (bury-buffer result)))
1419 (when result
1420 (unless (or desktop-first-buffer (< desktop-file-version 206))
1421 (setq desktop-first-buffer result))
1422 (set-buffer result)
1423 (unless (equal (buffer-name) desktop-buffer-name)
1424 (rename-buffer desktop-buffer-name t))
1425 ;; minor modes
1426 (cond ((equal '(t) desktop-buffer-minor-modes) ; backwards compatible
1427 (auto-fill-mode 1))
1428 ((equal '(nil) desktop-buffer-minor-modes) ; backwards compatible
1429 (auto-fill-mode 0))
1430 (t
1431 (dolist (minor-mode desktop-buffer-minor-modes)
1432 ;; Give minor mode module a chance to add a handler.
1433 (desktop-load-file minor-mode)
1434 (let ((handler (cdr (assq minor-mode desktop-minor-mode-handlers))))
1435 (if handler
1436 (funcall handler desktop-buffer-locals)
1437 (when (functionp minor-mode)
1438 (funcall minor-mode 1)))))))
1439 ;; Even though point and mark are non-nil when written by
1440 ;; `desktop-save', they may be modified by handlers wanting to set
1441 ;; point or mark themselves.
1442 (when desktop-buffer-point
1443 (goto-char
1444 (condition-case err
1445 ;; Evaluate point. Thus point can be something like
1446 ;; '(search-forward ...
1447 (eval desktop-buffer-point)
1448 (error (message "%s" (error-message-string err)) 1))))
1449 (when desktop-buffer-mark
ca70fe78
SM
Stefan Monnier2014-03-09 22:18:29 -04001450 (if (consp desktop-buffer-mark)
1451 (progn
1452 (move-marker (mark-marker) (car desktop-buffer-mark))
bf642130
SM
Stefan Monnier2014-11-21 13:01:40 -05001453 (if (car (cdr desktop-buffer-mark))
1454 (activate-mark 'dont-touch-tmm)))
ca70fe78 Stefan Monnier2014-03-09 22:18:29 -04001455 (move-marker (mark-marker) desktop-buffer-mark)))
06b60517
JB
Juanma Barranquero2011-04-19 15:44:55 +02001456 ;; Never override file system if the file really is read-only marked.
1457 (when desktop-buffer-read-only (setq buffer-read-only desktop-buffer-read-only))
b61d71e4
JB
Juanma Barranquero2013-07-23 03:10:54 +02001458 (dolist (this desktop-buffer-locals)
1459 (if (consp this)
ca70fe78 Stefan Monnier2014-03-09 22:18:29 -04001460 ;; An entry of this form `(symbol . value)'.
b61d71e4
JB
Juanma Barranquero2013-07-23 03:10:54 +02001461 (progn
1462 (make-local-variable (car this))
1463 (set (car this) (cdr this)))
ca70fe78 Stefan Monnier2014-03-09 22:18:29 -04001464 ;; An entry of the form `symbol'.
b61d71e4 Juanma Barranquero2013-07-23 03:10:54 +02001465 (make-local-variable this)
c96983ef
KD
Kelly Dean2015-02-09 13:25:53 +00001466 (makunbound this)))
1467 (unless (< desktop-file-version 208) ; Don't misinterpret any old custom args
1468 (dolist (record compacted-vars)
1469 (let*
1470 ((var (car record))
26f8a384 Stefan Monnier2015-04-10 01:50:22 -04001471 (deser-fun (nth 2 (assq var desktop-var-serdes-funs))))
c96983ef
KD
Kelly Dean2015-02-09 13:25:53 +00001472 (if deser-fun (set var (funcall deser-fun (cadr record))))))))
1473 result))))
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +00001474
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +00001475;; ----------------------------------------------------------------------------
ec4c6f22 Richard M. Stallman1994-01-06 11:34:51 +00001476;; Backward compatibility -- update parameters to 205 standards.
06b60517
JB
Juanma Barranquero2011-04-19 15:44:55 +02001477(defun desktop-buffer (buffer-filename buffer-name buffer-majormode
1478 mim pt mk ro tl fc cfs cr buffer-misc)
1479 (desktop-create-buffer 205 buffer-filename buffer-name
1480 buffer-majormode (cdr mim) pt mk ro
1481 buffer-misc
ec4c6f22
RS
Richard M. Stallman1994-01-06 11:34:51 +00001482 (list (cons 'truncate-lines tl)
1483 (cons 'fill-column fc)
1484 (cons 'case-fold-search cfs)
1485 (cons 'case-replace cr)
1486 (cons 'overwrite-mode (car mim)))))
84b538ec Juanma Barranquero2003-04-10 16:26:12 +00001487
150f39ee Lars Hansen2005-01-07 20:18:59 +00001488(defun desktop-append-buffer-args (&rest args)
cc8b76bf Juanma Barranquero2005-07-19 09:54:05 +00001489 "Append ARGS at end of `desktop-buffer-args-list'.
150f39ee
LH
Lars Hansen2005-01-07 20:18:59 +00001490ARGS must be an argument list for `desktop-create-buffer'."
1491 (setq desktop-buffer-args-list (nconc desktop-buffer-args-list (list args)))
1492 (unless desktop-lazy-timer
1493 (setq desktop-lazy-timer
1494 (run-with-idle-timer desktop-lazy-idle-delay t 'desktop-idle-create-buffers))))
1495
1496(defun desktop-lazy-create-buffer ()
1497 "Pop args from `desktop-buffer-args-list', create buffer and bury it."
1498 (when desktop-buffer-args-list
1499 (let* ((remaining (length desktop-buffer-args-list))
1500 (args (pop desktop-buffer-args-list))
1501 (buffer-name (nth 2 args))
1502 (msg (format "Desktop lazily opening %s (%s remaining)..."
1503 buffer-name remaining)))
1504 (when desktop-lazy-verbose
8a26c165 Deepak Goel2005-09-18 12:25:02 +00001505 (message "%s" msg))
150f39ee
LH
Lars Hansen2005-01-07 20:18:59 +00001506 (let ((desktop-first-buffer nil)
1507 (desktop-buffer-ok-count 0)
1508 (desktop-buffer-fail-count 0))
1509 (apply 'desktop-create-buffer args)
1510 (run-hooks 'desktop-delay-hook)
1511 (setq desktop-delay-hook nil)
1512 (bury-buffer (get-buffer buffer-name))
1513 (when desktop-lazy-verbose
1514 (message "%s%s" msg (if (> desktop-buffer-ok-count 0) "done" "failed")))))))
1515
1516(defun desktop-idle-create-buffers ()
1517 "Create buffers until the user does something, then stop.
1518If there are no buffers left to create, kill the timer."
1519 (let ((repeat 1))
1520 (while (and repeat desktop-buffer-args-list)
1521 (save-window-excursion
1522 (desktop-lazy-create-buffer))
1523 (setq repeat (sit-for 0.2))
1524 (unless desktop-buffer-args-list
1525 (cancel-timer desktop-lazy-timer)
1526 (setq desktop-lazy-timer nil)
1527 (message "Lazy desktop load complete")
1528 (sit-for 3)
1529 (message "")))))
1530
1531(defun desktop-lazy-complete ()
1532 "Run the desktop load to completion."
1533 (interactive)
1534 (let ((desktop-lazy-verbose t))
1535 (while desktop-buffer-args-list
1536 (save-window-excursion
1537 (desktop-lazy-create-buffer)))
1538 (message "Lazy desktop load complete")))
1539
1540(defun desktop-lazy-abort ()
1541 "Abort lazy loading of the desktop."
1542 (interactive)
1543 (when desktop-lazy-timer
1544 (cancel-timer desktop-lazy-timer)
1545 (setq desktop-lazy-timer nil))
1546 (when desktop-buffer-args-list
1547 (setq desktop-buffer-args-list nil)
32226619 Juanma Barranquero2009-10-02 03:48:36 +00001548 (when (called-interactively-p 'interactive)
150f39ee
LH
Lars Hansen2005-01-07 20:18:59 +00001549 (message "Lazy desktop load aborted"))))
1550
0b9bd504 Richard M. Stallman1993-10-07 16:50:26 +00001551;; ----------------------------------------------------------------------------
6b61353c Kenichi Handa2004-04-16 12:51:06 +00001552;; 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 +00001553;; command line, we do the rest of what it takes to use desktop, but do it
1554;; after finishing loading the init file.
1555;; We cannot use `command-switch-alist' to process "--no-desktop" because these
1556;; functions are processed after `after-init-hook'.
1557(add-hook
1558 'after-init-hook
341c2f07 Stefan Monnier2007-04-11 02:28:26 +00001559 (lambda ()
4a2fce7a Richard M. Stallman2003-04-09 01:37:56 +00001560 (let ((key "--no-desktop"))
4b217d46
LH
Lars Hansen2005-04-18 18:27:39 +00001561 (when (member key command-line-args)
1562 (setq command-line-args (delete key command-line-args))
2b777cd9 Juri Linkov2014-02-07 09:44:29 +02001563 (desktop-save-mode 0)))
54d22a6f Juri Linkov2008-02-12 23:41:19 +00001564 (when desktop-save-mode
61dcf9bc
GM
Glenn Morris2014-07-15 21:28:42 -07001565 ;; People don't expect emacs -nw, or --daemon,
1566 ;; to create graphical frames (bug#17693).
1567 ;; TODO perhaps there should be a separate value
1568 ;; for desktop-restore-frames to control this startup behavior?
1569 (let ((desktop-restore-frames (and desktop-restore-frames
1570 initial-window-system
1571 (not (daemonp)))))
1572 (desktop-read)
1573 (setq inhibit-startup-screen t)))))
813dbb2d Richard M. Stallman1997-12-29 20:58:19 +00001574
f12ad6ec
GM
Glenn Morris2013-05-02 13:47:39 -04001575;; So we can restore vc-dir buffers.
1576(autoload 'vc-dir-mode "vc-dir" nil t)
1577
ab1d55ea Richard M. Stallman1993-06-01 20:11:54 +00001578(provide 'desktop)
6343ed61 Richard M. Stallman1993-06-01 20:09:25 +00001579
80f9f3db Stefan Monnier2000-10-10 16:42:37 +00001580;;; desktop.el ends here
8c106d17
GM
Glenn Morris2013-10-12 17:31:19 -07001581
1582;; Local Variables:
1583;; coding: utf-8
1584;; End: