Move all the put's for menu-enable props to top level.
[bpt/emacs.git] / lisp / startup.el
CommitLineData
c88ab9ce
ER
1;;; startup.el --- process Emacs shell arguments
2
d3cf8dc3 3;; Copyright (C) 1985, 1986, 1992, 1994, 1995 Free Software Foundation, Inc.
eea8d4ef 4
630cc463 5;; Maintainer: FSF
d7b4d18f 6;; Keywords: internal
630cc463 7
a726e0d1
JB
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
4746118a 12;; the Free Software Foundation; either version 2, or (at your option)
a726e0d1
JB
13;; any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
b578f267
EN
21;; along with GNU Emacs; see the file COPYING. If not, write to the
22;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23;; Boston, MA 02111-1307, USA.
a726e0d1 24
630cc463 25;;; Commentary:
a726e0d1 26
ab30fc8a
RS
27;; This file parses the command line and gets Emacs running. Options on
28;; the command line are handled in precedence order. The order is the
29;; one in the list below; first described means first handled. Options
30;; within each category (delimited by a bar) are handled in the order
31;; encountered on the command line.
32
33;; -------------------------
34;; -version Print Emacs version to stderr, then exit
35;; --version successfully right away.
36;; This option is handled by emacs.c
37;; -------------------------
38;; -help Print a short usage description and exit
39;; --help successfully right away.
40;; This option is handled by emacs.c
41;; -------------------------
42;; -nl Do not use shared memory (for systems that
43;; -no-shared-memory support this) for the dumped Emacs data.
44;; This option is handled by emacs.c
45;;
46;; -map For VMS.
47;; --map-data This option is handled by emacs.c
48;; -------------------------
49;; -t FILE Use FILE as the name of the terminal.
50;; --terminal FILE Using this implies "-nw" also.
51;; This option is handled by emacs.c
52;; -------------------------
53;; -d DISPNAME Use DISPNAME as the name of the X-windows
54;; -display DISPNAME display for the initial frame.
55;; --display DISPNAME This option is handled by emacs.c
56;; -------------------------
57;; -nw Do not use a windows system (but use the
58;; --no-windows terminal instead.)
59;; This option is handled by emacs.c
60;; -------------------------
61;; -batch Execute noninteractively (messages go to stdout,
62;; --batch variable noninteractive set to t)
63;; This option is handled by emacs.c
64;; -------------------------
65;; -q Do not load user's init file and do not load
66;; -no-init-file "default.el". Regardless of this switch,
6f9340dd 67;; --no-init-file "site-start" is still loaded.
ab30fc8a 68;; -------------------------
6f9340dd 69;; -no-site-file Do not load "site-start.el". (This is the ONLY
ab30fc8a
RS
70;; --no-site-file way to prevent loading that file.)
71;; -------------------------
72;; -u USER Load USER's init file instead of the init
73;; -user USER file belonging to the user starting Emacs.
74;; --user USER
75;; -------------------------
76;; -debug-init Don't catch errors in init files; let the
77;; --debug-init debugger run.
78;; -------------------------
79;; -i ICONTYPE Set type of icon using when Emacs is
80;; -itype ICONTYPE iconified under X-windows.
81;; --icon-type ICONTYPE This option is passed on to term/x-win.el
82;;
83;; -iconic Start Emacs iconified under X-windows.
84;; --iconic This option is passed on to term/x-win.el
85;; -------------------------
86;; Various X-windows options for colors/fonts/geometry/title etc.
87;; These options are passed on to term/x-win.el which see. Certain
88;; of these are also found in term/pc-win.el
89;; -------------------------
90;; FILE Visit FILE.
91;;
92;; -L DIRNAME Add DIRNAME to load-path
93;; -directory DIRNAME
94;; --directory DIRNAME
95;;
96;; -l FILE Load and execute the Emacs lisp code
97;; -load FILE in FILE.
98;; --load FILE
99;;
100;; -f FUNC Execute Emacs lisp function FUNC with
101;; -funcall FUNC no arguments. The "-e" form is outdated
102;; --funcall FUNC and should not be used. (It's a typo
103;; -e FUNC promoted to a feature.)
104;;
955093c9
EN
105;; -eval FORM Execute Emacs lisp form FORM.
106;; --eval FORM
e6b75e30 107;;
ab30fc8a
RS
108;; -insert FILE Insert the contents of FILE into buffer.
109;; --insert FILE
110;; -------------------------
111;; -kill Kill (exit) Emacs right away.
112;; --kill
113;; -------------------------
a726e0d1 114
630cc463
ER
115;;; Code:
116
a726e0d1
JB
117(setq top-level '(normal-top-level))
118
119(defvar command-line-processed nil "t once command line has been processed")
120
121(defconst inhibit-startup-message nil
1d7da582 122 "*Non-nil inhibits the initial startup message.
a726e0d1
JB
123This is for use in your personal init file, once you are familiar
124with the contents of the startup message.")
125
1d7da582
RS
126(defconst inhibit-startup-echo-area-message nil
127 "*Non-nil inhibits the initial startup echo area message.
128Inhibition takes effect only if your `.emacs' file contains
e5575c06 129a line of this form:
54a003f7 130 (setq inhibit-startup-echo-area-message \"YOUR-USER-NAME\")
e5575c06
RS
131If your `.emacs' file is byte-compiled, use the following form instead:
132 (eval '(setq inhibit-startup-echo-area-message \"YOUR-USER-NAME\"))
1d7da582
RS
133Thus, someone else using a copy of your `.emacs' file will see
134the startup message unless he personally acts to inhibit it.")
135
a726e0d1
JB
136(defconst inhibit-default-init nil
137 "*Non-nil inhibits loading the `default' library.")
138
139(defconst command-switch-alist nil
140 "Alist of command-line switches.
141Elements look like (SWITCH-STRING . HANDLER-FUNCTION).
142HANDLER-FUNCTION receives switch name as sole arg;
143remaining command-line args are in the variable `command-line-args-left'.")
144
860befc8
RS
145(defvar command-line-args-left nil
146 "List of command-line args not yet processed.")
147
a726e0d1
JB
148(defvar command-line-functions nil ;; lrs 7/31/89
149 "List of functions to process unrecognized command-line arguments.
150Each function should access the dynamically bound variables
b4484ea8 151`argi' (the current argument) and `command-line-args-left' (the remaining
a726e0d1 152arguments). The function should return non-nil only if it recognizes and
b4484ea8
RS
153processes `argi'. If it does so, it may consume successive arguments by
154altering `command-line-args-left' to remove them.")
a726e0d1 155
09a1077c
RS
156(defvar command-line-default-directory nil
157 "Default directory to use for command line arguments.
158This is normally copied from `default-directory' when Emacs starts.")
159
b3afdeb8
RS
160;;; This is here, rather than in x-win.el, so that we can ignore these
161;;; options when we are not using X.
162(defvar command-line-x-option-alist
163 '(("-bw" 1 x-handle-numeric-switch border-width)
164 ("-d" 1 x-handle-display)
165 ("-display" 1 x-handle-display)
166 ("-name" 1 x-handle-name-rn-switch)
167 ("-rn" 1 x-handle-name-rn-switch)
168 ("-T" 1 x-handle-switch name)
169 ("-r" 0 x-handle-switch reverse t)
170 ("-rv" 0 x-handle-switch reverse t)
171 ("-reverse" 0 x-handle-switch reverse t)
172 ("-reverse-video" 0 x-handle-switch reverse t)
173 ("-fn" 1 x-handle-switch font)
174 ("-font" 1 x-handle-switch font)
175 ("-ib" 1 x-handle-numeric-switch internal-border-width)
1f7f78f1
RS
176 ("-g" 1 x-handle-geometry)
177 ("-geometry" 1 x-handle-geometry)
b3afdeb8
RS
178 ("-fg" 1 x-handle-switch foreground-color)
179 ("-foreground" 1 x-handle-switch foreground-color)
180 ("-bg" 1 x-handle-switch background-color)
181 ("-background" 1 x-handle-switch background-color)
182 ("-ms" 1 x-handle-switch mouse-color)
183 ("-itype" 0 x-handle-switch icon-type t)
184 ("-i" 0 x-handle-switch icon-type t)
185 ("-iconic" 0 x-handle-iconic)
186 ("-xrm" 1 x-handle-xrm-switch)
187 ("-cr" 1 x-handle-switch cursor-color)
188 ("-vb" 0 x-handle-switch vertical-scroll-bars t)
189 ("-hb" 0 x-handle-switch horizontal-scroll-bars t)
190 ("-bd" 1 x-handle-switch)
191 ("--border-width" 1 x-handle-numeric-switch border-width)
192 ("--display" 1 x-handle-display)
193 ("--name" 1 x-handle-name-rn-switch)
194 ("--title" 1 x-handle-name-rn-switch)
195 ("--reverse-video" 0 x-handle-switch reverse t)
196 ("--font" 1 x-handle-switch font)
197 ("--internal-border" 1 x-handle-numeric-switch internal-border-width)
1f7f78f1 198 ("--geometry" 1 x-handle-geometry)
b3afdeb8
RS
199 ("--foreground-color" 1 x-handle-switch foreground-color)
200 ("--background-color" 1 x-handle-switch background-color)
201 ("--mouse-color" 1 x-handle-switch mouse-color)
202 ("--icon-type" 0 x-handle-switch icon-type t)
203 ("--iconic" 0 x-handle-iconic)
204 ("--xrm" 1 x-handle-xrm-switch)
205 ("--cursor-color" 1 x-handle-switch cursor-color)
206 ("--vertical-scroll-bars" 0 x-handle-switch vertical-scroll-bars t)
207 ("--border-color" 1 x-handle-switch border-width))
208 "Alist of X Windows options.
209Each element has the form
210 (NAME NUMARGS HANDLER FRAME-PARAM VALUE)
211where NAME is the option name string, NUMARGS is the number of arguments
212that the option accepts, HANDLER is a function to call to handle the option.
213FRAME-PARAM (optional) is the frame parameter this option specifies,
214and VALUE is the value which is given to that frame parameter
215\(most options use the argument for this, so VALUE is not present).")
216
e3bd99f5 217(defvar before-init-hook nil
b4484ea8 218 "Functions to call after handling urgent options but before init files.
0cc89026 219The frame system uses this to open frames to display messages while
3fc958a4
JB
220Emacs loads the user's initialization file.")
221
e3bd99f5 222(defvar after-init-hook nil
a0965605 223 "Functions to call after loading the init file (`~/.emacs').
e3bd99f5 224The call is not protected by a condition-case, so you can set `debug-on-error'
a0965605 225in `.emacs', and put all the actual code on `after-init-hook'.")
e3bd99f5 226
a726e0d1 227(defvar term-setup-hook nil
b4484ea8 228 "Functions to be called after loading terminal-specific Lisp code.
e3bd99f5 229See `run-hooks'. This variable exists for users to set,
a726e0d1
JB
230so as to override the definitions made by the terminal-specific file.
231Emacs never sets this variable itself.")
232
233(defvar keyboard-type nil
b4484ea8
RS
234 "The brand of keyboard you are using.
235This variable is used to define
a726e0d1
JB
236the proper function and keypad keys for use under X. It is used in a
237fashion analogous to the environment value TERM.")
238
239(defvar window-setup-hook nil
b4484ea8
RS
240 "Normal hook run to initialize window system display.
241Emacs runs this hook after processing the command line arguments and loading
242the user's init file.")
a726e0d1
JB
243
244(defconst initial-major-mode 'lisp-interaction-mode
245 "Major mode command symbol to use for the initial *scratch* buffer.")
246
247(defvar init-file-user nil
248 "Identity of user whose `.emacs' file is or was read.
2bdfaa42
KH
249The value is nil if no init file is being used; otherwise, it may be either
250the null string, meaning that the init file was taken from the user that
251originally logged in, or it may be a string containing a user's name.
a726e0d1 252
2bdfaa42
KH
253In either of the latter cases, `(concat \"~\" init-file-user \"/\")'
254evaluates to the name of the directory where the `.emacs' file was
13fce4e6
RS
255looked for.
256
257Setting `init-file-user' does not prevent Emacs from loading
258`site-start.el'. The only way to do that is to use `--no-site-file'.")
a726e0d1 259
b7444d31
RS
260(defvar site-run-file "site-start"
261 "File containing site-wide run-time initializations.
262This file is loaded at run-time before `~/.emacs'. It contains inits
263that need to be in place for the entire site, but which, due to their
264higher incidence of change, don't make sense to load into emacs'
265dumped image. Thus, the run-time load order is: 1. file described in
13fce4e6
RS
266this variable, if non-nil; 2. `~/.emacs'; 3. `default.el'.
267
268Don't use the `site-start.el' file for things some users may not like.
269Put them in `default.el' instead, so that users can more easily
270override them. Users can prevent loading `default.el' with the `-q'
271option or by setting `inhibit-default-init' in their own init files,
272but inhibiting `site-start.el' requires `--no-site-file', which
273is less convenient.")
b7444d31 274
30dc01ea
RS
275(defconst iso-8859-1-locale-regexp "8859[-_]?1"
276 "Regexp that specifies when to enable the ISO 8859-1 character set.
277We do that if this regexp matches the locale name
278specified by the LC_ALL, LC_CTYPE and LANG environment variables.")
279
c13fbb62
RS
280(defvar mail-host-address nil
281 "*Name of this machine, for purposes of naming users.")
282
c10d1f06 283(defvar user-mail-address nil
452e9090
RS
284 "*Full mailing address of this user.
285This is initialized based on `mail-host-address',
286after your init file is read, in case it sets `mail-host-address'.")
c10d1f06 287
1f7f78f1
RS
288(defvar auto-save-list-file-prefix
289 (if (eq system-type 'ms-dos)
290 "~/_s" ; MS-DOS cannot have initial dot, and allows only 8.3 names
291 "~/.saves-")
cdee38c3
KH
292 "Prefix for generating `auto-save-list-file-name'.
293This is used after reading your `.emacs' file to initialize
294`auto-save-list-file-name', by appending Emacs's pid and the system name,
295if you have not already set `auto-save-list-file-name' yourself.
296Set this to nil if you want to prevent `auto-save-list-file-name'
297from being initialized.")
2e05d063 298
a726e0d1
JB
299(defvar init-file-debug nil)
300
52320897
RS
301(defvar init-file-had-error nil)
302
e87a7309
RS
303;; This function is called from the subdirs.el file.
304(defun normal-top-level-add-to-load-path (dirs)
305 (let ((tail (member default-directory load-path)))
306 (setcdr tail (append (mapcar 'expand-file-name dirs) (cdr tail)))))
307
a726e0d1
JB
308(defun normal-top-level ()
309 (if command-line-processed
310 (message "Back to top level.")
311 (setq command-line-processed t)
8d4c2221
RS
312 ;; Give *Messages* the same default-directory as *scratch*,
313 ;; just to keep things predictable.
314 (let ((dir default-directory))
315 (save-excursion
316 (set-buffer (get-buffer "*Messages*"))
317 (setq default-directory dir)))
e87a7309
RS
318 ;; Look in each dir in load-path for a subdirs.el file.
319 ;; If we find one, load it, which will add the appropriate subdirs
320 ;; of that dir into load-path,
321 (let ((tail load-path)
322 new)
323 (while tail
324 (setq new (cons (car tail) new))
325 (let ((default-directory (car tail)))
326 (load (expand-file-name "subdirs.el" (car tail)) t t t))
327 (setq tail (cdr tail))))
ffd56f97 328 (if (not (eq system-type 'vax-vms))
a4b33896
JB
329 (progn
330 ;; If the PWD environment variable isn't accurate, delete it.
331 (let ((pwd (getenv "PWD")))
332 (and (stringp pwd)
333 ;; Use FOO/., so that if FOO is a symlink, file-attributes
334 ;; describes the directory linked to, not FOO itself.
335 (or (equal (file-attributes
336 (concat (file-name-as-directory pwd) "."))
337 (file-attributes
338 (concat (file-name-as-directory default-directory)
339 ".")))
340 (setq process-environment
341 (delete (concat "PWD=" pwd)
342 process-environment)))))))
492878e4 343 (setq default-directory (abbreviate-file-name default-directory))
6f2c86fa
KH
344 (let ((menubar-bindings-done nil))
345 (unwind-protect
346 (command-line)
347 ;; Do this again, in case .emacs defined more abbreviations.
348 (setq default-directory (abbreviate-file-name default-directory))
b3c7c12c
RS
349 ;; Specify the file for recording all the auto save files of this session.
350 ;; This is used by recover-session.
cdee38c3
KH
351 (or auto-save-list-file-name
352 (and auto-save-list-file-prefix
353 (setq auto-save-list-file-name
1f7f78f1
RS
354 ;; Under MS-DOS our PID is almost always reused between
355 ;; Emacs invocations. We need something more unique.
356 (if (eq system-type 'ms-dos)
2c42ec0b
RS
357 (concat
358 (make-temp-name
359 (expand-file-name auto-save-list-file-prefix))
360 "~")
361
362 (expand-file-name (format "%s%d-%s~"
1f7f78f1
RS
363 auto-save-list-file-prefix
364 (emacs-pid)
365 (system-name)))))))
6f2c86fa
KH
366 (run-hooks 'emacs-startup-hook)
367 (and term-setup-hook
368 (run-hooks 'term-setup-hook))
369 ;; Modify the initial frame based on what .emacs puts into
370 ;; ...-frame-alist.
371 (if (fboundp 'frame-notice-user-settings)
372 (frame-notice-user-settings))
373 ;; Now we know the user's default font, so add it to the menu.
374 (if (fboundp 'font-menu-add-default)
375 (font-menu-add-default))
376 (and window-setup-hook
377 (run-hooks 'window-setup-hook))
378 (or menubar-bindings-done
39d6d6be 379 (if (or (eq window-system 'x) (eq window-system 'win32))
365636dc 380 (precompute-menubar-bindings)))))))
6f2c86fa
KH
381
382;; Precompute the keyboard equivalents in the menu bar items.
383(defun precompute-menubar-bindings ()
365636dc
RS
384 (let ((submap (lookup-key global-map [menu-bar])))
385 (while submap
386 (and (consp (car submap))
387 (symbolp (car (car submap)))
388 (stringp (car-safe (cdr (car submap))))
389 (keymapp (cdr (cdr (car submap))))
a18042d7
RS
390 (progn
391 (x-popup-menu nil (cdr (cdr (car submap))))
392 (if purify-flag
393 (garbage-collect))))
365636dc
RS
394 (setq submap (cdr submap))))
395 (setq define-key-rebound-commands t))
a726e0d1
JB
396
397(defun command-line ()
09a1077c
RS
398 (setq command-line-default-directory default-directory)
399
74f2ab06 400 ;; See if we should import version-control from the environment variable.
a726e0d1
JB
401 (let ((vc (getenv "VERSION_CONTROL")))
402 (cond ((eq vc nil)) ;don't do anything if not set
403 ((or (string= vc "t")
404 (string= vc "numbered"))
405 (setq version-control t))
406 ((or (string= vc "nil")
407 (string= vc "existing"))
408 (setq version-control nil))
409 ((or (string= vc "never")
410 (string= vc "simple"))
411 (setq version-control 'never))))
412
30dc01ea
RS
413 (if (let ((ctype
414 ;; Use the first of these three envvars that has a nonempty value.
415 (or (let ((string (getenv "LC_ALL")))
416 (and (not (equal string "")) string))
417 (let ((string (getenv "LC_CTYPE")))
418 (and (not (equal string "")) string))
419 (let ((string (getenv "LANG")))
420 (and (not (equal string "")) string)))))
421 (and ctype
422 (string-match iso-8859-1-locale-regexp ctype)))
e9d8e8c7 423 (progn
62bb5440 424 (require 'disp-table)
e9d8e8c7
RS
425 (standard-display-european t)
426 (require 'iso-syntax)))
427
79058860
JB
428 ;;! This has been commented out; I currently find the behavior when
429 ;;! split-window-keep-point is nil disturbing, but if I can get used
430 ;;! to it, then it would be better to eliminate the option.
431 ;;! ;; Choose a good default value for split-window-keep-point.
432 ;;! (setq split-window-keep-point (> baud-rate 2400))
f35fe3c6 433
a726e0d1 434 ;; Read window system's init file if using a window system.
1ed14cfd
RS
435 (condition-case error
436 (if (and window-system (not noninteractive))
437 (load (concat term-file-prefix
438 (symbol-name window-system)
439 "-win")
440 ;; Every window system should have a startup file;
441 ;; barf if we can't find it.
442 nil t))
443 ;; If we can't read it, print the error message and exit.
444 (error
2677ad61
RS
445 (princ
446 (if (eq (car error) 'error)
447 (apply 'concat (cdr error))
448 (if (memq 'file-error (get (car error) 'error-conditions))
449 (format "%s: %s"
450 (nth 1 error)
451 (mapconcat '(lambda (obj) (prin1-to-string obj t))
452 (cdr (cdr error)) ", "))
453 (format "%s: %s"
454 (get (car error) 'error-message)
455 (mapconcat '(lambda (obj) (prin1-to-string obj t))
456 (cdr error) ", "))))
457 'external-debugging-output)
458 (setq window-system nil)
1ed14cfd 459 (kill-emacs)))
a726e0d1 460
03e3c30a
JB
461 (let ((done nil)
462 (args (cdr command-line-args)))
463
a726e0d1
JB
464 ;; Figure out which user's init file to load,
465 ;; either from the environment or from the options.
466 (setq init-file-user (if noninteractive nil (user-login-name)))
467 ;; If user has not done su, use current $HOME to find .emacs.
468 (and init-file-user (string= init-file-user (user-real-login-name))
469 (setq init-file-user ""))
03e3c30a
JB
470
471 ;; Process the command-line args, and delete the arguments
472 ;; processed. This is consistent with the way main in emacs.c
473 ;; does things.
a726e0d1 474 (while (and (not done) args)
096b7031 475 (let ((longopts '(("--no-init-file") ("--no-site-file") ("--user")
a360cae9 476 ("--debug-init") ("--iconic") ("--icon-type")))
096b7031
KH
477 (argi (car args))
478 (argval nil))
452e9090
RS
479 ;; Handle --OPTION=VALUE format.
480 (if (and (string-match "\\`--" argi)
481 (string-match "=" argi))
a981e7ff
KH
482 (setq argval (substring argi (match-end 0))
483 argi (substring argi 0 (match-beginning 0))))
096b7031
KH
484 (let ((completion (try-completion argi longopts)))
485 (if (eq completion t)
486 (setq argi (substring argi 1))
487 (if (stringp completion)
488 (let ((elt (assoc completion longopts)))
489 (or elt
490 (error "Option `%s' is ambiguous" argi))
3f53ddd0
RS
491 (setq argi (substring (car elt) 1)))
492 (setq argval nil))))
a726e0d1
JB
493 (cond
494 ((or (string-equal argi "-q")
495 (string-equal argi "-no-init-file"))
496 (setq init-file-user nil
497 args (cdr args)))
498 ((or (string-equal argi "-u")
499 (string-equal argi "-user"))
096b7031 500 (or argval
d3bea05f
RS
501 (setq args (cdr args)
502 argval (car args)))
096b7031
KH
503 (setq init-file-user argval
504 argval nil
a726e0d1 505 args (cdr args)))
b7444d31
RS
506 ((string-equal argi "-no-site-file")
507 (setq site-run-file nil
508 args (cdr args)))
a726e0d1
JB
509 ((string-equal argi "-debug-init")
510 (setq init-file-debug t
511 args (cdr args)))
a360cae9
RS
512 ((string-equal argi "-iconic")
513 (setq initial-frame-alist
514 (cons '(visibility . icon) initial-frame-alist))
515 (setq args (cdr args)))
516 ((or (string-equal argi "-icon-type")
517 (string-equal argi "-i")
518 (string-equal argi "-itype"))
519 (setq default-frame-alist
520 (cons '(icon-type . t) default-frame-alist))
521 (setq args (cdr args)))
096b7031
KH
522 (t (setq done t)))
523 ;; Was argval set but not used?
524 (and argval
525 (error "Option `%s' doesn't allow an argument" argi))))
526
03e3c30a 527 ;; Re-attach the program name to the front of the arg list.
4048e56d 528 (and command-line-args (setcdr command-line-args args)))
a726e0d1 529
c722566c 530 ;; Under X Windows, this creates the X frame and deletes the terminal frame.
4e1b1e72
JB
531 (if (fboundp 'face-initialize)
532 (face-initialize))
853ccbd5
RS
533 (if (fboundp 'frame-initialize)
534 (frame-initialize))
1fe0333f 535 ;; If frame was created with a menu bar, set menu-bar-mode on.
39d6d6be 536 (if (or (not (or (eq window-system 'x) (eq window-system 'win32)))
3ede3ece 537 (> (cdr (assq 'menu-bar-lines (frame-parameters))) 0))
1fe0333f 538 (menu-bar-mode t))
c722566c 539
e3bd99f5 540 (run-hooks 'before-init-hook)
3fc958a4 541
09973c54
RM
542 ;; Run the site-start library if it exists. The point of this file is
543 ;; that it is run before .emacs. There is no point in doing this after
544 ;; .emacs; that is useless.
b7444d31
RS
545 (if site-run-file
546 (load site-run-file t t))
09973c54 547
8a988f45
RS
548 ;; Sites should not disable this. Only individuals should disable
549 ;; the startup message.
550 (setq inhibit-startup-message nil)
551
a726e0d1 552 ;; Load that user's init file, or the default one, or none.
3d1b78f0
RS
553 (let (debug-on-error-from-init-file
554 debug-on-error-should-be-set
555 (debug-on-error-initial
556 (if (eq init-file-debug t) 'startup init-file-debug)))
557 (let ((debug-on-error debug-on-error-initial)
558 ;; This function actually reads the init files.
559 (inner
560 (function
561 (lambda ()
562 (if init-file-user
a4c5c705
RS
563 (progn
564 (setq user-init-file
565 (cond
566 ((eq system-type 'ms-dos)
567 (concat "~" init-file-user "/_emacs"))
7d1aa45d 568 ((eq system-type 'windows-nt)
521736d1
RS
569 (if (file-exists-p "~/.emacs")
570 "~/.emacs"
571 "~/_emacs"))
a4c5c705
RS
572 ((eq system-type 'vax-vms)
573 "sys$login:.emacs")
574 (t
575 (concat "~" init-file-user "/.emacs"))))
576 (load user-init-file t t t)
577 (or inhibit-default-init
578 (let ((inhibit-startup-message nil))
579 ;; Users are supposed to be told their rights.
580 ;; (Plus how to get help and how to undo.)
581 ;; Don't you dare turn this off for anyone
582 ;; except yourself.
583 (load "default" t t)))))))))
3d1b78f0
RS
584 (if init-file-debug
585 ;; Do this without a condition-case if the user wants to debug.
586 (funcall inner)
587 (condition-case error
588 (progn
589 (funcall inner)
590 (setq init-file-had-error nil))
591 (error (message "Error in init file: %s%s%s"
592 (get (car error) 'error-message)
ad2aeb8d 593 (if (cdr error) ": " "")
3d1b78f0
RS
594 (mapconcat 'prin1-to-string (cdr error) ", "))
595 (setq init-file-had-error t))))
ad2aeb8d 596 ;; If we can tell that the init file altered debug-on-error,
3d1b78f0
RS
597 ;; arrange to preserve the value that it set up.
598 (or (eq debug-on-error debug-on-error-initial)
599 (setq debug-on-error-should-be-set t
600 debug-on-error-from-init-file debug-on-error)))
601 (if debug-on-error-should-be-set
602 (setq debug-on-error debug-on-error-from-init-file)))
3fc958a4 603
556f7d77
RS
604 ;; Do this here in case the init file sets mail-host-address.
605 (or user-mail-address
606 (setq user-mail-address (concat (user-login-name) "@"
607 (or mail-host-address
608 (system-name)))))
609
e3bd99f5
RM
610 (run-hooks 'after-init-hook)
611
a726e0d1
JB
612 ;; If *scratch* exists and init file didn't change its mode, initialize it.
613 (if (get-buffer "*scratch*")
614 (save-excursion
615 (set-buffer "*scratch*")
616 (if (eq major-mode 'fundamental-mode)
617 (funcall initial-major-mode))))
618 ;; Load library for our terminal type.
619 ;; User init file can set term-file-prefix to nil to prevent this.
620 (and term-file-prefix (not noninteractive) (not window-system)
621 (let ((term (getenv "TERM"))
622 hyphend)
623 (while (and term
624 (not (load (concat term-file-prefix term) t t)))
625 ;; Strip off last hyphen and what follows, then try again
626 (if (setq hyphend (string-match "[-_][^-_]+$" term))
627 (setq term (substring term 0 hyphend))
628 (setq term nil)))))
629
03e3c30a 630 ;; Process the remaining args.
a726e0d1
JB
631 (command-line-1 (cdr command-line-args))
632
633 ;; If -batch, terminate after processing the command options.
634 (if noninteractive (kill-emacs t)))
635
636(defun command-line-1 (command-line-args-left)
52320897 637 (or noninteractive (input-pending-p) init-file-had-error
1d7da582
RS
638 (and inhibit-startup-echo-area-message
639 (let ((buffer (get-buffer-create " *temp*")))
640 (prog1
641 (condition-case nil
642 (save-excursion
643 (set-buffer buffer)
644 (insert-file-contents user-init-file)
645 (re-search-forward
646 (concat
d9a71a8f
RS
647 "([ \t\n]*setq[ \t\n]+"
648 "inhibit-startup-echo-area-message[ \t\n]+"
649 (regexp-quote
650 (prin1-to-string
651 (if (string= init-file-user "")
652 (user-login-name)
653 init-file-user)))
654 "[ \t\n]*)")
1d7da582
RS
655 nil t))
656 (error nil))
657 (kill-buffer buffer))))
658 (message (if (eq (key-binding "\C-h\C-p") 'describe-project)
659 "For information about the GNU Project and its goals, type C-h C-p."
660 (substitute-command-keys
661 "For information about the GNU Project and its goals, type \\[describe-project]."))))
a726e0d1
JB
662 (if (null command-line-args-left)
663 (cond ((and (not inhibit-startup-message) (not noninteractive)
664 ;; Don't clobber a non-scratch buffer if init file
665 ;; has selected it.
666 (string= (buffer-name) "*scratch*")
667 (not (input-pending-p)))
668 ;; If there are no switches to process, we might as well
669 ;; run this hook now, and there may be some need to do it
670 ;; before doing any output.
671 (and term-setup-hook
672 (run-hooks 'term-setup-hook))
673 ;; Don't let the hook be run twice.
674 (setq term-setup-hook nil)
4e1b1e72
JB
675
676 ;; It's important to notice the user settings before we
677 ;; display the startup message; otherwise, the settings
678 ;; won't take effect until the user gives the first
679 ;; keystroke, and that's distracting.
680 (if (fboundp 'frame-notice-user-settings)
681 (frame-notice-user-settings))
682
a726e0d1
JB
683 (and window-setup-hook
684 (run-hooks 'window-setup-hook))
685 (setq window-setup-hook nil)
fd11871a
RS
686 ;; Do this now to avoid an annoying delay if the user
687 ;; clicks the menu bar during the sit-for.
39d6d6be 688 (if (or (eq window-system 'x) (eq window-system 'win32))
365636dc 689 (precompute-menubar-bindings))
fd11871a 690 (setq menubar-bindings-done t)
a726e0d1
JB
691 (unwind-protect
692 (progn
6695496f
RS
693 ;; The convention for this piece of code is that
694 ;; each piece of output starts with one or two newlines
695 ;; and does not end with any newlines.
a726e0d1
JB
696 (insert (emacs-version)
697 "
40e23599 698Copyright (C) 1996 Free Software Foundation, Inc.")
a726e0d1
JB
699 ;; If keys have their default meanings,
700 ;; use precomputed string to save lots of time.
701 (if (and (eq (key-binding "\C-h") 'help-command)
702 (eq (key-binding "\C-xu") 'advertised-undo)
703 (eq (key-binding "\C-x\C-c") 'save-buffers-kill-emacs)
e65a6404
RS
704 (eq (key-binding "\C-ht") 'help-with-tutorial)
705 (eq (key-binding "\C-hi") 'info))
6695496f
RS
706 (insert "\n
707Type C-h for help; C-x u to undo changes. (`C-' means use CTRL key.)
a726e0d1
JB
708To kill the Emacs job, type C-x C-c.
709Type C-h t for a tutorial on using Emacs.
e65a6404
RS
710Type C-h i to enter Info, which you can use to read GNU documentation.")
711 (insert (substitute-command-keys
6695496f
RS
712 (format "\n
713Type %s for help; \\[advertised-undo] to undo changes. (`C-' means use CTRL key.)
e65a6404
RS
714To kill the Emacs job, type \\[save-buffers-kill-emacs].
715Type \\[help-with-tutorial] for a tutorial on using Emacs.
716Type \\[info] to enter Info, which you can use to read GNU documentation."
717 (let ((where (where-is-internal
718 'help-command nil t)))
719 (if where
720 (key-description where)
721 "M-x help"))))))
3ede3ece
RS
722 ;; Say how to use the menu bar
723 ;; if that is not with the mouse.
724 (if (not (assq 'display (frame-parameters)))
725 (if (eq (key-binding "\M-`") 'tmm-menubar)
325cbd32 726 (insert "\n\nType F10, ESC ` or Meta-` to use the menu bar.")
3ede3ece
RS
727 (insert (substitute-command-keys
728 "\n\nType \\[tmm-menubar] to use the menu bar."))))
e65a6404
RS
729
730 ;; Windows and MSDOS (currently) do not count as
731 ;; window systems, but do have mouse support.
1f7f78f1 732 (if window-system
6695496f 733 (insert "\n
e65a6404 734C-mouse-3 (third mouse button, with Control) gets a mode-specific menu."))
95127745
KH
735 (and auto-save-list-file-prefix
736 (directory-files
737 (file-name-directory auto-save-list-file-prefix)
738 nil
739 (concat "\\`"
740 (regexp-quote (file-name-nondirectory
741 auto-save-list-file-prefix)))
742 t)
743 (insert "\n\nIf an Emacs session crashed recently,\n"
744 "type M-x recover-session RET to recover"
745 " the files you were editing."))
6695496f 746
e65a6404
RS
747 (if (and (eq (key-binding "\C-h\C-c") 'describe-copying)
748 (eq (key-binding "\C-h\C-d") 'describe-distribution)
749 (eq (key-binding "\C-h\C-w") 'describe-no-warranty))
750 (insert
6695496f 751 "\n
a726e0d1
JB
752GNU Emacs comes with ABSOLUTELY NO WARRANTY; type C-h C-w for full details.
753You may give out copies of Emacs; type C-h C-c to see the conditions.
754Type C-h C-d for information on getting the latest version.")
755 (insert (substitute-command-keys
6695496f 756 "\n
a726e0d1
JB
757GNU Emacs comes with ABSOLUTELY NO WARRANTY; type \\[describe-no-warranty] for full details.
758You may give out copies of Emacs; type \\[describe-copying] to see the conditions.
759Type \\[describe-distribution] for information on getting the latest version.")))
fb3afe87 760
a726e0d1
JB
761 (set-buffer-modified-p nil)
762 (sit-for 120))
763 (save-excursion
764 ;; In case the Emacs server has already selected
765 ;; another buffer, erase the one our message is in.
766 (set-buffer (get-buffer "*scratch*"))
767 (erase-buffer)
768 (set-buffer-modified-p nil)))))
eca1cf26
RS
769 ;; Delay 2 seconds after the init file error message
770 ;; was displayed, so user can read it.
771 (if init-file-had-error
772 (sit-for 2))
09a1077c 773 (let ((dir command-line-default-directory)
a726e0d1
JB
774 (file-count 0)
775 first-file-buffer
776 (line 0))
777 (while command-line-args-left
3f53ddd0
RS
778 (let* ((argi (car command-line-args-left))
779 (orig-argi argi)
780 ;; This includes our standard options' long versions
781 ;; and long versions of what's on command-switch-alist.
782 (longopts
aba66e2a 783 (append '(("--funcall") ("--load") ("--insert") ("--kill")
e6b75e30 784 ("--directory") ("--eval"))
3f53ddd0
RS
785 (mapcar '(lambda (elt)
786 (list (concat "-" (car elt))))
787 command-switch-alist)))
aba66e2a
RS
788 tem argval completion
789 ;; List of directories specified in -L/--directory,
790 ;; in reverse of the order specified.
791 extra-load-path
792 (initial-load-path load-path))
a726e0d1 793 (setq command-line-args-left (cdr command-line-args-left))
3f53ddd0 794
b3afdeb8
RS
795 ;; Add the long X options to longopts.
796 (setq tem command-line-x-option-alist)
797 (while tem
798 (if (string-match "^--" (car (car tem)))
799 (setq longopts (cons (list (car (car tem))) longopts)))
800 (setq tem (cdr tem)))
801
3f53ddd0
RS
802 ;; Convert long options to ordinary options
803 ;; and separate out an attached option argument into argval.
804 (if (string-match "^--[^=]*=" argi)
805 (setq argval (substring argi (match-end 0))
806 argi (substring argi 0 (1- (match-end 0)))))
807 (setq completion (try-completion argi longopts))
808 (if (eq completion t)
809 (setq argi (substring argi 1))
810 (if (stringp completion)
811 (let ((elt (assoc completion longopts)))
812 (or elt
813 (error "Option `%s' is ambiguous" argi))
814 (setq argi (substring (car elt) 1)))
815 (setq argval nil argi orig-argi)))
816
817 ;; Execute the option.
a726e0d1 818 (cond ((setq tem (assoc argi command-switch-alist))
3f53ddd0
RS
819 (if argval
820 (let ((command-line-args-left
821 (cons argval command-line-args-left)))
822 (funcall (cdr tem) argi))
823 (funcall (cdr tem) argi)))
a726e0d1
JB
824 ((or (string-equal argi "-f") ;what the manual claims
825 (string-equal argi "-funcall")
826 (string-equal argi "-e")) ; what the source used to say
3f53ddd0
RS
827 (if argval
828 (setq tem (intern argval))
829 (setq tem (intern (car command-line-args-left)))
830 (setq command-line-args-left (cdr command-line-args-left)))
1908c565
RS
831 (if (arrayp (symbol-function tem))
832 (command-execute tem)
833 (funcall tem)))
e6b75e30
RS
834 ((string-equal argi "-eval")
835 (if argval
836 (setq tem argval)
837 (setq tem (car command-line-args-left))
838 (setq command-line-args-left (cdr command-line-args-left)))
955093c9 839 (eval (read tem)))
aba66e2a
RS
840 ;; Set the default directory as specified in -L.
841 ((or (string-equal argi "-L")
842 (string-equal argi "-directory"))
843 (if argval
844 (setq tem argval)
845 (setq tem (car command-line-args-left)
846 command-line-args-left (cdr command-line-args-left)))
47c7adae 847 (setq tem (command-line-normalize-file-name tem))
aba66e2a
RS
848 (setq extra-load-path
849 (cons (expand-file-name tem) extra-load-path))
850 (setq load-path (append (nreverse extra-load-path)
851 initial-load-path)))
a726e0d1
JB
852 ((or (string-equal argi "-l")
853 (string-equal argi "-load"))
3f53ddd0
RS
854 (if argval
855 (setq tem argval)
856 (setq tem (car command-line-args-left)
857 command-line-args-left (cdr command-line-args-left)))
47c7adae 858 (let ((file (command-line-normalize-file-name tem)))
a726e0d1
JB
859 ;; Take file from default dir if it exists there;
860 ;; otherwise let `load' search for it.
861 (if (file-exists-p (expand-file-name file))
862 (setq file (expand-file-name file)))
3f53ddd0 863 (load file nil t)))
fbce8654 864 ((string-equal argi "-insert")
3f53ddd0
RS
865 (if argval
866 (setq tem argval)
867 (setq tem (car command-line-args-left)
868 command-line-args-left (cdr command-line-args-left)))
2d2aae54
EN
869 (or (stringp tem)
870 (error "File name omitted from `-insert' option"))
47c7adae 871 (insert-file-contents (command-line-normalize-file-name tem)))
a726e0d1
JB
872 ((string-equal argi "-kill")
873 (kill-emacs t))
874 ((string-match "^\\+[0-9]+\\'" argi)
875 (setq line (string-to-int argi)))
b3afdeb8
RS
876 ((setq tem (assoc argi command-line-x-option-alist))
877 ;; Ignore X-windows options and their args if not using X.
878 (setq command-line-args-left
879 (nthcdr (nth 1 tem) command-line-args-left)))
a726e0d1
JB
880 (t
881 ;; We have almost exhausted our options. See if the
882 ;; user has made any other command-line options available
883 (let ((hooks command-line-functions);; lrs 7/31/89
884 (did-hook nil))
885 (while (and hooks
886 (not (setq did-hook (funcall (car hooks)))))
887 (setq hooks (cdr hooks)))
888 (if (not did-hook)
889 ;; Ok, presume that the argument is a file name
890 (progn
7a79b90c
RS
891 (if (string-match "\\`-" argi)
892 (error "Unknown option `%s'" argi))
a726e0d1 893 (setq file-count (1+ file-count))
47c7adae 894 (setq argi (command-line-normalize-file-name argi))
a726e0d1
JB
895 (cond ((= file-count 1)
896 (setq first-file-buffer
897 (find-file (expand-file-name argi dir))))
898 (t
899 (find-file-other-window (expand-file-name argi dir))))
900 (or (zerop line)
901 (goto-line line))
902 (setq line 0))))))))
903 ;; If 3 or more files visited, and not all visible,
904 ;; show user what they all are.
905 (if (> file-count 2)
906 (or (get-buffer-window first-file-buffer)
7e0795a4 907 (progn (other-window 1)
e8997612 908 (buffer-menu)))))))
c88ab9ce 909
47c7adae
RS
910(defun command-line-normalize-file-name (file)
911 "Collapse multiple slashes to one, to handle non-Emacs file names."
912 (while (string-match "//+" file)
913 (setq file (replace-match "/" t t file)))
914 file)
915
c88ab9ce 916;;; startup.el ends here