Move here from lisp/nxml. Rename from "test." to "test-" for doschk.
[bpt/emacs.git] / lisp / startup.el
CommitLineData
c88ab9ce
ER
1;;; startup.el --- process Emacs shell arguments
2
a3194d03 3;; Copyright (C) 1985, 1986, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
93926b07
GM
4;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
5;; Free Software Foundation, Inc.
eea8d4ef 6
630cc463 7;; Maintainer: FSF
d7b4d18f 8;; Keywords: internal
630cc463 9
a726e0d1
JB
10;; This file is part of GNU Emacs.
11
12;; GNU Emacs is free software; you can redistribute it and/or modify
13;; it under the terms of the GNU General Public License as published by
b4aa6026 14;; the Free Software Foundation; either version 3, or (at your option)
a726e0d1
JB
15;; any later version.
16
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
b578f267 23;; along with GNU Emacs; see the file COPYING. If not, write to the
086add15
LK
24;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25;; Boston, MA 02110-1301, USA.
a726e0d1 26
630cc463 27;;; Commentary:
a726e0d1 28
6b61353c
KH
29;; This file parses the command line and gets Emacs running. Options
30;; on the command line are handled in precedence order. For priorities
31;; see the structure standard_args in the emacs.c file.
a726e0d1 32
630cc463
ER
33;;; Code:
34
a726e0d1
JB
35(setq top-level '(normal-top-level))
36
42a3e6fa 37(defvar command-line-processed nil
2879a13b 38 "Non-nil once command line has been processed.")
a726e0d1 39
42a3e6fa 40(defgroup initialization nil
ca3685a3 41 "Emacs start-up procedure."
26cdce23
JL
42 :group 'environment)
43
44(defcustom initial-buffer-choice nil
45 "Buffer to show after starting Emacs.
490a1ad6 46If the value is nil and `inhibit-startup-screen' is nil, show the
26cdce23
JL
47startup screen. If the value is string, visit the specified file or
48directory using `find-file'. If t, open the `*scratch*' buffer."
49 :type '(choice
490a1ad6 50 (const :tag "Startup screen" nil)
26cdce23
JL
51 (directory :tag "Directory" :value "~/")
52 (file :tag "File" :value "~/file.txt")
53 (const :tag "Lisp scratch buffer" t))
54 :version "23.1"
55 :group 'initialization)
42a3e6fa 56
490a1ad6 57(defcustom inhibit-startup-screen nil
249d9683 58 "Non-nil inhibits the startup screen.
ab863ac2 59It also inhibits display of the initial message in the `*scratch*' buffer.
249d9683 60
531b591d
AM
61This is for use in your personal init file (but NOT site-start.el), once
62you are familiar with the contents of the startup screen."
42a3e6fa
RS
63 :type 'boolean
64 :group 'initialization)
a726e0d1 65
490a1ad6
JL
66(defvaralias 'inhibit-splash-screen 'inhibit-startup-screen)
67(defvaralias 'inhibit-startup-message 'inhibit-startup-screen)
1b207153 68
22a58255 69(defvar startup-screen-inhibit-startup-screen nil)
1b207153 70
42a3e6fa 71(defcustom inhibit-startup-echo-area-message nil
1d7da582 72 "*Non-nil inhibits the initial startup echo area message.
42a3e6fa
RS
73Setting this variable takes effect
74only if you do it with the customization buffer
94487c4e 75or if your `.emacs' file contains a line of this form:
54a003f7 76 (setq inhibit-startup-echo-area-message \"YOUR-USER-NAME\")
e5575c06
RS
77If your `.emacs' file is byte-compiled, use the following form instead:
78 (eval '(setq inhibit-startup-echo-area-message \"YOUR-USER-NAME\"))
1d7da582 79Thus, someone else using a copy of your `.emacs' file will see
42a3e6fa
RS
80the startup message unless he personally acts to inhibit it."
81 :type '(choice (const :tag "Don't inhibit")
82 (string :tag "Enter your user name, to inhibit"))
83 :group 'initialization)
1d7da582 84
42a3e6fa
RS
85(defcustom inhibit-default-init nil
86 "*Non-nil inhibits loading the `default' library."
87 :type 'boolean
88 :group 'initialization)
a726e0d1 89
802a980a
GM
90(defcustom inhibit-startup-buffer-menu nil
91 "*Non-nil inhibits display of buffer list when more than 2 files are loaded."
92 :type 'boolean
93 :group 'initialization)
94
d7fa5aa2 95(defvar command-switch-alist nil
a726e0d1
JB
96 "Alist of command-line switches.
97Elements look like (SWITCH-STRING . HANDLER-FUNCTION).
6b61353c
KH
98HANDLER-FUNCTION receives the switch string as its sole argument;
99the remaining command-line args are in the variable `command-line-args-left'.")
a726e0d1 100
860befc8
RS
101(defvar command-line-args-left nil
102 "List of command-line args not yet processed.")
103
aa5310e4
DK
104(defvaralias 'argv 'command-line-args-left
105 "List of command-line args not yet processed.
106This is a convenience alias, so that one can write \(pop argv\)
107inside of --eval command line arguments in order to access
108following arguments.")
109
a726e0d1
JB
110(defvar command-line-functions nil ;; lrs 7/31/89
111 "List of functions to process unrecognized command-line arguments.
112Each function should access the dynamically bound variables
b4484ea8 113`argi' (the current argument) and `command-line-args-left' (the remaining
a726e0d1 114arguments). The function should return non-nil only if it recognizes and
b4484ea8
RS
115processes `argi'. If it does so, it may consume successive arguments by
116altering `command-line-args-left' to remove them.")
a726e0d1 117
09a1077c
RS
118(defvar command-line-default-directory nil
119 "Default directory to use for command line arguments.
120This is normally copied from `default-directory' when Emacs starts.")
121
b3afdeb8
RS
122;;; This is here, rather than in x-win.el, so that we can ignore these
123;;; options when we are not using X.
46cfd295 124(defconst command-line-x-option-alist
b3afdeb8
RS
125 '(("-bw" 1 x-handle-numeric-switch border-width)
126 ("-d" 1 x-handle-display)
127 ("-display" 1 x-handle-display)
5676ab57 128 ("-name" 1 x-handle-name-switch)
2c3fef40
RS
129 ("-title" 1 x-handle-switch title)
130 ("-T" 1 x-handle-switch title)
b3afdeb8
RS
131 ("-r" 0 x-handle-switch reverse t)
132 ("-rv" 0 x-handle-switch reverse t)
133 ("-reverse" 0 x-handle-switch reverse t)
134 ("-reverse-video" 0 x-handle-switch reverse t)
135 ("-fn" 1 x-handle-switch font)
136 ("-font" 1 x-handle-switch font)
188b6a5e
EZ
137 ("-fs" 0 x-handle-initial-switch fullscreen fullboth)
138 ("-fw" 0 x-handle-initial-switch fullscreen fullwidth)
139 ("-fh" 0 x-handle-initial-switch fullscreen fullheight)
b3afdeb8 140 ("-ib" 1 x-handle-numeric-switch internal-border-width)
1f7f78f1 141 ("-g" 1 x-handle-geometry)
9ff6bda1 142 ("-lsp" 1 x-handle-numeric-switch line-spacing)
1f7f78f1 143 ("-geometry" 1 x-handle-geometry)
b3afdeb8
RS
144 ("-fg" 1 x-handle-switch foreground-color)
145 ("-foreground" 1 x-handle-switch foreground-color)
146 ("-bg" 1 x-handle-switch background-color)
147 ("-background" 1 x-handle-switch background-color)
148 ("-ms" 1 x-handle-switch mouse-color)
c755acf3 149 ("-nbi" 0 x-handle-switch icon-type nil)
b3afdeb8
RS
150 ("-iconic" 0 x-handle-iconic)
151 ("-xrm" 1 x-handle-xrm-switch)
152 ("-cr" 1 x-handle-switch cursor-color)
153 ("-vb" 0 x-handle-switch vertical-scroll-bars t)
154 ("-hb" 0 x-handle-switch horizontal-scroll-bars t)
155 ("-bd" 1 x-handle-switch)
156 ("--border-width" 1 x-handle-numeric-switch border-width)
157 ("--display" 1 x-handle-display)
5676ab57 158 ("--name" 1 x-handle-name-switch)
7775acb8 159 ("--title" 1 x-handle-switch title)
b3afdeb8
RS
160 ("--reverse-video" 0 x-handle-switch reverse t)
161 ("--font" 1 x-handle-switch font)
188b6a5e
EZ
162 ("--fullscreen" 0 x-handle-initial-switch fullscreen fullboth)
163 ("--fullwidth" 0 x-handle-initial-switch fullscreen fullwidth)
164 ("--fullheight" 0 x-handle-initial-switch fullscreen fullheight)
b3afdeb8 165 ("--internal-border" 1 x-handle-numeric-switch internal-border-width)
1f7f78f1 166 ("--geometry" 1 x-handle-geometry)
b3afdeb8
RS
167 ("--foreground-color" 1 x-handle-switch foreground-color)
168 ("--background-color" 1 x-handle-switch background-color)
169 ("--mouse-color" 1 x-handle-switch mouse-color)
bb1f0f78 170 ("--no-bitmap-icon" 0 x-handle-no-bitmap-icon)
b3afdeb8
RS
171 ("--iconic" 0 x-handle-iconic)
172 ("--xrm" 1 x-handle-xrm-switch)
173 ("--cursor-color" 1 x-handle-switch cursor-color)
174 ("--vertical-scroll-bars" 0 x-handle-switch vertical-scroll-bars t)
9ff6bda1 175 ("--line-spacing" 1 x-handle-numeric-switch line-spacing)
7f944e8e 176 ("--border-color" 1 x-handle-switch border-color)
c434f203
JD
177 ("--smid" 1 x-handle-smid)
178 ("--parent-id" 1 x-handle-parent-id))
b3afdeb8
RS
179 "Alist of X Windows options.
180Each element has the form
181 (NAME NUMARGS HANDLER FRAME-PARAM VALUE)
182where NAME is the option name string, NUMARGS is the number of arguments
183that the option accepts, HANDLER is a function to call to handle the option.
184FRAME-PARAM (optional) is the frame parameter this option specifies,
185and VALUE is the value which is given to that frame parameter
186\(most options use the argument for this, so VALUE is not present).")
187
e3bd99f5 188(defvar before-init-hook nil
db3f571a 189 "Normal hook run after handling urgent options but before loading init files.")
3fc958a4 190
e3bd99f5 191(defvar after-init-hook nil
db3f571a
KH
192 "Normal hook run after loading the init files, `~/.emacs' and `default.el'.
193There is no `condition-case' around the running of these functions;
194therefore, if you set `debug-on-error' non-nil in `.emacs',
195an error in one of these functions will invoke the debugger.")
196
5c9fad41
GM
197(defvar before-init-time nil
198 "Value of `current-time' before Emacs begins initialization.")
238cbdf8 199
db3f571a
KH
200(defvar emacs-startup-hook nil
201 "Normal hook run after loading init files and handling the command line.")
e3bd99f5 202
a726e0d1 203(defvar term-setup-hook nil
db3f571a
KH
204 "Normal hook run after loading terminal-specific Lisp code.
205It also follows `emacs-startup-hook'. This hook exists for users to set,
a726e0d1
JB
206so as to override the definitions made by the terminal-specific file.
207Emacs never sets this variable itself.")
208
deebb0e9
RS
209(defvar inhibit-startup-hooks nil
210 "Non-nil means don't run `term-setup-hook' and `emacs-startup-hook'.
211This is because we already did so.")
212
a726e0d1 213(defvar keyboard-type nil
b4484ea8 214 "The brand of keyboard you are using.
9ab281f0
JB
215This variable is used to define the proper function and keypad
216keys for use under X. It is used in a fashion analogous to the
217environment variable TERM.")
a726e0d1
JB
218
219(defvar window-setup-hook nil
b4484ea8
RS
220 "Normal hook run to initialize window system display.
221Emacs runs this hook after processing the command line arguments and loading
222the user's init file.")
a726e0d1 223
42a3e6fa 224(defcustom initial-major-mode 'lisp-interaction-mode
ab863ac2 225 "Major mode command symbol to use for the initial `*scratch*' buffer."
ce2f921e 226 :type 'function
42a3e6fa 227 :group 'initialization)
a726e0d1 228
ecbff273 229(defvar init-file-user nil
a726e0d1 230 "Identity of user whose `.emacs' file is or was read.
d7fa5aa2
RS
231The value is nil if `-q' or `--no-init-file' was specified,
232meaning do not load any init file.
233
d3a81eee
EZ
234Otherwise, the value may be an empty string, meaning
235use the init file for the user who originally logged in,
236or it may be a string containing a user's name meaning
237use that person's init file.
a726e0d1 238
2bdfaa42
KH
239In either of the latter cases, `(concat \"~\" init-file-user \"/\")'
240evaluates to the name of the directory where the `.emacs' file was
13fce4e6
RS
241looked for.
242
243Setting `init-file-user' does not prevent Emacs from loading
ecbff273 244`site-start.el'. The only way to do that is to use `--no-site-file'.")
a726e0d1 245
42a3e6fa 246(defcustom site-run-file "site-start"
b7444d31
RS
247 "File containing site-wide run-time initializations.
248This file is loaded at run-time before `~/.emacs'. It contains inits
249that need to be in place for the entire site, but which, due to their
fcaf7de9 250higher incidence of change, don't make sense to load into Emacs's
b7444d31 251dumped image. Thus, the run-time load order is: 1. file described in
13fce4e6
RS
252this variable, if non-nil; 2. `~/.emacs'; 3. `default.el'.
253
254Don't use the `site-start.el' file for things some users may not like.
255Put them in `default.el' instead, so that users can more easily
256override them. Users can prevent loading `default.el' with the `-q'
257option or by setting `inhibit-default-init' in their own init files,
258but inhibiting `site-start.el' requires `--no-site-file', which
842a1eac
RS
259is less convenient.
260
261This variable is defined for customization so as to make
262it visible in the relevant context. However, actually customizing it
263is not allowed, since it would not work anyway. The only way to set
9ab281f0 264this variable usefully is to set it while building and dumping Emacs."
93812130 265 :type '(choice (const :tag "none" nil) string)
842a1eac
RS
266 :group 'initialization
267 :initialize 'custom-initialize-default
268 :set '(lambda (variable value)
269 (error "Customizing `site-run-file' does not work")))
b7444d31 270
42a3e6fa
RS
271(defcustom mail-host-address nil
272 "*Name of this machine, for purposes of naming users."
273 :type '(choice (const nil) string)
274 :group 'mail)
c13fbb62 275
680ebfa6 276(defcustom user-mail-address (if command-line-processed
cee0c996
EZ
277 (or (getenv "EMAIL")
278 (concat (user-login-name) "@"
279 (or mail-host-address
280 (system-name))))
680ebfa6
RS
281 ;; Empty string means "not set yet".
282 "")
452e9090 283 "*Full mailing address of this user.
cee0c996
EZ
284This is initialized with environment variable `EMAIL' or, as a
285fallback, using `mail-host-address'. This is done after your
286init file is read, in case it sets `mail-host-address'."
42a3e6fa
RS
287 :type 'string
288 :group 'mail)
c10d1f06 289
42a3e6fa 290(defcustom auto-save-list-file-prefix
73f13e5a
GM
291 (cond ((eq system-type 'ms-dos)
292 ;; MS-DOS cannot have initial dot, and allows only 8.3 names
34b68a62 293 (concat user-emacs-directory "auto-save.list/_s"))
73f13e5a 294 (t
34b68a62 295 (concat user-emacs-directory "auto-save-list/.saves-")))
cdee38c3
KH
296 "Prefix for generating `auto-save-list-file-name'.
297This is used after reading your `.emacs' file to initialize
298`auto-save-list-file-name', by appending Emacs's pid and the system name,
299if you have not already set `auto-save-list-file-name' yourself.
73f13e5a 300Directories in the prefix will be created if necessary.
cdee38c3 301Set this to nil if you want to prevent `auto-save-list-file-name'
42a3e6fa 302from being initialized."
3671f444
KH
303 :type '(choice (const :tag "Don't record a session's auto save list" nil)
304 string)
42a3e6fa 305 :group 'auto-save)
2e05d063 306
6b61353c
KH
307(defvar emacs-quick-startup nil)
308
dc58296d
RS
309(defvar emacs-basic-display nil)
310
a726e0d1
JB
311(defvar init-file-debug nil)
312
5b309ebf
RS
313(defvar init-file-had-error nil
314 "Non-nil if there was an error loading the user's init file.")
52320897 315
95eada65
RS
316(defvar normal-top-level-add-subdirs-inode-list nil)
317
178b4542
JL
318(defvar no-blinking-cursor nil)
319
0a480f3d
RS
320(defvar default-frame-background-mode)
321
b693e375
RS
322(defvar pure-space-overflow nil
323 "Non-nil if building Emacs overflowed pure space.")
324
22a58255
CY
325(defvar pure-space-overflow-message "\
326Warning Warning!!! Pure space overflow !!!Warning Warning
327\(See the node Pure Storage in the Lisp manual for details.)\n")
328
5f5ba825 329(defvar tutorial-directory nil
f51a80af
GM
330 "Directory containing the Emacs TUTORIAL files.")
331
5f5ba825
GM
332;; Get correct value in a dumped, installed Emacs.
333(eval-at-startup
334 (setq tutorial-directory (file-name-as-directory
335 (expand-file-name "tutorials" data-directory))))
336
859e15c1 337(defun normal-top-level-add-subdirs-to-load-path ()
0412d833
RS
338 "Add all subdirectories of current directory to `load-path'.
339More precisely, this uses only the subdirectories whose names
f734a13e
DL
340start with letters or digits; it excludes any subdirectory named `RCS'
341or `CVS', and any subdirectory that contains a file named `.nosearch'."
f1180544 342 (let (dirs
95eada65 343 attrs
859e15c1
KH
344 (pending (list default-directory)))
345 ;; This loop does a breadth-first tree walk on DIR's subtree,
346 ;; putting each subdir into DIRS as its contents are examined.
347 (while pending
4e0a3971 348 (push (pop pending) dirs)
722a451d
EZ
349 (let* ((this-dir (car dirs))
350 (contents (directory-files this-dir))
351 (default-directory this-dir)
fcaf7de9
SM
352 (canonicalized (if (fboundp 'untranslated-canonical-name)
353 (untranslated-canonical-name this-dir))))
722a451d
EZ
354 ;; The Windows version doesn't report meaningful inode
355 ;; numbers, so use the canonicalized absolute file name of the
356 ;; directory instead.
357 (setq attrs (or canonicalized
358 (nthcdr 10 (file-attributes this-dir))))
95eada65 359 (unless (member attrs normal-top-level-add-subdirs-inode-list)
4e0a3971
SM
360 (push attrs normal-top-level-add-subdirs-inode-list)
361 (dolist (file contents)
c4a40544 362 ;; The lower-case variants of RCS and CVS are for DOS/Windows.
4e0a3971
SM
363 (unless (member file '("." ".." "RCS" "CVS" "rcs" "cvs"))
364 (when (and (string-match "\\`[[:alnum:]]" file)
9d1fb179
RS
365 ;; Avoid doing a `stat' when it isn't necessary
366 ;; because that can cause trouble when an NFS server
367 ;; is down.
4e0a3971
SM
368 (not (string-match "\\.elc?\\'" file))
369 (file-directory-p file))
370 (let ((expanded (expand-file-name file)))
95eada65
RS
371 (unless (file-exists-p (expand-file-name ".nosearch"
372 expanded))
4e0a3971 373 (setq pending (nconc pending (list expanded)))))))))))
bb15e81a 374 (normal-top-level-add-to-load-path (cdr (nreverse dirs)))))
859e15c1 375
537b6e4e
RS
376;; This function is called from a subdirs.el file.
377;; It assumes that default-directory is the directory
378;; in which the subdirs.el file exists,
379;; and it adds to load-path the subdirs of that directory
380;; as specified in DIRS. Normally the elements of DIRS are relative.
e87a7309 381(defun normal-top-level-add-to-load-path (dirs)
cd1c10f6
RS
382 (let ((tail load-path)
383 (thisdir (directory-file-name default-directory)))
384 (while (and tail
138e541f
GM
385 ;;Don't go all the way to the nil terminator.
386 (cdr tail)
cd1c10f6
RS
387 (not (equal thisdir (car tail)))
388 (not (and (memq system-type '(ms-dos windows-nt))
389 (equal (downcase thisdir) (downcase (car tail))))))
390 (setq tail (cdr tail)))
138e541f
GM
391 ;;Splice the new section in.
392 (when tail
393 (setcdr tail (append (mapcar 'expand-file-name dirs) (cdr tail))))))
e87a7309 394
a726e0d1
JB
395(defun normal-top-level ()
396 (if command-line-processed
397 (message "Back to top level.")
398 (setq command-line-processed t)
8d4c2221
RS
399 ;; Give *Messages* the same default-directory as *scratch*,
400 ;; just to keep things predictable.
401 (let ((dir default-directory))
fcaf7de9 402 (with-current-buffer "*Messages*"
8d4c2221 403 (setq default-directory dir)))
9715399e
MR
404 ;; `user-full-name' is now known; reset its standard-value here.
405 (put 'user-full-name 'standard-value
406 (list (default-value 'user-full-name)))
80d71556
KH
407 ;; For root, preserve owner and group when editing files.
408 (if (equal (user-uid) 0)
409 (setq backup-by-copying-when-mismatch t))
e87a7309
RS
410 ;; Look in each dir in load-path for a subdirs.el file.
411 ;; If we find one, load it, which will add the appropriate subdirs
412 ;; of that dir into load-path,
357438eb
KH
413 ;; Look for a leim-list.el file too. Loading it will register
414 ;; available input methods.
b6666b5f
SM
415 (let ((tail load-path) dir)
416 (while tail
417 (setq dir (car tail))
418 (let ((default-directory dir))
419 (load (expand-file-name "subdirs.el") t t t))
420 (let ((default-directory dir))
421 (load (expand-file-name "leim-list.el") t t t))
422 ;; We don't use a dolist loop and we put this "setq-cdr" command at
423 ;; the end, because the subdirs.el files may add elements to the end
424 ;; of load-path and we want to take it into account.
425 (setq tail (cdr tail))))
fcaf7de9
SM
426 (unless (eq system-type 'vax-vms)
427 ;; If the PWD environment variable isn't accurate, delete it.
428 (let ((pwd (getenv "PWD")))
429 (and (stringp pwd)
430 ;; Use FOO/., so that if FOO is a symlink, file-attributes
431 ;; describes the directory linked to, not FOO itself.
432 (or (equal (file-attributes
433 (concat (file-name-as-directory pwd) "."))
434 (file-attributes
435 (concat (file-name-as-directory default-directory)
436 ".")))
437 (setq process-environment
438 (delete (concat "PWD=" pwd)
439 process-environment))))))
492878e4 440 (setq default-directory (abbreviate-file-name default-directory))
6f2c86fa
KH
441 (let ((menubar-bindings-done nil))
442 (unwind-protect
443 (command-line)
444 ;; Do this again, in case .emacs defined more abbreviations.
445 (setq default-directory (abbreviate-file-name default-directory))
b3c7c12c
RS
446 ;; Specify the file for recording all the auto save files of this session.
447 ;; This is used by recover-session.
cdee38c3
KH
448 (or auto-save-list-file-name
449 (and auto-save-list-file-prefix
450 (setq auto-save-list-file-name
1f7f78f1
RS
451 ;; Under MS-DOS our PID is almost always reused between
452 ;; Emacs invocations. We need something more unique.
4b33deaa
EZ
453 (cond ((eq system-type 'ms-dos)
454 ;; We are going to access the auto-save
455 ;; directory, so make sure it exists.
456 (make-directory
457 (file-name-directory auto-save-list-file-prefix)
458 t)
f1180544 459 (concat
4b33deaa
EZ
460 (make-temp-name
461 (expand-file-name
462 auto-save-list-file-prefix))
463 "~"))
464 (t
465 (expand-file-name
466 (format "%s%d-%s~"
467 auto-save-list-file-prefix
468 (emacs-pid)
469 (system-name))))))))
deebb0e9
RS
470 (unless inhibit-startup-hooks
471 (run-hooks 'emacs-startup-hook)
472 (and term-setup-hook
473 (run-hooks 'term-setup-hook)))
6a1e7d67
GM
474
475 ;; Don't do this if we failed to create the initial frame,
476 ;; for instance due to a dense colormap.
538ef02a
GM
477 (when (or frame-initial-frame
478 ;; If frame-initial-frame has no meaning, do this anyway.
2246281f 479 (not (and initial-window-system
538ef02a 480 (not noninteractive)
2246281f 481 (not (eq initial-window-system 'pc)))))
6a1e7d67
GM
482 ;; Modify the initial frame based on what .emacs puts into
483 ;; ...-frame-alist.
484 (if (fboundp 'frame-notice-user-settings)
485 (frame-notice-user-settings))
2666355c
KL
486 ;; Set the faces for the initial background mode even if
487 ;; frame-notice-user-settings didn't (such as on a tty).
488 ;; frame-set-background-mode is idempotent, so it won't
489 ;; cause any harm if it's already been done.
6a1e7d67 490 (if (fboundp 'frame-set-background-mode)
2666355c 491 (frame-set-background-mode (selected-frame))))
13ab33c4 492
6f2c86fa
KH
493 ;; Now we know the user's default font, so add it to the menu.
494 (if (fboundp 'font-menu-add-default)
495 (font-menu-add-default))
496 (and window-setup-hook
497 (run-hooks 'window-setup-hook))
498 (or menubar-bindings-done
66c24e1e 499 (if (display-popup-menus-p)
fdb88463
SM
500 (precompute-menubar-bindings)))))
501 ;; Subprocesses of Emacs do not have direct access to the terminal, so
502 ;; unless told otherwise they should only assume a dumb terminal.
503 ;; We are careful to do it late (after term-setup-hook), although the
504 ;; new multi-tty code does not use $TERM any more there anyway.
4bbfda32
SM
505 (setenv "TERM" "dumb")
506 ;; Remove DISPLAY from the process-environment as well. This allows
507 ;; `callproc.c' to give it a useful adaptive default which is either
508 ;; the value of the `display' frame-parameter or the DISPLAY value
509 ;; from initial-environment.
510 (let ((display (frame-parameter nil 'display)))
511 ;; Be careful which DISPLAY to remove from process-environment: follow
512 ;; the logic of `callproc.c'.
513 (if (stringp display) (setq display (concat "DISPLAY=" display))
514 (dolist (varval initial-environment)
515 (if (string-match "\\`DISPLAY=" varval)
516 (setq display varval))))
517 (when display
4bbfda32 518 (delete display process-environment)))))
6f2c86fa
KH
519
520;; Precompute the keyboard equivalents in the menu bar items.
521(defun precompute-menubar-bindings ()
365636dc
RS
522 (let ((submap (lookup-key global-map [menu-bar])))
523 (while submap
524 (and (consp (car submap))
525 (symbolp (car (car submap)))
526 (stringp (car-safe (cdr (car submap))))
527 (keymapp (cdr (cdr (car submap))))
a18042d7
RS
528 (progn
529 (x-popup-menu nil (cdr (cdr (car submap))))
530 (if purify-flag
531 (garbage-collect))))
365636dc 532 (setq submap (cdr submap))))
5b61c6a7 533 (setq define-key-rebound-commands t))
a726e0d1 534
c381f482
EZ
535;; Command-line options supported by tty's:
536(defconst tty-long-option-alist
8957d2bf
EZ
537 '(("--name" . "-name")
538 ("--title" . "-T")
539 ("--reverse-video" . "-reverse")
c381f482 540 ("--foreground-color" . "-fg")
8957d2bf
EZ
541 ("--background-color" . "-bg")
542 ("--color" . "-color")))
c381f482 543
b66b6aeb
GM
544(defconst tool-bar-images-pixel-height 24
545 "Height in pixels of images in the tool bar.")
546
3a55d3d0
JR
547(defvar tool-bar-originally-present nil
548 "Non-nil if tool-bars are present before user and site init files are read.")
549
e9cda827
KL
550(defvar handle-args-function-alist '((nil . tty-handle-args))
551 "Functions for processing window-system dependent command-line arguments.
552Window system startup files should add their own function to this
553alist, which should parse the command line arguments. Those
554pertaining to the window system should be processed and removed
555from the returned command line.")
556
557(defvar window-system-initialization-alist '((nil . ignore))
558 "Alist of window-system initialization functions.
559Window-system startup files should add their own initialization
560function to this list. The function should take no arguments,
561and initialize the window system environment to prepare for
2bb819d5 562opening the first frame (e.g. open a connection to an X server).")
e9cda827 563
bca8c7be 564;; Handle the X-like command-line arguments "-fg", "-bg", "-name", etc.
c381f482 565(defun tty-handle-args (args)
bca8c7be 566 (let (rest)
ae8bf5ab 567 (message "%S" args)
c381f482
EZ
568 (while (and args
569 (not (equal (car args) "--")))
bca8c7be
MS
570 (let* ((argi (pop args))
571 (orig-argi argi)
572 argval completion)
c381f482
EZ
573 ;; Check for long options with attached arguments
574 ;; and separate out the attached option argument into argval.
bca8c7be
MS
575 (when (string-match "^\\(--[^=]*\\)=" argi)
576 (setq argval (substring argi (match-end 0))
577 argi (match-string 1 argi)))
578 (when (string-match "^--" argi)
579 (setq completion (try-completion argi tty-long-option-alist))
c381f482
EZ
580 (if (eq completion t)
581 ;; Exact match for long option.
bca8c7be 582 (setq argi (cdr (assoc argi tty-long-option-alist)))
c381f482
EZ
583 (if (stringp completion)
584 (let ((elt (assoc completion tty-long-option-alist)))
585 ;; Check for abbreviated long option.
586 (or elt
bca8c7be
MS
587 (error "Option `%s' is ambiguous" argi))
588 (setq argi (cdr elt)))
c381f482 589 ;; Check for a short option.
bca8c7be
MS
590 (setq argval nil
591 argi orig-argi))))
592 (cond ((member argi '("-fg" "-foreground"))
593 (push (cons 'foreground-color (or argval (pop args)))
594 default-frame-alist))
595 ((member argi '("-bg" "-background"))
596 (push (cons 'background-color (or argval (pop args)))
597 default-frame-alist))
598 ((member argi '("-T" "-name"))
599 (unless argval (setq argval (pop args)))
600 (push (cons 'title
601 (if (stringp argval)
602 argval
603 (let ((case-fold-search t)
604 i)
605 (setq argval (invocation-name))
606
607 ;; Change any . or * characters in name to
608 ;; hyphens, so as to emulate behavior on X.
609 (while
610 (setq i (string-match "[.*]" argval))
611 (aset argval i ?-))
612 argval)))
613 default-frame-alist))
614 ((member argi '("-r" "-rv" "-reverse"))
615 (push '(reverse . t)
616 default-frame-alist))
617 ((equal argi "-color")
618 (unless argval (setq argval 8)) ; default --color means 8 ANSI colors
619 (push (cons 'tty-color-mode
620 (cond
621 ((numberp argval) argval)
622 ((string-match "-?[0-9]+" argval)
623 (string-to-number argval))
624 (t (intern argval))))
625 default-frame-alist))
626 (t
627 (push argi rest)))))
628 (nreverse rest)))
c381f482 629
a726e0d1 630(defun command-line ()
5c9fad41 631 (setq before-init-time (current-time)
238cbdf8 632 command-line-default-directory default-directory)
09a1077c 633
849eedba 634 ;; Choose a reasonable location for temporary files.
a3194d03 635 (custom-reevaluate-setting 'temporary-file-directory)
51db08eb 636 (custom-reevaluate-setting 'small-temporary-file-directory)
a3194d03 637 (custom-reevaluate-setting 'auto-save-file-name-transforms)
849eedba 638
74f2ab06 639 ;; See if we should import version-control from the environment variable.
a726e0d1
JB
640 (let ((vc (getenv "VERSION_CONTROL")))
641 (cond ((eq vc nil)) ;don't do anything if not set
bca8c7be 642 ((member vc '("t" "numbered"))
a726e0d1 643 (setq version-control t))
bca8c7be 644 ((member vc '("nil" "existing"))
a726e0d1 645 (setq version-control nil))
bca8c7be 646 ((member vc '("never" "simple"))
a726e0d1
JB
647 (setq version-control 'never))))
648
79058860
JB
649 ;;! This has been commented out; I currently find the behavior when
650 ;;! split-window-keep-point is nil disturbing, but if I can get used
651 ;;! to it, then it would be better to eliminate the option.
652 ;;! ;; Choose a good default value for split-window-keep-point.
653 ;;! (setq split-window-keep-point (> baud-rate 2400))
f35fe3c6 654
d4308a4d
EZ
655 ;; Set the default strings to display in mode line for
656 ;; end-of-line formats that aren't native to this platform.
657 (cond
658 ((memq system-type '(ms-dos windows-nt emx))
bca8c7be
MS
659 (setq eol-mnemonic-unix "(Unix)"
660 eol-mnemonic-mac "(Mac)"))
bde61f8b
EZ
661 ;; Both Mac and Unix EOLs are now "native" on Mac OS so keep the
662 ;; abbreviated strings `/' and `:' set in coding.c for them.
663 ((eq system-type 'macos)
664 (setq eol-mnemonic-dos "(DOS)"))
bca8c7be
MS
665 (t ; this is for Unix/GNU/Linux systems
666 (setq eol-mnemonic-dos "(DOS)"
667 eol-mnemonic-mac "(Mac)")))
d4308a4d 668
2666355c 669 ;; Make sure window system's init file was loaded in loadup.el if using a window system.
1ed14cfd 670 (condition-case error
e9cda827
KL
671 (unless noninteractive
672 (if (and initial-window-system
673 (not (featurep
2666355c 674 (intern (concat (symbol-name initial-window-system) "-win")))))
e9cda827
KL
675 (error "Unsupported window system `%s'" initial-window-system))
676 ;; Process window-system specific command line parameters.
677 (setq command-line-args
678 (funcall (or (cdr (assq initial-window-system handle-args-function-alist))
679 (error "Unsupported window system `%s'" initial-window-system))
680 command-line-args))
681 ;; Initialize the window system. (Open connection, etc.)
682 (funcall (or (cdr (assq initial-window-system window-system-initialization-alist))
683 (error "Unsupported window system `%s'" initial-window-system))))
684 ;; If there was an error, print the error message and exit.
1ed14cfd 685 (error
2677ad61
RS
686 (princ
687 (if (eq (car error) 'error)
688 (apply 'concat (cdr error))
689 (if (memq 'file-error (get (car error) 'error-conditions))
690 (format "%s: %s"
bca8c7be
MS
691 (nth 1 error)
692 (mapconcat (lambda (obj) (prin1-to-string obj t))
693 (cdr (cdr error)) ", "))
2677ad61 694 (format "%s: %s"
bca8c7be
MS
695 (get (car error) 'error-message)
696 (mapconcat (lambda (obj) (prin1-to-string obj t))
697 (cdr error) ", "))))
2677ad61 698 'external-debugging-output)
27f5188c 699 (terpri 'external-debugging-output)
2246281f 700 (setq initial-window-system nil)
1ed14cfd 701 (kill-emacs)))
a726e0d1 702
640a9cdd
JR
703 (set-locale-environment nil)
704
735895f1
EZ
705 ;; Convert preloaded file names in load-history to absolute.
706 (let ((simple-file-name
3b61abfe
EZ
707 ;; Look for simple.el or simple.elc and use their directory
708 ;; as the place where all Lisp files live.
735895f1
EZ
709 (locate-file "simple" load-path (get-load-suffixes)))
710 lisp-dir)
711 ;; Don't abort if simple.el cannot be found, but print a warning.
712 (if (null simple-file-name)
713 (progn
714 (princ "Warning: Could not find simple.el nor simple.elc"
715 'external-debugging-output)
716 (terpri 'external-debugging-output))
717 (setq lisp-dir (file-truename (file-name-directory simple-file-name)))
718 (setq load-history
719 (mapcar (lambda (elt)
720 (if (and (stringp (car elt))
721 (not (file-name-absolute-p (car elt))))
722 (cons (concat lisp-dir
723 (car elt))
724 (cdr elt))
725 elt))
726 load-history))))
4b816985 727
c16eb7b0
RS
728 ;; Convert the arguments to Emacs internal representation.
729 (let ((args (cdr command-line-args)))
730 (while args
731 (setcar args
732 (decode-coding-string (car args) locale-coding-system t))
bca8c7be 733 (pop args)))
c16eb7b0 734
03e3c30a
JB
735 (let ((done nil)
736 (args (cdr command-line-args)))
737
a726e0d1
JB
738 ;; Figure out which user's init file to load,
739 ;; either from the environment or from the options.
740 (setq init-file-user (if noninteractive nil (user-login-name)))
741 ;; If user has not done su, use current $HOME to find .emacs.
bca8c7be
MS
742 (and init-file-user
743 (equal init-file-user (user-real-login-name))
a726e0d1 744 (setq init-file-user ""))
03e3c30a
JB
745
746 ;; Process the command-line args, and delete the arguments
747 ;; processed. This is consistent with the way main in emacs.c
748 ;; does things.
a726e0d1 749 (while (and (not done) args)
9ab281f0
JB
750 (let* ((longopts '(("--no-init-file") ("--no-site-file") ("--debug-init")
751 ("--user") ("--iconic") ("--icon-type") ("--quick")
752 ("--no-blinking-cursor") ("--basic-display")))
bca8c7be
MS
753 (argi (pop args))
754 (orig-argi argi)
755 argval)
452e9090 756 ;; Handle --OPTION=VALUE format.
bca8c7be 757 (when (string-match "^\\(--[^=]*\\)=" argi)
1b207153 758 (setq argval (substring argi (match-end 0))
bca8c7be 759 argi (match-string 1 argi)))
1b207153
CW
760 (unless (equal argi "--")
761 (let ((completion (try-completion argi longopts)))
762 (if (eq completion t)
763 (setq argi (substring argi 1))
764 (if (stringp completion)
765 (let ((elt (assoc completion longopts)))
766 (or elt
767 (error "Option `%s' is ambiguous" argi))
768 (setq argi (substring (car elt) 1)))
bca8c7be
MS
769 (setq argval nil
770 argi orig-argi)))))
a726e0d1 771 (cond
dc58296d 772 ((member argi '("-Q" "-quick"))
6b61353c
KH
773 (setq init-file-user nil
774 site-run-file nil
dc58296d
RS
775 emacs-quick-startup t))
776 ((member argi '("-D" "-basic-display"))
777 (setq no-blinking-cursor t
778 emacs-basic-display t)
6b61353c 779 (push '(vertical-scroll-bars . nil) initial-frame-alist))
4e0a3971
SM
780 ((member argi '("-q" "-no-init-file"))
781 (setq init-file-user nil))
782 ((member argi '("-u" "-user"))
bca8c7be 783 (setq init-file-user (or argval (pop args))
4e0a3971 784 argval nil))
bca8c7be 785 ((equal argi "-no-site-file")
4e0a3971 786 (setq site-run-file nil))
bca8c7be 787 ((equal argi "-debug-init")
4e0a3971 788 (setq init-file-debug t))
bca8c7be 789 ((equal argi "-iconic")
4e0a3971 790 (push '(visibility . icon) initial-frame-alist))
bca8c7be 791 ((member argi '("-icon-type" "-i" "-itype"))
4e0a3971 792 (push '(icon-type . t) default-frame-alist))
178b4542
JL
793 ((member argi '("-nbc" "-no-blinking-cursor"))
794 (setq no-blinking-cursor t))
4e0a3971 795 ;; Push the popped arg back on the list of arguments.
bca8c7be
MS
796 (t
797 (push argi args)
798 (setq done t)))
096b7031
KH
799 ;; Was argval set but not used?
800 (and argval
801 (error "Option `%s' doesn't allow an argument" argi))))
802
03e3c30a 803 ;; Re-attach the program name to the front of the arg list.
bca8c7be
MS
804 (and command-line-args
805 (setcdr command-line-args args)))
a726e0d1 806
ce98f555
RS
807 (run-hooks 'before-init-hook)
808
ed0fb1f1 809 ;; Under X Window, this creates the X frame and deletes the terminal frame.
14f16b9c
GM
810 (when (fboundp 'frame-initialize)
811 (frame-initialize))
812
ed0fb1f1 813 ;; Turn off blinking cursor if so specified in X resources. This is here
b08cb5a6 814 ;; only because all other settings of no-blinking-cursor are here.
ed0fb1f1
JD
815 (unless (or noninteractive
816 emacs-basic-display
817 (and (memq window-system '(x w32 mac))
818 (not (member (x-get-resource "cursorBlink" "CursorBlink")
819 '("off" "false")))))
820 (setq no-blinking-cursor t))
821
1fe0333f 822 ;; If frame was created with a menu bar, set menu-bar-mode on.
bca8c7be 823 (unless (or noninteractive
dc58296d 824 emacs-basic-display
2246281f 825 (and (memq initial-window-system '(x w32))
bca8c7be 826 (<= (frame-parameter nil 'menu-bar-lines) 0)))
8ab9589d 827 (menu-bar-mode 1))
c722566c 828
7d1eb6a4 829 ;; If frame was created with a tool bar, switch tool-bar-mode on.
bca8c7be 830 (unless (or noninteractive
dc58296d 831 emacs-basic-display
bca8c7be
MS
832 (not (display-graphic-p))
833 (<= (frame-parameter nil 'tool-bar-lines) 0))
b66b6aeb 834 (tool-bar-mode 1))
7d1eb6a4 835
3413f928 836 ;; Can't do this init in defcustom because the relevant variables
a3194d03
SM
837 ;; are not set.
838 (custom-reevaluate-setting 'blink-cursor-mode)
dc86f0a9 839 (custom-reevaluate-setting 'tooltip-mode)
c442c26d 840 (custom-reevaluate-setting 'global-font-lock-mode)
97a7dbee
YM
841 (custom-reevaluate-setting 'mouse-wheel-down-event)
842 (custom-reevaluate-setting 'mouse-wheel-up-event)
db441dba 843 (custom-reevaluate-setting 'file-name-shadow-mode)
a496452f 844 (custom-reevaluate-setting 'send-mail-function)
1e2d7573 845 (custom-reevaluate-setting 'focus-follows-mouse)
2cc11fd4 846 (custom-reevaluate-setting 'global-auto-composition-mode)
3b73087e 847
30a2fded
KL
848 (normal-erase-is-backspace-setup-frame)
849
1592c1ef 850 ;; Register default TTY colors for the case the terminal hasn't a
79c3172f
KL
851 ;; terminal init file. We do this regardles of whether the terminal
852 ;; supports colors or not and regardless the current display type,
853 ;; since users can connect to color-capable terminals and also
854 ;; switch color support on or off in mid-session by setting the
855 ;; tty-color-mode frame parameter.
d448e982 856 (tty-register-default-colors)
1592c1ef 857
3a55d3d0
JR
858 ;; Record whether the tool-bar is present before the user and site
859 ;; init files are processed. frame-notice-user-settings uses this
860 ;; to determine if the tool-bar has been disabled by the init files,
861 ;; and the frame needs to be resized.
862 (when (fboundp 'frame-notice-user-settings)
863 (let ((tool-bar-lines (or (assq 'tool-bar-lines initial-frame-alist)
864 (assq 'tool-bar-lines default-frame-alist))))
865 (setq tool-bar-originally-present
bca8c7be
MS
866 (and tool-bar-lines
867 (cdr tool-bar-lines)
868 (not (eq 0 (cdr tool-bar-lines)))))))
3a55d3d0 869
752ef254
GM
870 (let ((old-scalable-fonts-allowed scalable-fonts-allowed)
871 (old-font-list-limit font-list-limit)
872 (old-face-ignored-fonts face-ignored-fonts))
873
752ef254
GM
874 ;; Run the site-start library if it exists. The point of this file is
875 ;; that it is run before .emacs. There is no point in doing this after
876 ;; .emacs; that is useless.
5f144784
GM
877 ;; Note that user-init-file is nil at this point. Code that might
878 ;; be loaded from site-run-file and wants to test if -q was given
879 ;; should check init-file-user instead, since that is already set.
880 ;; See cus-edit.el for an example.
f1180544 881 (if site-run-file
752ef254
GM
882 (load site-run-file t t))
883
884 ;; Sites should not disable this. Only individuals should disable
1cff9ad1
JL
885 ;; the startup screen.
886 (setq inhibit-startup-screen nil)
752ef254 887
f963ea40 888 ;; Warn for invalid user name.
ce98f555
RS
889 (when init-file-user
890 (if (string-match "[~/:\n]" init-file-user)
891 (display-warning 'initialization
892 (format "Invalid user name %s"
893 init-file-user)
894 :error)
1df1e49e
EZ
895 (if (file-directory-p (expand-file-name
896 ;; We don't support ~USER on MS-Windows except
897 ;; for the current user, and always load .emacs
898 ;; from the current user's home directory (see
899 ;; below). So always check "~", even if invoked
900 ;; with "-u USER", or if $USER or $LOGNAME are
901 ;; set to something different.
902 (if (eq system-type 'windows-nt)
903 "~"
904 (concat "~" init-file-user))))
ce98f555
RS
905 nil
906 (display-warning 'initialization
907 (format "User %s has no home directory"
908 init-file-user)
909 :error))))
f963ea40 910
752ef254
GM
911 ;; Load that user's init file, or the default one, or none.
912 (let (debug-on-error-from-init-file
913 debug-on-error-should-be-set
914 (debug-on-error-initial
915 (if (eq init-file-debug t) 'startup init-file-debug))
916 (orig-enable-multibyte default-enable-multibyte-characters))
917 (let ((debug-on-error debug-on-error-initial)
918 ;; This function actually reads the init files.
919 (inner
920 (function
921 (lambda ()
922 (if init-file-user
923 (let ((user-init-file-1
4e0a3971 924 (cond
752ef254
GM
925 ((eq system-type 'ms-dos)
926 (concat "~" init-file-user "/_emacs"))
927 ((eq system-type 'windows-nt)
fe7ecaf2 928 ;; Prefer .emacs on Windows.
752ef254
GM
929 (if (directory-files "~" nil "^\\.emacs\\(\\.elc?\\)?$")
930 "~/.emacs"
fe7ecaf2
JR
931 ;; Also support _emacs for compatibility.
932 (if (directory-files "~" nil "^_emacs\\(\\.elc?\\)?$")
933 "~/_emacs"
934 ;; But default to .emacs if _emacs does not exist.
935 "~/.emacs")))
f1180544 936 ((eq system-type 'vax-vms)
752ef254 937 "sys$login:.emacs")
4e0a3971 938 (t
752ef254
GM
939 (concat "~" init-file-user "/.emacs")))))
940 ;; This tells `load' to store the file name found
941 ;; into user-init-file.
942 (setq user-init-file t)
943 (load user-init-file-1 t t)
f1180544 944
a04d5983
RS
945 (when (eq user-init-file t)
946 ;; If we did not find ~/.emacs, try
c3ab3701 947 ;; ~/.emacs.d/init.el.
a04d5983
RS
948 (let ((otherfile
949 (expand-file-name
c3ab3701 950 "init"
a04d5983 951 (file-name-as-directory
c3ab3701 952 (concat "~" init-file-user "/.emacs.d")))))
a04d5983
RS
953 (load otherfile t t)
954
955 ;; If we did not find the user's init file,
956 ;; set user-init-file conclusively.
957 ;; Don't let it be set from default.el.
958 (when (eq user-init-file t)
959 (setq user-init-file user-init-file-1))))
f1180544 960
752ef254
GM
961 ;; If we loaded a compiled file, set
962 ;; `user-init-file' to the source version if that
963 ;; exists.
964 (when (and user-init-file
965 (equal (file-name-extension user-init-file)
966 "elc"))
967 (let* ((source (file-name-sans-extension user-init-file))
968 (alt (concat source ".el")))
969 (setq source (cond ((file-exists-p alt) alt)
970 ((file-exists-p source) source)
971 (t nil)))
972 (when source
973 (when (file-newer-than-file-p source user-init-file)
974 (message "Warning: %s is newer than %s"
975 source user-init-file)
976 (sit-for 1))
977 (setq user-init-file source))))
f1180544 978
bca8c7be 979 (unless inhibit-default-init
1cff9ad1 980 (let ((inhibit-startup-screen nil))
bca8c7be
MS
981 ;; Users are supposed to be told their rights.
982 ;; (Plus how to get help and how to undo.)
983 ;; Don't you dare turn this off for anyone
984 ;; except yourself.
985 (load "default" t t)))))))))
752ef254
GM
986 (if init-file-debug
987 ;; Do this without a condition-case if the user wants to debug.
988 (funcall inner)
989 (condition-case error
990 (progn
991 (funcall inner)
992 (setq init-file-had-error nil))
993 (error
994 (let ((message-log-max nil))
995 (save-excursion
996 (set-buffer (get-buffer-create "*Messages*"))
997 (insert "\n\n"
998 (format "An error has occurred while loading `%s':\n\n"
999 user-init-file)
1000 (format "%s%s%s"
1001 (get (car error) 'error-message)
1002 (if (cdr error) ": " "")
f5b6cffd 1003 (mapconcat (lambda (s) (prin1-to-string s t)) (cdr error) ", "))
752ef254 1004 "\n\n"
f5b6cffd
KS
1005 "To ensure normal operation, you should investigate and remove the\n"
1006 "cause of the error in your initialization file. Start Emacs with\n"
1007 "the `--debug-init' option to view a complete error backtrace.\n\n"))
752ef254
GM
1008 (message "Error in init file: %s%s%s"
1009 (get (car error) 'error-message)
1010 (if (cdr error) ": " "")
1011 (mapconcat 'prin1-to-string (cdr error) ", "))
f5b6cffd
KS
1012 (let ((pop-up-windows nil))
1013 (pop-to-buffer "*Messages*"))
752ef254 1014 (setq init-file-had-error t)))))
ac3186fd 1015
9c8b2150
RS
1016 (if (and deactivate-mark transient-mark-mode)
1017 (with-current-buffer (window-buffer)
1018 (deactivate-mark)))
1019
d5bd2558
GM
1020 ;; If the user has a file of abbrevs, read it (unless -batch).
1021 (when (and (not noninteractive)
1022 (file-exists-p abbrev-file-name)
2863a9be 1023 (file-readable-p abbrev-file-name))
ac3186fd
RS
1024 (quietly-read-abbrev-file abbrev-file-name))
1025
70b199c3
RS
1026 ;; If the abbrevs came entirely from the init file or the
1027 ;; abbrevs file, they do not need saving.
1028 (setq abbrevs-changed nil)
1029
752ef254
GM
1030 ;; If we can tell that the init file altered debug-on-error,
1031 ;; arrange to preserve the value that it set up.
1032 (or (eq debug-on-error debug-on-error-initial)
1033 (setq debug-on-error-should-be-set t
1034 debug-on-error-from-init-file debug-on-error)))
1035 (if debug-on-error-should-be-set
1036 (setq debug-on-error debug-on-error-from-init-file))
1037 (unless (or default-enable-multibyte-characters
1038 (eq orig-enable-multibyte default-enable-multibyte-characters))
1039 ;; Init file changed to unibyte. Reset existing multibyte
1040 ;; buffers (probably *scratch*, *Messages*, *Minibuff-0*).
1041 ;; Arguably this should only be done if they're free of
1042 ;; multibyte characters.
e18c18e8
JB
1043 (mapc (lambda (buffer)
1044 (with-current-buffer buffer
1045 (if enable-multibyte-characters
1046 (set-buffer-multibyte nil))))
1047 (buffer-list))
752ef254
GM
1048 ;; Also re-set the language environment in case it was
1049 ;; originally done before unibyte was set and is sensitive to
1050 ;; unibyte (display table, terminal coding system &c).
1051 (set-language-environment current-language-environment)))
f1180544 1052
752ef254 1053 ;; Do this here in case the init file sets mail-host-address.
5b88a2c5 1054 (if (equal user-mail-address "")
cee0c996
EZ
1055 (setq user-mail-address (or (getenv "EMAIL")
1056 (concat (user-login-name) "@"
1057 (or mail-host-address
1058 (system-name))))))
752ef254 1059
d60b49ac
DN
1060 ;; Originally face attributes were specified via
1061 ;; `font-lock-face-attributes'. Users then changed the default
1062 ;; face attributes by setting that variable. However, we try and
1063 ;; be back-compatible and respect its value if set except for
1064 ;; faces where M-x customize has been used to save changes for the
1065 ;; face.
1066 (when (boundp 'font-lock-face-attributes)
1067 (let ((face-attributes font-lock-face-attributes))
1068 (while face-attributes
1069 (let* ((face-attribute (pop face-attributes))
1070 (face (car face-attribute)))
1071 ;; Rustle up a `defface' SPEC from a
1072 ;; `font-lock-face-attributes' entry.
1073 (unless (get face 'saved-face)
1074 (let ((foreground (nth 1 face-attribute))
1075 (background (nth 2 face-attribute))
1076 (bold-p (nth 3 face-attribute))
1077 (italic-p (nth 4 face-attribute))
1078 (underline-p (nth 5 face-attribute))
1079 face-spec)
1080 (when foreground
1081 (setq face-spec (cons ':foreground (cons foreground face-spec))))
1082 (when background
1083 (setq face-spec (cons ':background (cons background face-spec))))
1084 (when bold-p
1085 (setq face-spec (append '(:weight bold) face-spec)))
1086 (when italic-p
1087 (setq face-spec (append '(:slant italic) face-spec)))
1088 (when underline-p
1089 (setq face-spec (append '(:underline t) face-spec)))
1090 (face-spec-set face (list (list t face-spec)) nil)))))))
1091
752ef254
GM
1092 ;; If parameter have been changed in the init file which influence
1093 ;; face realization, clear the face cache so that new faces will
1094 ;; be realized.
1095 (unless (and (eq scalable-fonts-allowed old-scalable-fonts-allowed)
1096 (eq font-list-limit old-font-list-limit)
1097 (eq face-ignored-fonts old-face-ignored-fonts))
1098 (clear-face-cache)))
f1180544 1099
e3bd99f5
RM
1100 (run-hooks 'after-init-hook)
1101
1fc67c11 1102 ;; Decode all default-directory.
cea927ed
KH
1103 (if (and default-enable-multibyte-characters locale-coding-system)
1104 (save-excursion
1105 (dolist (elt (buffer-list))
1106 (set-buffer elt)
1107 (if default-directory
1108 (setq default-directory
1109 (decode-coding-string default-directory
1110 locale-coding-system t))))
1111 (setq command-line-default-directory
1112 (decode-coding-string command-line-default-directory
1113 locale-coding-system t))))
1114
a726e0d1
JB
1115 ;; If *scratch* exists and init file didn't change its mode, initialize it.
1116 (if (get-buffer "*scratch*")
694210c4 1117 (with-current-buffer "*scratch*"
a726e0d1 1118 (if (eq major-mode 'fundamental-mode)
26cdce23 1119 (funcall initial-major-mode))))
f1180544 1120
a726e0d1
JB
1121 ;; Load library for our terminal type.
1122 ;; User init file can set term-file-prefix to nil to prevent this.
bca8c7be 1123 (unless (or noninteractive
cd85984a
KL
1124 initial-window-system)
1125 (tty-run-terminal-initialization (selected-frame)))
a726e0d1 1126
5777a167
RS
1127 ;; Update the out-of-memory error message based on user's key bindings
1128 ;; for save-some-buffers.
1129 (setq memory-signal-data
1130 (list 'error
1131 (substitute-command-keys "Memory exhausted--use \\[save-some-buffers] then exit and restart Emacs")))
1132
03e3c30a 1133 ;; Process the remaining args.
a726e0d1
JB
1134 (command-line-1 (cdr command-line-args))
1135
1136 ;; If -batch, terminate after processing the command options.
ca57f55d
JD
1137 (if noninteractive (kill-emacs t))
1138
1139 ;; Run emacs-session-restore (session management) if started by
1140 ;; the session manager and we have a session manager connection.
bca8c7be
MS
1141 (if (and (boundp 'x-session-previous-id)
1142 (stringp x-session-previous-id))
a99df87d
RS
1143 (with-no-warnings
1144 (emacs-session-restore x-session-previous-id))))
a726e0d1 1145
46cfd295 1146(defcustom initial-scratch-message (purecopy "\
3b79c219
GM
1147;; This buffer is for notes you don't want to save, and for Lisp evaluation.
1148;; If you want to create a file, visit that file with C-x C-f,
1149;; then enter the text in that file's own buffer.
9fe3219e 1150
46cfd295 1151")
9fe3219e 1152 "Initial message displayed in *scratch* buffer at startup.
249d9683 1153If this is nil, no message will be displayed.
490a1ad6 1154If `inhibit-startup-screen' is non-nil, then no message is displayed,
249d9683 1155regardless of the value of this variable."
fa071a47
RS
1156 :type '(choice (text :tag "Message")
1157 (const :tag "none" nil))
1158 :group 'initialization)
9fe3219e 1159
ce9ded5d
GM
1160\f
1161;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1162;;; Fancy splash screen
1163;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1164
fad930b6 1165(defvar fancy-startup-text
422abbfd 1166 '((:face (variable-pitch (:foreground "red"))
22a58255 1167 "Welcome to "
6e0cfad3
JL
1168 :link ("GNU Emacs"
1169 (lambda (button) (browse-url "http://www.gnu.org/software/emacs/"))
1170 "Browse http://www.gnu.org/software/emacs/")
22a58255
CY
1171 ", one component of the "
1172 :link
1173 (lambda ()
1174 (if (eq system-type 'gnu/linux)
6e0cfad3
JL
1175 '("GNU/Linux"
1176 (lambda (button) (browse-url "http://www.gnu.org/gnu/linux-and-gnu.html"))
1177 "Browse http://www.gnu.org/gnu/linux-and-gnu.html")
1178 '("GNU" (lambda (button) (describe-project))
1179 "Display info on the GNU project")))
22a58255 1180 " operating system.\n"
34acda03
GM
1181 :face variable-pitch "To quit a partially entered command, type "
1182 :face default "Control-g"
1183 :face variable-pitch ".\n\n"
fad930b6 1184 :link ("Emacs Tutorial" (lambda (button) (help-with-tutorial)))
22a58255 1185 "\tLearn basic keystroke commands"
fad930b6
RS
1186 (lambda ()
1187 (let* ((en "TUTORIAL")
1188 (tut (or (get-language-info current-language-environment
1189 'tutorial)
1190 en))
1191 (title (with-temp-buffer
1192 (insert-file-contents
1193 (expand-file-name tut tutorial-directory)
1194 nil 0 256)
1195 (search-forward ".")
1196 (buffer-substring (point-min) (1- (point))))))
1197 ;; If there is a specific tutorial for the current language
1198 ;; environment and it is not English, append its title.
1199 (if (string= en tut)
1200 ""
1201 (concat " (" title ")"))))
1202 "\n"
1203 :face variable-pitch
fad930b6 1204 :link ("Emacs Guided Tour"
6e0cfad3
JL
1205 (lambda (button) (browse-url "http://www.gnu.org/software/emacs/tour/"))
1206 "Browse http://www.gnu.org/software/emacs/tour/")
fad930b6 1207 "\tOverview of Emacs features\n"
490a1ad6
JL
1208 :link ("View Emacs Manual" (lambda (button) (info-emacs-manual)))
1209 "\tView the Emacs manual using Info\n"
fad930b6
RS
1210 :link ("Absence of Warranty" (lambda (button) (describe-no-warranty)))
1211 "\tGNU Emacs comes with "
422abbfd 1212 :face (variable-pitch (:slant oblique))
fad930b6
RS
1213 "ABSOLUTELY NO WARRANTY\n"
1214 :face variable-pitch
1215 :link ("Copying Conditions" (lambda (button) (describe-copying)))
1216 "\tConditions for redistributing and changing Emacs\n"
22a58255
CY
1217 :link ("Ordering Manuals" (lambda (button) (view-order-manuals)))
1218 "\tPurchasing printed copies of manuals\n"
fad930b6 1219 "\n"))
ce9ded5d
GM
1220 "A list of texts to show in the middle part of splash screens.
1221Each element in the list should be a list of strings or pairs
1222`:face FACE', like `fancy-splash-insert' accepts them.")
1223
1d865f15 1224(defvar fancy-about-text
422abbfd 1225 '((:face (variable-pitch (:foreground "red"))
22a58255 1226 "This is "
6e0cfad3
JL
1227 :link ("GNU Emacs"
1228 (lambda (button) (browse-url "http://www.gnu.org/software/emacs/"))
1229 "Browse http://www.gnu.org/software/emacs/")
22a58255
CY
1230 ", one component of the "
1231 :link
1232 (lambda ()
1233 (if (eq system-type 'gnu/linux)
6e0cfad3
JL
1234 '("GNU/Linux"
1235 (lambda (button) (browse-url "http://www.gnu.org/gnu/linux-and-gnu.html"))
1236 "Browse http://www.gnu.org/gnu/linux-and-gnu.html")
1237 '("GNU" (lambda (button) (describe-project))
1238 "Display info on the GNU project.")))
22a58255 1239 " operating system.\n"
34acda03 1240 :face (lambda ()
422abbfd
RS
1241 (list 'variable-pitch
1242 (list :foreground
1243 (if (eq (frame-parameter nil 'background-mode) 'dark)
1244 "cyan" "darkblue"))))
22a58255
CY
1245 "\n"
1246 (lambda () (emacs-version))
1247 "\n"
422abbfd 1248 :face (variable-pitch (:height 0.5))
22a58255
CY
1249 (lambda () emacs-copyright)
1250 "\n\n"
1251 :face variable-pitch
490a1ad6
JL
1252 :link ("Authors"
1253 (lambda (button)
1254 (view-file (expand-file-name "AUTHORS" data-directory))
1255 (goto-char (point-min))))
1256 "\tMany people have contributed code included in GNU Emacs\n"
1257 :link ("Contributing"
1258 (lambda (button)
1259 (view-file (expand-file-name "CONTRIBUTE" data-directory))
1260 (goto-char (point-min))))
1261 "\tHow to contribute improvements to Emacs\n"
1262 "\n"
fad930b6
RS
1263 :link ("GNU and Freedom" (lambda (button) (describe-project)))
1264 "\tWhy we developed GNU Emacs, and the GNU operating system\n"
1265 :link ("Absence of Warranty" (lambda (button) (describe-no-warranty)))
1266 "\tGNU Emacs comes with "
422abbfd 1267 :face (variable-pitch (:slant oblique))
fad930b6
RS
1268 "ABSOLUTELY NO WARRANTY\n"
1269 :face variable-pitch
1270 :link ("Copying Conditions" (lambda (button) (describe-copying)))
1271 "\tConditions for redistributing and changing Emacs\n"
1272 :link ("Getting New Versions" (lambda (button) (describe-distribution)))
1273 "\tHow to obtain the latest version of Emacs\n"
1cff9ad1
JL
1274 :link ("Ordering Manuals" (lambda (button) (view-order-manuals)))
1275 "\tBuying printed manuals from the FSF\n"
fad930b6
RS
1276 "\n"
1277 :link ("Emacs Tutorial" (lambda (button) (help-with-tutorial)))
1278 "\tLearn basic Emacs keystroke commands"
1279 (lambda ()
1280 (let* ((en "TUTORIAL")
1281 (tut (or (get-language-info current-language-environment
1282 'tutorial)
1283 en))
1284 (title (with-temp-buffer
1285 (insert-file-contents
1286 (expand-file-name tut tutorial-directory)
1287 nil 0 256)
1288 (search-forward ".")
1289 (buffer-substring (point-min) (1- (point))))))
1290 ;; If there is a specific tutorial for the current language
1291 ;; environment and it is not English, append its title.
1292 (if (string= en tut)
1293 ""
1294 (concat " (" title ")"))))
1295 "\n"
1296 :link ("Emacs Guided Tour"
6e0cfad3
JL
1297 (lambda (button) (browse-url "http://www.gnu.org/software/emacs/tour/"))
1298 "Browse http://www.gnu.org/software/emacs/tour/")
fad930b6
RS
1299 "\tSee an overview of the many facilities of GNU Emacs"
1300 ))
1d865f15
JL
1301 "A list of texts to show in the middle part of the About screen.
1302Each element in the list should be a list of strings or pairs
1303`:face FACE', like `fancy-splash-insert' accepts them.")
1304
ce9ded5d 1305
fb275c02 1306(defgroup fancy-splash-screen ()
a01bb1db 1307 "Fancy splash screen when Emacs starts."
fb275c02 1308 :version "21.1"
a01bb1db
GM
1309 :group 'initialization)
1310
8ad8561b
GM
1311(defcustom fancy-splash-image nil
1312 "*The image to show in the splash screens, or nil for defaults."
a01bb1db 1313 :group 'fancy-splash-screen
8ad8561b
GM
1314 :type '(choice (const :tag "Default" nil)
1315 (file :tag "File")))
ce9ded5d
GM
1316
1317
aeb6faec 1318(defvar splash-screen-keymap
26cdce23
JL
1319 (let ((map (make-sparse-keymap)))
1320 (suppress-keymap map)
1321 (set-keymap-parent map button-buffer-map)
aeb6faec
JL
1322 (define-key map "\C-?" 'scroll-down)
1323 (define-key map " " 'scroll-up)
1324 (define-key map "q" 'exit-splash-screen)
26cdce23
JL
1325 map)
1326 "Keymap for splash screen buffer.")
1327
f645586f
GM
1328;; These are temporary storage areas for the splash screen display.
1329
ce9ded5d
GM
1330(defun fancy-splash-insert (&rest args)
1331 "Insert text into the current buffer, with faces.
22a58255
CY
1332Arguments from ARGS should be either strings; functions called
1333with no args that return a string; pairs `:face FACE', where FACE
1334is a face specification usable with `put-text-property'; or pairs
1335`:link LINK' where LINK is a list of arguments to pass to
6e0cfad3
JL
1336`insert-button', of the form (LABEL ACTION [HELP-ECHO]), which
1337specifies the button's label, `action' property and help-echo string.
1338FACE and LINK can also be functions, which are evaluated to obtain
1339a face or button specification."
ce9ded5d
GM
1340 (let ((current-face nil))
1341 (while args
26cdce23 1342 (cond ((eq (car args) :face)
22a58255
CY
1343 (setq args (cdr args) current-face (car args))
1344 (if (functionp current-face)
1345 (setq current-face (funcall current-face))))
26cdce23
JL
1346 ((eq (car args) :link)
1347 (setq args (cdr args))
1348 (let ((spec (car args)))
22a58255
CY
1349 (if (functionp spec)
1350 (setq spec (funcall spec)))
26cdce23
JL
1351 (insert-button (car spec)
1352 'face (list 'link current-face)
1353 'action (cadr spec)
6e0cfad3
JL
1354 'help-echo (concat "mouse-2, RET: "
1355 (or (nth 2 spec)
1356 "Follow this link"))
26cdce23
JL
1357 'follow-link t)))
1358 (t (insert (propertize (let ((it (car args)))
1359 (if (functionp it)
1360 (funcall it)
1361 it))
1362 'face current-face
d4a629de 1363 'help-echo (startup-echo-area-message)))))
ce9ded5d
GM
1364 (setq args (cdr args)))))
1365
1366
1367(defun fancy-splash-head ()
1368 "Insert the head part of the splash screen into the current buffer."
51e8cfdd
GM
1369 (let* ((image-file (cond ((stringp fancy-splash-image)
1370 fancy-splash-image)
1371 ((and (display-color-p)
1372 (image-type-available-p 'xpm))
f51a80af
GM
1373 (if (and (fboundp 'x-display-planes)
1374 (= (funcall 'x-display-planes) 8))
1375 "splash8.xpm"
1376 "splash.xpm"))
1377 (t "splash.pbm")))
51e8cfdd 1378 (img (create-image image-file))
ce9ded5d
GM
1379 (image-width (and img (car (image-size img))))
1380 (window-width (window-width (selected-window))))
1381 (when img
1382 (when (> window-width image-width)
f645586f 1383 ;; Center the image in the window.
6b61353c
KH
1384 (insert (propertize " " 'display
1385 `(space :align-to (+ center (-0.5 . ,img)))))
f645586f 1386
e7f3afa9
MB
1387 ;; Change the color of the XPM version of the splash image
1388 ;; so that it is visible with a dark frame background.
1389 (when (and (memq 'xpm img)
1390 (eq (frame-parameter nil 'background-mode) 'dark))
1391 (setq img (append img '(:color-symbols (("#000000" . "gray30"))))))
1392
aeb6faec
JL
1393 ;; Insert the image with a help-echo and a link.
1394 (make-button (prog1 (point) (insert-image img)) (point)
1395 'face 'default
6e0cfad3 1396 'help-echo "mouse-2, RET: Browse http://www.gnu.org/"
aeb6faec
JL
1397 'action (lambda (button) (browse-url "http://www.gnu.org/"))
1398 'follow-link t)
22a58255
CY
1399 (insert "\n\n")))))
1400
1cff9ad1 1401(defun fancy-startup-tail (&optional concise)
ce9ded5d 1402 "Insert the tail part of the splash screen into the current buffer."
95fadcca
GM
1403 (let ((fg (if (eq (frame-parameter nil 'background-mode) 'dark)
1404 "cyan" "darkblue")))
1cff9ad1
JL
1405 (unless concise
1406 (fancy-splash-insert
1407 :face 'variable-pitch
1408 "\nTo start... "
1409 :link '("Open a File"
6e0cfad3
JL
1410 (lambda (button) (call-interactively 'find-file))
1411 "Specify a new file's name, to edit the file")
1cff9ad1
JL
1412 " "
1413 :link '("Open Home Directory"
6e0cfad3
JL
1414 (lambda (button) (dired "~"))
1415 "Open your home directory, to operate on its files")
1cff9ad1
JL
1416 " "
1417 :link '("Customize Startup"
6e0cfad3
JL
1418 (lambda (button) (customize-group 'initialization))
1419 "Change initialization settings including this screen")
1cff9ad1 1420 "\n"))
422abbfd 1421 (fancy-splash-insert :face `(variable-pitch (:foreground ,fg))
95fadcca
GM
1422 "\nThis is "
1423 (emacs-version)
1424 "\n"
422abbfd 1425 :face '(variable-pitch (:height 0.5))
22a58255
CY
1426 emacs-copyright
1427 "\n")
ed638cc9
RS
1428 (and auto-save-list-file-prefix
1429 ;; Don't signal an error if the
1430 ;; directory for auto-save-list files
1431 ;; does not yet exist.
1432 (file-directory-p (file-name-directory
1433 auto-save-list-file-prefix))
1434 (directory-files
1435 (file-name-directory auto-save-list-file-prefix)
1436 nil
1437 (concat "\\`"
1438 (regexp-quote (file-name-nondirectory
1439 auto-save-list-file-prefix)))
1440 t)
422abbfd 1441 (fancy-splash-insert :face '(variable-pitch (:foreground "red"))
1d865f15 1442 "\nIf an Emacs session crashed recently, "
5b309ebf
RS
1443 "type "
1444 :face '(fixed-pitch :foreground "red")
1445 "Meta-x recover-session RET"
422abbfd 1446 :face '(variable-pitch (:foreground "red"))
5b309ebf 1447 "\nto recover"
22a58255
CY
1448 " the files you were editing."))
1449
1cff9ad1
JL
1450 (when concise
1451 (fancy-splash-insert
3d9d55e6 1452 :face 'variable-pitch "\n"
09723615
JL
1453 :link '("Dismiss this startup screen"
1454 (lambda (button)
1455 (when startup-screen-inhibit-startup-screen
1456 (customize-set-variable 'inhibit-startup-screen t)
1457 (customize-mark-to-save 'inhibit-startup-screen)
1458 (custom-save-all))
1459 (let ((w (get-buffer-window "*GNU Emacs*")))
1460 (and w (not (one-window-p)) (delete-window w)))
1461 (kill-buffer "*GNU Emacs*")))
1cff9ad1
JL
1462 " ")
1463 (when (or user-init-file custom-file)
1464 (let ((checked (create-image "\300\300\141\143\067\076\034\030"
22a58255 1465 'xbm t :width 8 :height 8 :background "grey75"
1cff9ad1
JL
1466 :foreground "black" :relief -2 :ascent 'center))
1467 (unchecked (create-image (make-string 8 0)
1468 'xbm t :width 8 :height 8 :background "grey75"
1469 :foreground "black" :relief -2 :ascent 'center)))
1470 (insert-button
1471 " " :on-glyph checked :off-glyph unchecked 'checked nil
1472 'display unchecked 'follow-link t
1473 'action (lambda (button)
1474 (if (overlay-get button 'checked)
1475 (progn (overlay-put button 'checked nil)
1476 (overlay-put button 'display (overlay-get button :off-glyph))
1477 (setq startup-screen-inhibit-startup-screen nil))
1478 (overlay-put button 'checked t)
1479 (overlay-put button 'display (overlay-get button :on-glyph))
1480 (setq startup-screen-inhibit-startup-screen t)))))
422abbfd 1481 (fancy-splash-insert :face '(variable-pitch (:height 0.9))
09723615 1482 " Never show it again.")))))
f645586f 1483
aeb6faec 1484(defun exit-splash-screen ()
26cdce23 1485 "Stop displaying the splash screen buffer."
f645586f 1486 (interactive)
1d865f15
JL
1487 (quit-window t))
1488
1cff9ad1 1489(defun fancy-startup-screen (&optional concise)
22a58255 1490 "Display fancy startup screen.
1cff9ad1
JL
1491If CONCISE is non-nil, display a concise version of the
1492splash screen in another window."
3d9d55e6 1493 (let ((splash-buffer (get-buffer-create "*GNU Emacs*")))
09723615 1494 (with-current-buffer splash-buffer
3d9d55e6
CY
1495 (let ((inhibit-read-only t))
1496 (erase-buffer)
4222d0a4 1497 (setq default-directory command-line-default-directory)
3d9d55e6
CY
1498 (make-local-variable 'startup-screen-inhibit-startup-screen)
1499 (if pure-space-overflow
1500 (insert pure-space-overflow-message))
1501 (unless concise
1502 (fancy-splash-head))
1503 (dolist (text fancy-startup-text)
1504 (apply #'fancy-splash-insert text)
1505 (insert "\n"))
1506 (skip-chars-backward "\n")
1507 (delete-region (point) (point-max))
1508 (insert "\n")
1509 (fancy-startup-tail concise))
1510 (use-local-map splash-screen-keymap)
1511 (setq tab-width 22
1512 buffer-read-only t)
1513 (set-buffer-modified-p nil)
1514 (if (and view-read-only (not view-mode))
1515 (view-mode-enter nil 'kill-buffer))
09723615
JL
1516 (goto-char (point-min))
1517 (forward-line (if concise 2 4)))
3d9d55e6
CY
1518 (if concise
1519 (progn
1520 (display-buffer splash-buffer)
1521 ;; If the splash screen is in a split window, fit it.
1522 (let ((window (get-buffer-window splash-buffer t)))
1523 (or (null window)
1524 (eq window (selected-window))
1525 (eq window (next-window window))
1526 (fit-window-to-buffer window))))
1527 (switch-to-buffer splash-buffer))))
22a58255
CY
1528
1529(defun fancy-about-screen ()
1530 "Display fancy About screen."
1531 (let ((frame (fancy-splash-frame)))
1532 (save-selected-window
1533 (select-frame frame)
1534 (switch-to-buffer "*About GNU Emacs*")
1535 (setq buffer-undo-list t
1536 mode-line-format (propertize "---- %b %-"
1537 'face 'mode-line-buffer-id))
1538 (let ((inhibit-read-only t))
1539 (erase-buffer)
1540 (if pure-space-overflow
1541 (insert pure-space-overflow-message))
1542 (fancy-splash-head)
1543 (dolist (text fancy-about-text)
1544 (apply #'fancy-splash-insert text)
1545 (insert "\n"))
22a58255
CY
1546 (set-buffer-modified-p nil)
1547 (goto-char (point-min))
1548 (force-mode-line-update))
aeb6faec 1549 (use-local-map splash-screen-keymap)
cb3fe757 1550 (setq tab-width 22)
22a58255 1551 (message "%s" (startup-echo-area-message))
08326816 1552 (setq buffer-read-only t)
09723615
JL
1553 (goto-char (point-min))
1554 (forward-line 3))))
6b20fb8e
RS
1555
1556(defun fancy-splash-frame ()
1557 "Return the frame to use for the fancy splash screen.
1558Returning non-nil does not mean we should necessarily
1559use the fancy splash screen, but if we do use it,
1560we put it on this frame."
1561 (let (chosen-frame)
3a321ddb 1562 (dolist (frame (append (frame-list) (list (selected-frame))))
6b20fb8e
RS
1563 (if (and (frame-visible-p frame)
1564 (not (window-minibuffer-p (frame-selected-window frame))))
1565 (setq chosen-frame frame)))
1566 chosen-frame))
f645586f 1567
285991dc
GM
1568(defun use-fancy-splash-screens-p ()
1569 "Return t if fancy splash screens should be used."
6b61353c
KH
1570 (when (and (display-graphic-p)
1571 (or (and (display-color-p)
285991dc 1572 (image-type-available-p 'xpm))
6b61353c 1573 (image-type-available-p 'pbm)))
16d2fae9
JPW
1574 (let ((frame (fancy-splash-frame)))
1575 (when frame
1576 (let* ((img (create-image (or fancy-splash-image
1577 (if (and (display-color-p)
1578 (image-type-available-p 'xpm))
1579 "splash.xpm" "splash.pbm"))))
a68ccb40
RS
1580 (image-height (and img (cdr (image-size img nil frame))))
1581 ;; We test frame-height so that, if the frame is split
1582 ;; by displaying a warning, that doesn't cause the normal
1583 ;; splash screen to be used.
1584 (frame-height (1- (frame-height frame))))
1585 (> frame-height (+ image-height 19)))))))
285991dc
GM
1586
1587
1d865f15
JL
1588(defun normal-splash-screen (&optional startup)
1589 "Display non-graphic splash screen.
1590If optional argument STARTUP is non-nil, display the startup screen
1591after Emacs starts. If STARTUP is nil, display the About screen."
82e736c1 1592 (let ((prev-buffer (current-buffer)))
1d865f15
JL
1593 (with-current-buffer (get-buffer-create "*About GNU Emacs*")
1594 (setq buffer-read-only nil)
1595 (erase-buffer)
4222d0a4 1596 (setq default-directory command-line-default-directory)
1d865f15
JL
1597 (set (make-local-variable 'tab-width) 8)
1598 (if (not startup)
1599 (set (make-local-variable 'mode-line-format)
1600 (propertize "---- %b %-" 'face 'mode-line-buffer-id)))
1601
1602 (if pure-space-overflow
22a58255 1603 (insert pure-space-overflow-message))
260a5020 1604
1d865f15
JL
1605 ;; The convention for this piece of code is that
1606 ;; each piece of output starts with one or two newlines
1607 ;; and does not end with any newlines.
22a58255 1608 (insert (if startup "Welcome to GNU Emacs" "This is GNU Emacs"))
1d865f15
JL
1609 (insert
1610 (if (eq system-type 'gnu/linux)
1611 ", one component of the GNU/Linux operating system.\n"
1612 ", a part of the GNU operating system.\n"))
1613
1614 (if startup
1615 (if (display-mouse-p)
1616 ;; The user can use the mouse to activate menus
1617 ;; so give help in terms of menu items.
fad930b6 1618 (normal-mouse-startup-screen)
c61453ea 1619
e349ae3b 1620 ;; No mouse menus, so give help using kbd commands.
fad930b6 1621 (normal-no-mouse-startup-screen))
e349ae3b 1622
fad930b6 1623 (normal-about-screen))
1d865f15
JL
1624
1625 ;; The rest of the startup screen is the same on all
1626 ;; kinds of terminals.
1627
1628 ;; Give information on recovering, if there was a crash.
1629 (and startup
1630 auto-save-list-file-prefix
1631 ;; Don't signal an error if the
1632 ;; directory for auto-save-list files
1633 ;; does not yet exist.
1634 (file-directory-p (file-name-directory
1635 auto-save-list-file-prefix))
1636 (directory-files
1637 (file-name-directory auto-save-list-file-prefix)
1638 nil
1639 (concat "\\`"
1640 (regexp-quote (file-name-nondirectory
1641 auto-save-list-file-prefix)))
1642 t)
1643 (insert "\n\nIf an Emacs session crashed recently, "
1644 "type Meta-x recover-session RET\nto recover"
1645 " the files you were editing.\n"))
26cdce23 1646
1d865f15 1647 (use-local-map splash-screen-keymap)
e349ae3b 1648
1d865f15
JL
1649 ;; Display the input that we set up in the buffer.
1650 (set-buffer-modified-p nil)
1651 (setq buffer-read-only t)
1652 (if (and view-read-only (not view-mode))
1653 (view-mode-enter nil 'kill-buffer))
1654 (switch-to-buffer "*About GNU Emacs*")
1655 (if startup (rename-buffer "*GNU Emacs*" t))
1656 (goto-char (point-min)))))
82e736c1 1657
fad930b6
RS
1658(defun normal-mouse-startup-screen ()
1659 ;; The user can use the mouse to activate menus
1660 ;; so give help in terms of menu items.
1661 (insert "\
09723615 1662To follow a link, click Mouse-1 on it, or move to it and type RET.
26cdce23
JL
1663To quit a partially entered command, type Control-g.\n")
1664
fad930b6
RS
1665 (insert "\nImportant Help menu items:\n")
1666 (insert-button "Emacs Tutorial"
1667 'action (lambda (button) (help-with-tutorial))
1668 'follow-link t)
1669 (insert "\t\tLearn basic Emacs keystroke commands\n")
1670 (insert-button "Read the Emacs Manual"
1671 'action (lambda (button) (info-emacs-manual))
1672 'follow-link t)
1673 (insert "\tView the Emacs manual using Info\n")
1674 (insert-button "\(Non)Warranty"
1675 'action (lambda (button) (describe-no-warranty))
1676 'follow-link t)
1677 (insert "\t\tGNU Emacs comes with ABSOLUTELY NO WARRANTY\n")
1678 (insert-button "Copying Conditions"
1679 'action (lambda (button) (describe-copying))
1680 'follow-link t)
1681 (insert "\tConditions for redistributing and changing Emacs\n")
1682 (insert-button "More Manuals / Ordering Manuals"
1683 'action (lambda (button) (view-order-manuals))
1684 'follow-link t)
1685 (insert " How to order printed manuals from the FSF\n")
1686
1687 (insert "\nUseful tasks:\n")
1688 (insert-button "Visit New File"
1689 'action (lambda (button) (call-interactively 'find-file))
1690 'follow-link t)
1691 (insert "\t\tSpecify a new file's name, to edit the file\n")
1692 (insert-button "Open Home Directory"
1693 'action (lambda (button) (dired "~"))
1694 'follow-link t)
1695 (insert "\tOpen your home directory, to operate on its files\n")
1696 (insert-button "Customize Startup"
1697 'action (lambda (button) (customize-group 'initialization))
1698 'follow-link t)
1699 (insert "\tChange initialization settings including this screen\n")
1700
1701 (insert "\n" (emacs-version)
1702 "\n" emacs-copyright))
1703
1704;; No mouse menus, so give help using kbd commands.
1705(defun normal-no-mouse-startup-screen ()
1706
1707 ;; If keys have their default meanings,
1708 ;; use precomputed string to save lots of time.
1709 (if (and (eq (key-binding "\C-h") 'help-command)
1710 (eq (key-binding "\C-xu") 'advertised-undo)
1711 (eq (key-binding "\C-x\C-c") 'save-buffers-kill-terminal)
1712 (eq (key-binding "\C-ht") 'help-with-tutorial)
1713 (eq (key-binding "\C-hi") 'info)
1714 (eq (key-binding "\C-hr") 'info-emacs-manual)
1715 (eq (key-binding "\C-h\C-n") 'view-emacs-news))
1716 (progn
1717 (insert "
1718Get help\t C-h (Hold down CTRL and press h)
cd6ab24f 1719")
fad930b6
RS
1720 (insert-button "Emacs manual"
1721 'action (lambda (button) (info-emacs-manual))
1722 'follow-link t)
1723 (insert " C-h r\t")
1724 (insert-button "Browse manuals"
1725 'action (lambda (button) (Info-directory))
1726 'follow-link t)
1727 (insert "\t C-h i
cd6ab24f 1728")
fad930b6
RS
1729 (insert-button "Emacs tutorial"
1730 'action (lambda (button) (help-with-tutorial))
1731 'follow-link t)
1732 (insert " C-h t\tUndo changes\t C-x u
cd6ab24f 1733")
fad930b6
RS
1734 (insert-button "Buy manuals"
1735 'action (lambda (button) (view-order-manuals))
1736 'follow-link t)
1737 (insert "\t C-h C-m\tExit Emacs\t C-x C-c"))
5777a167 1738
fad930b6
RS
1739 (insert (format "
1740Get help\t %s
cd6ab24f 1741"
fad930b6
RS
1742 (let ((where (where-is-internal
1743 'help-command nil t)))
1744 (if where
1745 (key-description where)
1746 "M-x help"))))
1747 (insert-button "Emacs manual"
1748 'action (lambda (button) (info-emacs-manual))
1749 'follow-link t)
1750 (insert (substitute-command-keys"\t \\[info-emacs-manual]\t"))
1751 (insert-button "Browse manuals"
1752 'action (lambda (button) (Info-directory))
1753 'follow-link t)
1754 (insert (substitute-command-keys "\t \\[info]
cd6ab24f 1755"))
fad930b6
RS
1756 (insert-button "Emacs tutorial"
1757 'action (lambda (button) (help-with-tutorial))
1758 'follow-link t)
1759 (insert (substitute-command-keys
1760 "\t \\[help-with-tutorial]\tUndo changes\t \\[advertised-undo]
cd6ab24f 1761"))
fad930b6
RS
1762 (insert-button "Buy manuals"
1763 'action (lambda (button) (view-order-manuals))
1764 'follow-link t)
1765 (insert (substitute-command-keys
1766 "\t \\[view-order-manuals]\tExit Emacs\t \\[save-buffers-kill-terminal]")))
1767
1768 ;; Say how to use the menu bar with the keyboard.
1769 (insert "\n")
1770 (insert-button "Activate menubar"
1771 'action (lambda (button) (tmm-menubar))
1772 'follow-link t)
1773 (if (and (eq (key-binding "\M-`") 'tmm-menubar)
1774 (eq (key-binding [f10]) 'tmm-menubar))
1775 (insert " F10 or ESC ` or M-`")
1776 (insert (substitute-command-keys " \\[tmm-menubar]")))
1777
1778 ;; Many users seem to have problems with these.
1779 (insert "
c61453ea
PJ
1780\(`C-' means use the CTRL key. `M-' means use the Meta (or Alt) key.
1781If you have no Meta key, you may instead type ESC followed by the character.)")
1782
fad930b6
RS
1783 ;; Insert links to useful tasks
1784 (insert "\nUseful tasks:\n")
1785
1786 (insert-button "Visit New File"
1787 'action (lambda (button) (call-interactively 'find-file))
1788 'follow-link t)
1789 (insert "\t\t\t")
1790 (insert-button "Open Home Directory"
1791 'action (lambda (button) (dired "~"))
1792 'follow-link t)
1793 (insert "\n")
1794
1795 (insert-button "Customize Startup"
1796 'action (lambda (button) (customize-group 'initialization))
1797 'follow-link t)
1798 (insert "\t\t")
1799 (insert-button "Open *scratch* buffer"
1800 'action (lambda (button) (switch-to-buffer
1801 (get-buffer-create "*scratch*")))
1802 'follow-link t)
1803 (insert "\n")
1804 (insert "\n" (emacs-version) "\n" emacs-copyright "\n")
1805
1806 (if (and (eq (key-binding "\C-h\C-c") 'describe-copying)
1807 (eq (key-binding "\C-h\C-d") 'describe-distribution)
1808 (eq (key-binding "\C-h\C-w") 'describe-no-warranty))
1809 (progn
1810 (insert
490a1ad6 1811 "
cd6ab24f 1812GNU Emacs comes with ABSOLUTELY NO WARRANTY; type C-h C-w for ")
fad930b6
RS
1813 (insert-button "full details"
1814 'action (lambda (button) (describe-no-warranty))
1815 'follow-link t)
1816 (insert ".
c61453ea 1817Emacs is Free Software--Free as in Freedom--so you can redistribute copies
cd6ab24f 1818of Emacs and modify it; type C-h C-c to see ")
fad930b6
RS
1819 (insert-button "the conditions"
1820 'action (lambda (button) (describe-copying))
1821 'follow-link t)
1822 (insert ".
cd6ab24f 1823Type C-h C-d for information on ")
fad930b6
RS
1824 (insert-button "getting the latest version"
1825 'action (lambda (button) (describe-distribution))
1826 'follow-link t)
1827 (insert "."))
1828 (insert (substitute-command-keys
490a1ad6 1829 "
cd6ab24f 1830GNU Emacs comes with ABSOLUTELY NO WARRANTY; type \\[describe-no-warranty] for "))
fad930b6
RS
1831 (insert-button "full details"
1832 'action (lambda (button) (describe-no-warranty))
1833 'follow-link t)
1834 (insert (substitute-command-keys ".
c61453ea 1835Emacs is Free Software--Free as in Freedom--so you can redistribute copies
cd6ab24f 1836of Emacs and modify it; type \\[describe-copying] to see "))
fad930b6
RS
1837 (insert-button "the conditions"
1838 'action (lambda (button) (describe-copying))
1839 'follow-link t)
1840 (insert (substitute-command-keys".
cd6ab24f 1841Type \\[describe-distribution] for information on "))
fad930b6
RS
1842 (insert-button "getting the latest version"
1843 'action (lambda (button) (describe-distribution))
1844 'follow-link t)
1845 (insert ".")))
1846
1847(defun normal-about-screen ()
1848 (insert "\n" (emacs-version) "\n" emacs-copyright "\n\n")
1849
1850 (insert "To follow a link, click Mouse-1 on it, or move to it and type RET.\n\n")
1851
490a1ad6
JL
1852 (insert-button "Authors"
1853 'action
1854 (lambda (button)
1855 (view-file (expand-file-name "AUTHORS" data-directory))
1856 (goto-char (point-min)))
1857 'follow-link t)
1858 (insert "\t\tMany people have contributed code included in GNU Emacs\n")
1859
1860 (insert-button "Contributing"
1861 'action
1862 (lambda (button)
1863 (view-file (expand-file-name "CONTRIBUTE" data-directory))
1864 (goto-char (point-min)))
1865 'follow-link t)
1866 (insert "\tHow to contribute improvements to Emacs\n\n")
1867
fad930b6
RS
1868 (insert-button "GNU and Freedom"
1869 'action (lambda (button) (describe-project))
1870 'follow-link t)
1871 (insert "\t\tWhy we developed GNU Emacs and the GNU system\n")
1872
1873 (insert-button "Absence of Warranty"
1874 'action (lambda (button) (describe-no-warranty))
1875 'follow-link t)
1876 (insert "\tGNU Emacs comes with ABSOLUTELY NO WARRANTY\n")
1877
1878 (insert-button "Copying Conditions"
1879 'action (lambda (button) (describe-copying))
1880 'follow-link t)
1881 (insert "\tConditions for redistributing and changing Emacs\n")
1882
1883 (insert-button "Getting New Versions"
1884 'action (lambda (button) (describe-distribution))
1885 'follow-link t)
1886 (insert "\tHow to get the latest version of GNU Emacs\n")
1887
1888 (insert-button "More Manuals / Ordering Manuals"
1889 'action (lambda (button) (view-order-manuals))
1890 'follow-link t)
1891 (insert "\tBuying printed manuals from the FSF\n"))
c61453ea 1892
f645586f
GM
1893(defun startup-echo-area-message ()
1894 (if (eq (key-binding "\C-h\C-p") 'describe-project)
1cff9ad1 1895 "For information about GNU Emacs and the GNU system, type C-h C-a."
f645586f 1896 (substitute-command-keys
1cff9ad1
JL
1897 "For information about GNU Emacs and the GNU system, type \
1898\\[about-emacs].")))
ce9ded5d
GM
1899
1900
49939379 1901(defun display-startup-echo-area-message ()
15fa6db0 1902 (let ((resize-mini-windows t))
f1be5774
KL
1903 (or noninteractive ;(input-pending-p) init-file-had-error
1904 ;; t if the init file says to inhibit the echo area startup message.
1905 (and inhibit-startup-echo-area-message
1906 user-init-file
1907 (or (and (get 'inhibit-startup-echo-area-message 'saved-value)
1908 (equal inhibit-startup-echo-area-message
1909 (if (equal init-file-user "")
1910 (user-login-name)
1911 init-file-user)))
1912 ;; Wasn't set with custom; see if .emacs has a setq.
1913 (let ((buffer (get-buffer-create " *temp*")))
1914 (prog1
1915 (condition-case nil
1916 (save-excursion
1917 (set-buffer buffer)
1918 (insert-file-contents user-init-file)
1919 (re-search-forward
1920 (concat
1921 "([ \t\n]*setq[ \t\n]+"
1922 "inhibit-startup-echo-area-message[ \t\n]+"
1923 (regexp-quote
1924 (prin1-to-string
1925 (if (equal init-file-user "")
1926 (user-login-name)
1927 init-file-user)))
1928 "[ \t\n]*)")
1929 nil t))
1930 (error nil))
1931 (kill-buffer buffer)))))
1d865f15 1932 (message "%s" (startup-echo-area-message)))))
f645586f 1933
1cff9ad1 1934(defun display-startup-screen (&optional concise)
22a58255
CY
1935 "Display startup screen according to display.
1936A fancy display is used on graphic displays, normal otherwise.
49939379 1937
22a58255
CY
1938If CONCISE is non-nil, display a concise version of the startup
1939screen."
526039df 1940 ;; Prevent recursive calls from server-process-filter.
1cff9ad1 1941 (if (not (get-buffer "*GNU Emacs*"))
526039df 1942 (if (use-fancy-splash-screens-p)
22a58255
CY
1943 (fancy-startup-screen concise)
1944 (normal-splash-screen t))))
1945
1946(defun display-about-screen ()
1947 "Display the *About GNU Emacs* buffer.
1948A fancy display is used on graphic displays, normal otherwise."
1949 (interactive)
6b61353c 1950 (if (use-fancy-splash-screens-p)
1cff9ad1
JL
1951 (fancy-about-screen)
1952 (normal-splash-screen nil)))
c61453ea 1953
22a58255 1954(defalias 'about-emacs 'display-about-screen)
1cff9ad1 1955(defalias 'display-splash-screen 'display-startup-screen)
c61453ea 1956
a726e0d1 1957(defun command-line-1 (command-line-args-left)
f1be5774 1958 (display-startup-echo-area-message)
ed638cc9
RS
1959
1960 ;; Delay 2 seconds after an init file error message
1961 ;; was displayed, so user can read it.
bca8c7be
MS
1962 (when init-file-had-error
1963 (sit-for 2))
1964
cb58ea33
RS
1965 (when (and pure-space-overflow
1966 (not noninteractive))
1967 (display-warning
1968 'initialization
2dca98f3 1969 "Building Emacs overflowed pure space. (See the node Pure Storage in the Lisp manual for details.)"
cb58ea33
RS
1970 :warning))
1971
22a58255
CY
1972 (let ((file-count 0)
1973 first-file-buffer)
1974 (when command-line-args-left
1975 ;; We have command args; process them.
1976 (let ((dir command-line-default-directory)
1977 tem
1978 ;; This approach loses for "-batch -L DIR --eval "(require foo)",
1979 ;; if foo is intended to be found in DIR.
1980 ;;
1981 ;; ;; The directories listed in --directory/-L options will *appear*
1982 ;; ;; at the front of `load-path' in the order they appear on the
1983 ;; ;; command-line. We cannot do this by *placing* them at the front
1984 ;; ;; in the order they appear, so we need this variable to hold them,
1985 ;; ;; temporarily.
1986 ;; extra-load-path
1987 ;;
1988 ;; To DTRT we keep track of the splice point and modify `load-path'
1989 ;; straight away upon any --directory/-L option.
1990 splice
1991 just-files ;; t if this follows the magic -- option.
1992 ;; This includes our standard options' long versions
1993 ;; and long versions of what's on command-switch-alist.
1994 (longopts
1995 (append '(("--funcall") ("--load") ("--insert") ("--kill")
1996 ("--directory") ("--eval") ("--execute") ("--no-splash")
1997 ("--find-file") ("--visit") ("--file") ("--no-desktop"))
1998 (mapcar (lambda (elt)
1999 (list (concat "-" (car elt))))
2000 command-switch-alist)))
2001 (line 0)
2002 (column 0))
2003
2004 ;; Add the long X options to longopts.
2005 (dolist (tem command-line-x-option-alist)
2006 (if (string-match "^--" (car tem))
2007 (push (list (car tem)) longopts)))
2008
2009 ;; Loop, processing options.
2010 (while command-line-args-left
2011 (let* ((argi (car command-line-args-left))
2012 (orig-argi argi)
2013 argval completion)
2014 (setq command-line-args-left (cdr command-line-args-left))
2015
2016 ;; Do preliminary decoding of the option.
2017 (if just-files
2018 ;; After --, don't look for options; treat all args as files.
2019 (setq argi "")
2020 ;; Convert long options to ordinary options
2021 ;; and separate out an attached option argument into argval.
2022 (when (string-match "^\\(--[^=]*\\)=" argi)
2023 (setq argval (substring argi (match-end 0))
2024 argi (match-string 1 argi)))
2025 (if (equal argi "--")
2026 (setq completion nil)
2027 (setq completion (try-completion argi longopts)))
2028 (if (eq completion t)
2029 (setq argi (substring argi 1))
2030 (if (stringp completion)
2031 (let ((elt (assoc completion longopts)))
2032 (or elt
2033 (error "Option `%s' is ambiguous" argi))
2034 (setq argi (substring (car elt) 1)))
2035 (setq argval nil
2036 argi orig-argi))))
2037
2038 ;; Execute the option.
2039 (cond ((setq tem (assoc argi command-switch-alist))
2040 (if argval
2041 (let ((command-line-args-left
2042 (cons argval command-line-args-left)))
2043 (funcall (cdr tem) argi))
2044 (funcall (cdr tem) argi)))
2045
2046 ((equal argi "-no-splash")
1cff9ad1 2047 (setq inhibit-startup-screen t))
22a58255
CY
2048
2049 ((member argi '("-f" ; what the manual claims
2050 "-funcall"
2051 "-e")) ; what the source used to say
1cff9ad1 2052 (setq inhibit-startup-screen t)
22a58255
CY
2053 (setq tem (intern (or argval (pop command-line-args-left))))
2054 (if (commandp tem)
2055 (command-execute tem)
2056 (funcall tem)))
2057
2058 ((member argi '("-eval" "-execute"))
1cff9ad1 2059 (setq inhibit-startup-screen t)
22a58255
CY
2060 (eval (read (or argval (pop command-line-args-left)))))
2061
2062 ((member argi '("-L" "-directory"))
2063 (setq tem (expand-file-name
2064 (command-line-normalize-file-name
2065 (or argval (pop command-line-args-left)))))
2066 (cond (splice (setcdr splice (cons tem (cdr splice)))
2067 (setq splice (cdr splice)))
2068 (t (setq load-path (cons tem load-path)
2069 splice load-path))))
2070
2071 ((member argi '("-l" "-load"))
2072 (let* ((file (command-line-normalize-file-name
2073 (or argval (pop command-line-args-left))))
2074 ;; Take file from default dir if it exists there;
2075 ;; otherwise let `load' search for it.
2076 (file-ex (expand-file-name file)))
2077 (when (file-exists-p file-ex)
2078 (setq file file-ex))
2079 (load file nil t)))
2080
2081 ;; This is used to handle -script. It's not clear
2082 ;; we need to document it.
2083 ((member argi '("-scriptload"))
2084 (let* ((file (command-line-normalize-file-name
2085 (or argval (pop command-line-args-left))))
2086 ;; Take file from default dir.
2087 (file-ex (expand-file-name file)))
2088 (load file-ex nil t t)))
2089
2090 ((equal argi "-insert")
1cff9ad1 2091 (setq inhibit-startup-screen t)
22a58255
CY
2092 (setq tem (or argval (pop command-line-args-left)))
2093 (or (stringp tem)
2094 (error "File name omitted from `-insert' option"))
2095 (insert-file-contents (command-line-normalize-file-name tem)))
2096
2097 ((equal argi "-kill")
2098 (kill-emacs t))
2099
2100 ;; This is for when they use --no-desktop with -q, or
2101 ;; don't load Desktop in their .emacs. If desktop.el
2102 ;; _is_ loaded, it will handle this switch, and we
2103 ;; won't see it by the time we get here.
2104 ((equal argi "-no-desktop")
2105 (message "\"--no-desktop\" ignored because the Desktop package is not loaded"))
2106
2107 ((string-match "^\\+[0-9]+\\'" argi)
2108 (setq line (string-to-number argi)))
2109
2110 ((string-match "^\\+\\([0-9]+\\):\\([0-9]+\\)\\'" argi)
2111 (setq line (string-to-number (match-string 1 argi))
2112 column (string-to-number (match-string 2 argi))))
2113
2114 ((setq tem (assoc argi command-line-x-option-alist))
2115 ;; Ignore X-windows options and their args if not using X.
2116 (setq command-line-args-left
2117 (nthcdr (nth 1 tem) command-line-args-left)))
2118
2119 ((member argi '("-find-file" "-file" "-visit"))
1cff9ad1 2120 (setq inhibit-startup-screen t)
22a58255
CY
2121 ;; An explicit option to specify visiting a file.
2122 (setq tem (or argval (pop command-line-args-left)))
2123 (unless (stringp tem)
2124 (error "File name omitted from `%s' option" argi))
2125 (setq file-count (1+ file-count))
2126 (let ((file (expand-file-name
2127 (command-line-normalize-file-name tem) dir)))
2128 (if (= file-count 1)
2129 (setq first-file-buffer (find-file file))
2130 (find-file-other-window file)))
2131 (or (zerop line)
2132 (goto-line line))
2133 (setq line 0)
2134 (unless (< column 1)
2135 (move-to-column (1- column)))
2136 (setq column 0))
2137
2138 ((equal argi "--")
2139 (setq just-files t))
2140 (t
2141 ;; We have almost exhausted our options. See if the
2142 ;; user has made any other command-line options available
2143 (let ((hooks command-line-functions)
2144 (did-hook nil))
2145 (while (and hooks
2146 (not (setq did-hook (funcall (car hooks)))))
2147 (setq hooks (cdr hooks)))
2148 (if (not did-hook)
2149 ;; Presume that the argument is a file name.
2150 (progn
2151 (if (string-match "\\`-" argi)
2152 (error "Unknown option `%s'" argi))
1cff9ad1
JL
2153 (unless initial-window-system
2154 (setq inhibit-startup-screen t))
22a58255
CY
2155 (setq file-count (1+ file-count))
2156 (let ((file
2157 (expand-file-name
2158 (command-line-normalize-file-name orig-argi)
2159 dir)))
3d9d55e6
CY
2160 (cond ((= file-count 1)
2161 (setq first-file-buffer (find-file file)))
2162 (inhibit-startup-screen
2163 (find-file-other-window file))
2164 (t (find-file file))))
22a58255
CY
2165 (or (zerop line)
2166 (goto-line line))
2167 (setq line 0)
2168 (unless (< column 1)
2169 (move-to-column (1- column)))
2170 (setq column 0))))))
2171 ;; In unusual circumstances, the execution of Lisp code due
2172 ;; to command-line options can cause the last visible frame
2173 ;; to be deleted. In this case, kill emacs to avoid an
2174 ;; abort later.
2175 (unless (frame-live-p (selected-frame)) (kill-emacs nil))))))
2176
2177 (when initial-buffer-choice
2178 (cond ((eq initial-buffer-choice t)
2179 (switch-to-buffer (get-buffer-create "*scratch*")))
2180 ((stringp initial-buffer-choice)
2181 (find-file initial-buffer-choice))))
2182
1cff9ad1 2183 (if (or inhibit-startup-screen
22a58255
CY
2184 initial-buffer-choice
2185 noninteractive
2186 emacs-quick-startup)
2187
2188 ;; Not displaying a startup screen. If 3 or more files
2189 ;; visited, and not all visible, show user what they all are.
2190 (and (> file-count 2)
2191 (not noninteractive)
2192 (not inhibit-startup-buffer-menu)
2193 (or (get-buffer-window first-file-buffer)
2194 (list-buffers)))
2195
2196 ;; Display a startup screen, after some preparations.
2197
2198 ;; If there are no switches to process, we might as well
2199 ;; run this hook now, and there may be some need to do it
2200 ;; before doing any output.
2201 (run-hooks 'emacs-startup-hook)
2202 (and term-setup-hook
2203 (run-hooks 'term-setup-hook))
2204 (setq inhibit-startup-hooks t)
2205
2206 ;; It's important to notice the user settings before we
2207 ;; display the startup message; otherwise, the settings
2208 ;; won't take effect until the user gives the first
2209 ;; keystroke, and that's distracting.
2210 (when (fboundp 'frame-notice-user-settings)
2211 (frame-notice-user-settings))
2212
2213 ;; If there are no switches to process, we might as well
2214 ;; run this hook now, and there may be some need to do it
2215 ;; before doing any output.
2216 (when window-setup-hook
2217 (run-hooks 'window-setup-hook)
2218 ;; Don't let the hook be run twice.
2219 (setq window-setup-hook nil))
2220
04ef2618
CY
2221 ;; ;; Do this now to avoid an annoying delay if the user
2222 ;; ;; clicks the menu bar during the sit-for.
2223 ;; (when (display-popup-menus-p)
2224 ;; (precompute-menubar-bindings))
2225 ;; (with-no-warnings
2226 ;; (setq menubar-bindings-done t))
22a58255
CY
2227
2228 ;; If *scratch* exists and is empty, insert initial-scratch-message.
2229 (and initial-scratch-message
2230 (get-buffer "*scratch*")
2231 (with-current-buffer "*scratch*"
2232 (when (zerop (buffer-size))
2233 (insert initial-scratch-message)
2234 (set-buffer-modified-p nil))))
2235
1cff9ad1
JL
2236 (if (> file-count 0)
2237 (display-startup-screen t)
2238 (display-startup-screen nil)))))
49939379 2239
47c7adae
RS
2240(defun command-line-normalize-file-name (file)
2241 "Collapse multiple slashes to one, to handle non-Emacs file names."
6b9e794f
RS
2242 (save-match-data
2243 ;; Use arg 1 so that we don't collapse // at the start of the file name.
2244 ;; That is significant on some systems.
2245 ;; However, /// at the beginning is supposed to mean just /, not //.
2246 (if (string-match "^///+" file)
2247 (setq file (replace-match "/" t t file)))
2248 (while (string-match "//+" file 1)
2249 (setq file (replace-match "/" t t file)))
2250 file))
47c7adae 2251
a3194d03 2252;; arch-tag: 7e294698-244d-4758-984b-4047f887a5db
c88ab9ce 2253;;; startup.el ends here