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