(spell-filter): Make it a risky-local-variable.
[bpt/emacs.git] / lisp / startup.el
CommitLineData
c88ab9ce
ER
1;;; startup.el --- process Emacs shell arguments
2
1d7da582 3;; Copyright (C) 1985, 1986, 1992, 1994 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
21;; along with GNU Emacs; see the file COPYING. If not, write to
22;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23
630cc463 24;;; Commentary:
a726e0d1
JB
25
26; These are processed only at the beginning of the argument list.
27; -batch execute noninteractively (messages go to stdout,
28; variable noninteractive set to t)
29; This option must be the first in the arglist.
30; Processed by `main' in emacs.c -- never seen by lisp
31; -t file Specify to use file rather than stdin/stdout
32; as the terminal.
33; This option must be the first in the arglist.
34; Processed by `main' in emacs.c -- never seen by lisp
35; -nw Inhibit the use of any window-system-specific display
36; code; use the current virtual terminal.
37; This option must be the first in the arglist.
38; Processed by `main' in emacs.c -- never seen by lisp
39; -q load no init file
40; -no-init-file same
41; -u user load user's init file
42; -user user same
43; -debug-init Don't catch errors in init file; let debugger run.
096b7031 44; -no-site-file Don't load site-run-file.
a726e0d1
JB
45
46; These are processed in the order encountered.
47; -f function execute function
48; -funcall function same
49; -l file load file
50; -load file same
096b7031 51; -insert file insert file into buffer
a726e0d1
JB
52; file visit file
53; -kill kill (exit) emacs
54
630cc463
ER
55;;; Code:
56
a726e0d1
JB
57(setq top-level '(normal-top-level))
58
59(defvar command-line-processed nil "t once command line has been processed")
60
61(defconst inhibit-startup-message nil
1d7da582 62 "*Non-nil inhibits the initial startup message.
a726e0d1
JB
63This is for use in your personal init file, once you are familiar
64with the contents of the startup message.")
65
1d7da582
RS
66(defconst inhibit-startup-echo-area-message nil
67 "*Non-nil inhibits the initial startup echo area message.
68Inhibition takes effect only if your `.emacs' file contains
e5575c06 69a line of this form:
54a003f7 70 (setq inhibit-startup-echo-area-message \"YOUR-USER-NAME\")
e5575c06
RS
71If your `.emacs' file is byte-compiled, use the following form instead:
72 (eval '(setq inhibit-startup-echo-area-message \"YOUR-USER-NAME\"))
1d7da582
RS
73Thus, someone else using a copy of your `.emacs' file will see
74the startup message unless he personally acts to inhibit it.")
75
a726e0d1
JB
76(defconst inhibit-default-init nil
77 "*Non-nil inhibits loading the `default' library.")
78
79(defconst command-switch-alist nil
80 "Alist of command-line switches.
81Elements look like (SWITCH-STRING . HANDLER-FUNCTION).
82HANDLER-FUNCTION receives switch name as sole arg;
83remaining command-line args are in the variable `command-line-args-left'.")
84
860befc8
RS
85(defvar command-line-args-left nil
86 "List of command-line args not yet processed.")
87
a726e0d1
JB
88(defvar command-line-functions nil ;; lrs 7/31/89
89 "List of functions to process unrecognized command-line arguments.
90Each function should access the dynamically bound variables
b4484ea8 91`argi' (the current argument) and `command-line-args-left' (the remaining
a726e0d1 92arguments). The function should return non-nil only if it recognizes and
b4484ea8
RS
93processes `argi'. If it does so, it may consume successive arguments by
94altering `command-line-args-left' to remove them.")
a726e0d1 95
09a1077c
RS
96(defvar command-line-default-directory nil
97 "Default directory to use for command line arguments.
98This is normally copied from `default-directory' when Emacs starts.")
99
e3bd99f5 100(defvar before-init-hook nil
b4484ea8 101 "Functions to call after handling urgent options but before init files.
0cc89026 102The frame system uses this to open frames to display messages while
3fc958a4
JB
103Emacs loads the user's initialization file.")
104
e3bd99f5 105(defvar after-init-hook nil
a0965605 106 "Functions to call after loading the init file (`~/.emacs').
e3bd99f5 107The call is not protected by a condition-case, so you can set `debug-on-error'
a0965605 108in `.emacs', and put all the actual code on `after-init-hook'.")
e3bd99f5 109
a726e0d1 110(defvar term-setup-hook nil
b4484ea8 111 "Functions to be called after loading terminal-specific Lisp code.
e3bd99f5 112See `run-hooks'. This variable exists for users to set,
a726e0d1
JB
113so as to override the definitions made by the terminal-specific file.
114Emacs never sets this variable itself.")
115
116(defvar keyboard-type nil
b4484ea8
RS
117 "The brand of keyboard you are using.
118This variable is used to define
a726e0d1
JB
119the proper function and keypad keys for use under X. It is used in a
120fashion analogous to the environment value TERM.")
121
122(defvar window-setup-hook nil
b4484ea8
RS
123 "Normal hook run to initialize window system display.
124Emacs runs this hook after processing the command line arguments and loading
125the user's init file.")
a726e0d1
JB
126
127(defconst initial-major-mode 'lisp-interaction-mode
128 "Major mode command symbol to use for the initial *scratch* buffer.")
129
130(defvar init-file-user nil
131 "Identity of user whose `.emacs' file is or was read.
2bdfaa42
KH
132The value is nil if no init file is being used; otherwise, it may be either
133the null string, meaning that the init file was taken from the user that
134originally logged in, or it may be a string containing a user's name.
a726e0d1 135
2bdfaa42
KH
136In either of the latter cases, `(concat \"~\" init-file-user \"/\")'
137evaluates to the name of the directory where the `.emacs' file was
138looked for.")
a726e0d1 139
b7444d31
RS
140(defvar site-run-file "site-start"
141 "File containing site-wide run-time initializations.
142This file is loaded at run-time before `~/.emacs'. It contains inits
143that need to be in place for the entire site, but which, due to their
144higher incidence of change, don't make sense to load into emacs'
145dumped image. Thus, the run-time load order is: 1. file described in
146this variable, if non-nil; 2. `~/.emacs'; 3. `default.el'.")
147
30dc01ea
RS
148(defconst iso-8859-1-locale-regexp "8859[-_]?1"
149 "Regexp that specifies when to enable the ISO 8859-1 character set.
150We do that if this regexp matches the locale name
151specified by the LC_ALL, LC_CTYPE and LANG environment variables.")
152
c13fbb62
RS
153(defvar mail-host-address nil
154 "*Name of this machine, for purposes of naming users.")
155
c10d1f06 156(defvar user-mail-address nil
c13fbb62 157 "*Full mailing address of this user.")
c10d1f06 158
a726e0d1
JB
159(defvar init-file-debug nil)
160
52320897
RS
161(defvar init-file-had-error nil)
162
e87a7309
RS
163;; This function is called from the subdirs.el file.
164(defun normal-top-level-add-to-load-path (dirs)
165 (let ((tail (member default-directory load-path)))
166 (setcdr tail (append (mapcar 'expand-file-name dirs) (cdr tail)))))
167
a726e0d1
JB
168(defun normal-top-level ()
169 (if command-line-processed
170 (message "Back to top level.")
171 (setq command-line-processed t)
e87a7309
RS
172 ;; Look in each dir in load-path for a subdirs.el file.
173 ;; If we find one, load it, which will add the appropriate subdirs
174 ;; of that dir into load-path,
175 (let ((tail load-path)
176 new)
177 (while tail
178 (setq new (cons (car tail) new))
179 (let ((default-directory (car tail)))
180 (load (expand-file-name "subdirs.el" (car tail)) t t t))
181 (setq tail (cdr tail))))
ffd56f97 182 (if (not (eq system-type 'vax-vms))
a4b33896
JB
183 (progn
184 ;; If the PWD environment variable isn't accurate, delete it.
185 (let ((pwd (getenv "PWD")))
186 (and (stringp pwd)
187 ;; Use FOO/., so that if FOO is a symlink, file-attributes
188 ;; describes the directory linked to, not FOO itself.
189 (or (equal (file-attributes
190 (concat (file-name-as-directory pwd) "."))
191 (file-attributes
192 (concat (file-name-as-directory default-directory)
193 ".")))
194 (setq process-environment
195 (delete (concat "PWD=" pwd)
196 process-environment)))))))
492878e4 197 (setq default-directory (abbreviate-file-name default-directory))
c13fbb62
RS
198 (setq user-mail-address (concat (user-login-name) "@"
199 (or mail-host-address
200 (system-name))))
6f2c86fa
KH
201 (let ((menubar-bindings-done nil))
202 (unwind-protect
203 (command-line)
204 ;; Do this again, in case .emacs defined more abbreviations.
205 (setq default-directory (abbreviate-file-name default-directory))
206 (run-hooks 'emacs-startup-hook)
207 (and term-setup-hook
208 (run-hooks 'term-setup-hook))
209 ;; Modify the initial frame based on what .emacs puts into
210 ;; ...-frame-alist.
211 (if (fboundp 'frame-notice-user-settings)
212 (frame-notice-user-settings))
213 ;; Now we know the user's default font, so add it to the menu.
214 (if (fboundp 'font-menu-add-default)
215 (font-menu-add-default))
216 (and window-setup-hook
217 (run-hooks 'window-setup-hook))
218 (or menubar-bindings-done
219 (precompute-menubar-bindings))))))
220
221;; Precompute the keyboard equivalents in the menu bar items.
222(defun precompute-menubar-bindings ()
42a49b29 223 (if (eq window-system 'x)
6f2c86fa
KH
224 (let ((submap (lookup-key global-map [menu-bar])))
225 (while submap
226 (and (consp (car submap))
227 (symbolp (car (car submap)))
228 (stringp (car-safe (cdr (car submap))))
229 (keymapp (cdr (cdr (car submap))))
230 (x-popup-menu nil (cdr (cdr (car submap)))))
231 (setq submap (cdr submap))))))
a726e0d1
JB
232
233(defun command-line ()
09a1077c
RS
234 (setq command-line-default-directory default-directory)
235
74f2ab06 236 ;; See if we should import version-control from the environment variable.
a726e0d1
JB
237 (let ((vc (getenv "VERSION_CONTROL")))
238 (cond ((eq vc nil)) ;don't do anything if not set
239 ((or (string= vc "t")
240 (string= vc "numbered"))
241 (setq version-control t))
242 ((or (string= vc "nil")
243 (string= vc "existing"))
244 (setq version-control nil))
245 ((or (string= vc "never")
246 (string= vc "simple"))
247 (setq version-control 'never))))
248
30dc01ea
RS
249 (if (let ((ctype
250 ;; Use the first of these three envvars that has a nonempty value.
251 (or (let ((string (getenv "LC_ALL")))
252 (and (not (equal string "")) string))
253 (let ((string (getenv "LC_CTYPE")))
254 (and (not (equal string "")) string))
255 (let ((string (getenv "LANG")))
256 (and (not (equal string "")) string)))))
257 (and ctype
258 (string-match iso-8859-1-locale-regexp ctype)))
e9d8e8c7 259 (progn
62bb5440 260 (require 'disp-table)
e9d8e8c7
RS
261 (standard-display-european t)
262 (require 'iso-syntax)))
263
79058860
JB
264 ;;! This has been commented out; I currently find the behavior when
265 ;;! split-window-keep-point is nil disturbing, but if I can get used
266 ;;! to it, then it would be better to eliminate the option.
267 ;;! ;; Choose a good default value for split-window-keep-point.
268 ;;! (setq split-window-keep-point (> baud-rate 2400))
f35fe3c6 269
a726e0d1 270 ;; Read window system's init file if using a window system.
1ed14cfd
RS
271 (condition-case error
272 (if (and window-system (not noninteractive))
273 (load (concat term-file-prefix
274 (symbol-name window-system)
275 "-win")
276 ;; Every window system should have a startup file;
277 ;; barf if we can't find it.
278 nil t))
279 ;; If we can't read it, print the error message and exit.
280 (error
2677ad61
RS
281 (princ
282 (if (eq (car error) 'error)
283 (apply 'concat (cdr error))
284 (if (memq 'file-error (get (car error) 'error-conditions))
285 (format "%s: %s"
286 (nth 1 error)
287 (mapconcat '(lambda (obj) (prin1-to-string obj t))
288 (cdr (cdr error)) ", "))
289 (format "%s: %s"
290 (get (car error) 'error-message)
291 (mapconcat '(lambda (obj) (prin1-to-string obj t))
292 (cdr error) ", "))))
293 'external-debugging-output)
294 (setq window-system nil)
1ed14cfd 295 (kill-emacs)))
a726e0d1 296
03e3c30a
JB
297 (let ((done nil)
298 (args (cdr command-line-args)))
299
a726e0d1
JB
300 ;; Figure out which user's init file to load,
301 ;; either from the environment or from the options.
302 (setq init-file-user (if noninteractive nil (user-login-name)))
303 ;; If user has not done su, use current $HOME to find .emacs.
304 (and init-file-user (string= init-file-user (user-real-login-name))
305 (setq init-file-user ""))
03e3c30a
JB
306
307 ;; Process the command-line args, and delete the arguments
308 ;; processed. This is consistent with the way main in emacs.c
309 ;; does things.
a726e0d1 310 (while (and (not done) args)
096b7031
KH
311 (let ((longopts '(("--no-init-file") ("--no-site-file") ("--user")
312 ("--debug-init")))
313 (argi (car args))
314 (argval nil))
315 (if (string-match "=" argi)
a981e7ff
KH
316 (setq argval (substring argi (match-end 0))
317 argi (substring argi 0 (match-beginning 0))))
096b7031
KH
318 (let ((completion (try-completion argi longopts)))
319 (if (eq completion t)
320 (setq argi (substring argi 1))
321 (if (stringp completion)
322 (let ((elt (assoc completion longopts)))
323 (or elt
324 (error "Option `%s' is ambiguous" argi))
3f53ddd0
RS
325 (setq argi (substring (car elt) 1)))
326 (setq argval nil))))
a726e0d1
JB
327 (cond
328 ((or (string-equal argi "-q")
329 (string-equal argi "-no-init-file"))
330 (setq init-file-user nil
331 args (cdr args)))
332 ((or (string-equal argi "-u")
333 (string-equal argi "-user"))
096b7031
KH
334 (or argval
335 (setq argval (car args)
336 args (cdr args)))
337 (setq init-file-user argval
338 argval nil
a726e0d1 339 args (cdr args)))
b7444d31
RS
340 ((string-equal argi "-no-site-file")
341 (setq site-run-file nil
342 args (cdr args)))
a726e0d1
JB
343 ((string-equal argi "-debug-init")
344 (setq init-file-debug t
345 args (cdr args)))
096b7031
KH
346 (t (setq done t)))
347 ;; Was argval set but not used?
348 (and argval
349 (error "Option `%s' doesn't allow an argument" argi))))
350
03e3c30a
JB
351 ;; Re-attach the program name to the front of the arg list.
352 (setcdr command-line-args args))
a726e0d1 353
c722566c 354 ;; Under X Windows, this creates the X frame and deletes the terminal frame.
4e1b1e72
JB
355 (if (fboundp 'face-initialize)
356 (face-initialize))
853ccbd5
RS
357 (if (fboundp 'frame-initialize)
358 (frame-initialize))
1fe0333f
RS
359 ;; If frame was created with a menu bar, set menu-bar-mode on.
360 (if (and (eq window-system 'x)
361 (> (cdr (assq 'menu-bar-lines (frame-parameters))) 0))
362 (menu-bar-mode t))
c722566c 363
e3bd99f5 364 (run-hooks 'before-init-hook)
3fc958a4 365
09973c54
RM
366 ;; Run the site-start library if it exists. The point of this file is
367 ;; that it is run before .emacs. There is no point in doing this after
368 ;; .emacs; that is useless.
b7444d31
RS
369 (if site-run-file
370 (load site-run-file t t))
09973c54 371
8a988f45
RS
372 ;; Sites should not disable this. Only individuals should disable
373 ;; the startup message.
374 (setq inhibit-startup-message nil)
375
a726e0d1 376 ;; Load that user's init file, or the default one, or none.
3d1b78f0
RS
377 (let (debug-on-error-from-init-file
378 debug-on-error-should-be-set
379 (debug-on-error-initial
380 (if (eq init-file-debug t) 'startup init-file-debug)))
381 (let ((debug-on-error debug-on-error-initial)
382 ;; This function actually reads the init files.
383 (inner
384 (function
385 (lambda ()
386 (if init-file-user
a4c5c705
RS
387 (progn
388 (setq user-init-file
389 (cond
390 ((eq system-type 'ms-dos)
391 (concat "~" init-file-user "/_emacs"))
7d1aa45d
RS
392 ((eq system-type 'windows-nt)
393 "~/_emacs")
a4c5c705
RS
394 ((eq system-type 'vax-vms)
395 "sys$login:.emacs")
396 (t
397 (concat "~" init-file-user "/.emacs"))))
398 (load user-init-file t t t)
399 (or inhibit-default-init
400 (let ((inhibit-startup-message nil))
401 ;; Users are supposed to be told their rights.
402 ;; (Plus how to get help and how to undo.)
403 ;; Don't you dare turn this off for anyone
404 ;; except yourself.
405 (load "default" t t)))))))))
3d1b78f0
RS
406 (if init-file-debug
407 ;; Do this without a condition-case if the user wants to debug.
408 (funcall inner)
409 (condition-case error
410 (progn
411 (funcall inner)
412 (setq init-file-had-error nil))
413 (error (message "Error in init file: %s%s%s"
414 (get (car error) 'error-message)
ad2aeb8d 415 (if (cdr error) ": " "")
3d1b78f0
RS
416 (mapconcat 'prin1-to-string (cdr error) ", "))
417 (setq init-file-had-error t))))
ad2aeb8d 418 ;; If we can tell that the init file altered debug-on-error,
3d1b78f0
RS
419 ;; arrange to preserve the value that it set up.
420 (or (eq debug-on-error debug-on-error-initial)
421 (setq debug-on-error-should-be-set t
422 debug-on-error-from-init-file debug-on-error)))
423 (if debug-on-error-should-be-set
424 (setq debug-on-error debug-on-error-from-init-file)))
3fc958a4 425
e3bd99f5
RM
426 (run-hooks 'after-init-hook)
427
a726e0d1
JB
428 ;; If *scratch* exists and init file didn't change its mode, initialize it.
429 (if (get-buffer "*scratch*")
430 (save-excursion
431 (set-buffer "*scratch*")
432 (if (eq major-mode 'fundamental-mode)
433 (funcall initial-major-mode))))
434 ;; Load library for our terminal type.
435 ;; User init file can set term-file-prefix to nil to prevent this.
436 (and term-file-prefix (not noninteractive) (not window-system)
437 (let ((term (getenv "TERM"))
438 hyphend)
439 (while (and term
440 (not (load (concat term-file-prefix term) t t)))
441 ;; Strip off last hyphen and what follows, then try again
442 (if (setq hyphend (string-match "[-_][^-_]+$" term))
443 (setq term (substring term 0 hyphend))
444 (setq term nil)))))
445
03e3c30a 446 ;; Process the remaining args.
a726e0d1
JB
447 (command-line-1 (cdr command-line-args))
448
449 ;; If -batch, terminate after processing the command options.
450 (if noninteractive (kill-emacs t)))
451
452(defun command-line-1 (command-line-args-left)
52320897 453 (or noninteractive (input-pending-p) init-file-had-error
1d7da582
RS
454 (and inhibit-startup-echo-area-message
455 (let ((buffer (get-buffer-create " *temp*")))
456 (prog1
457 (condition-case nil
458 (save-excursion
459 (set-buffer buffer)
460 (insert-file-contents user-init-file)
461 (re-search-forward
462 (concat
d9a71a8f
RS
463 "([ \t\n]*setq[ \t\n]+"
464 "inhibit-startup-echo-area-message[ \t\n]+"
465 (regexp-quote
466 (prin1-to-string
467 (if (string= init-file-user "")
468 (user-login-name)
469 init-file-user)))
470 "[ \t\n]*)")
1d7da582
RS
471 nil t))
472 (error nil))
473 (kill-buffer buffer))))
474 (message (if (eq (key-binding "\C-h\C-p") 'describe-project)
475 "For information about the GNU Project and its goals, type C-h C-p."
476 (substitute-command-keys
477 "For information about the GNU Project and its goals, type \\[describe-project]."))))
a726e0d1
JB
478 (if (null command-line-args-left)
479 (cond ((and (not inhibit-startup-message) (not noninteractive)
480 ;; Don't clobber a non-scratch buffer if init file
481 ;; has selected it.
482 (string= (buffer-name) "*scratch*")
483 (not (input-pending-p)))
484 ;; If there are no switches to process, we might as well
485 ;; run this hook now, and there may be some need to do it
486 ;; before doing any output.
487 (and term-setup-hook
488 (run-hooks 'term-setup-hook))
489 ;; Don't let the hook be run twice.
490 (setq term-setup-hook nil)
4e1b1e72
JB
491
492 ;; It's important to notice the user settings before we
493 ;; display the startup message; otherwise, the settings
494 ;; won't take effect until the user gives the first
495 ;; keystroke, and that's distracting.
496 (if (fboundp 'frame-notice-user-settings)
497 (frame-notice-user-settings))
498
a726e0d1
JB
499 (and window-setup-hook
500 (run-hooks 'window-setup-hook))
501 (setq window-setup-hook nil)
fd11871a
RS
502 ;; Do this now to avoid an annoying delay if the user
503 ;; clicks the menu bar during the sit-for.
504 (precompute-menubar-bindings)
505 (setq menubar-bindings-done t)
a726e0d1
JB
506 (unwind-protect
507 (progn
508 (insert (emacs-version)
509 "
1d7da582 510Copyright (C) 1994 Free Software Foundation, Inc.\n\n")
a726e0d1
JB
511 ;; If keys have their default meanings,
512 ;; use precomputed string to save lots of time.
513 (if (and (eq (key-binding "\C-h") 'help-command)
514 (eq (key-binding "\C-xu") 'advertised-undo)
515 (eq (key-binding "\C-x\C-c") 'save-buffers-kill-emacs)
e65a6404
RS
516 (eq (key-binding "\C-ht") 'help-with-tutorial)
517 (eq (key-binding "\C-hi") 'info))
a726e0d1
JB
518 (insert
519 "Type C-h for help; C-x u to undo changes. (`C-' means use CTRL key.)
520To kill the Emacs job, type C-x C-c.
521Type C-h t for a tutorial on using Emacs.
e65a6404
RS
522Type C-h i to enter Info, which you can use to read GNU documentation.")
523 (insert (substitute-command-keys
524 (format "Type %s for help; \\[advertised-undo] to undo changes. (`C-' means use CTRL key.)
525To kill the Emacs job, type \\[save-buffers-kill-emacs].
526Type \\[help-with-tutorial] for a tutorial on using Emacs.
527Type \\[info] to enter Info, which you can use to read GNU documentation."
528 (let ((where (where-is-internal
529 'help-command nil t)))
530 (if where
531 (key-description where)
532 "M-x help"))))))
533
534 ;; Windows and MSDOS (currently) do not count as
535 ;; window systems, but do have mouse support.
1ca92e26 536 (if (or (memq system-type '(msdos windowsnt))
e65a6404
RS
537 window-system)
538 (insert "
539C-mouse-3 (third mouse button, with Control) gets a mode-specific menu."))
540 (insert "\n")
541 (if (and (eq (key-binding "\C-h\C-c") 'describe-copying)
542 (eq (key-binding "\C-h\C-d") 'describe-distribution)
543 (eq (key-binding "\C-h\C-w") 'describe-no-warranty))
544 (insert
545 "
a726e0d1
JB
546GNU Emacs comes with ABSOLUTELY NO WARRANTY; type C-h C-w for full details.
547You may give out copies of Emacs; type C-h C-c to see the conditions.
548Type C-h C-d for information on getting the latest version.")
549 (insert (substitute-command-keys
e65a6404 550 "
a726e0d1
JB
551GNU Emacs comes with ABSOLUTELY NO WARRANTY; type \\[describe-no-warranty] for full details.
552You may give out copies of Emacs; type \\[describe-copying] to see the conditions.
553Type \\[describe-distribution] for information on getting the latest version.")))
554 (set-buffer-modified-p nil)
555 (sit-for 120))
556 (save-excursion
557 ;; In case the Emacs server has already selected
558 ;; another buffer, erase the one our message is in.
559 (set-buffer (get-buffer "*scratch*"))
560 (erase-buffer)
561 (set-buffer-modified-p nil)))))
09a1077c 562 (let ((dir command-line-default-directory)
a726e0d1
JB
563 (file-count 0)
564 first-file-buffer
565 (line 0))
566 (while command-line-args-left
3f53ddd0
RS
567 (let* ((argi (car command-line-args-left))
568 (orig-argi argi)
569 ;; This includes our standard options' long versions
570 ;; and long versions of what's on command-switch-alist.
571 (longopts
572 (append '(("--funcall") ("--load") ("--insert") ("--kill"))
573 (mapcar '(lambda (elt)
574 (list (concat "-" (car elt))))
575 command-switch-alist)))
576 tem argval completion)
a726e0d1 577 (setq command-line-args-left (cdr command-line-args-left))
3f53ddd0
RS
578
579 ;; Convert long options to ordinary options
580 ;; and separate out an attached option argument into argval.
581 (if (string-match "^--[^=]*=" argi)
582 (setq argval (substring argi (match-end 0))
583 argi (substring argi 0 (1- (match-end 0)))))
584 (setq completion (try-completion argi longopts))
585 (if (eq completion t)
586 (setq argi (substring argi 1))
587 (if (stringp completion)
588 (let ((elt (assoc completion longopts)))
589 (or elt
590 (error "Option `%s' is ambiguous" argi))
591 (setq argi (substring (car elt) 1)))
592 (setq argval nil argi orig-argi)))
593
594 ;; Execute the option.
a726e0d1 595 (cond ((setq tem (assoc argi command-switch-alist))
3f53ddd0
RS
596 (if argval
597 (let ((command-line-args-left
598 (cons argval command-line-args-left)))
599 (funcall (cdr tem) argi))
600 (funcall (cdr tem) argi)))
a726e0d1
JB
601 ((or (string-equal argi "-f") ;what the manual claims
602 (string-equal argi "-funcall")
603 (string-equal argi "-e")) ; what the source used to say
3f53ddd0
RS
604 (if argval
605 (setq tem (intern argval))
606 (setq tem (intern (car command-line-args-left)))
607 (setq command-line-args-left (cdr command-line-args-left)))
a726e0d1
JB
608 (funcall tem))
609 ((or (string-equal argi "-l")
610 (string-equal argi "-load"))
3f53ddd0
RS
611 (if argval
612 (setq tem argval)
613 (setq tem (car command-line-args-left)
614 command-line-args-left (cdr command-line-args-left)))
615 (let ((file tem))
a726e0d1
JB
616 ;; Take file from default dir if it exists there;
617 ;; otherwise let `load' search for it.
618 (if (file-exists-p (expand-file-name file))
619 (setq file (expand-file-name file)))
3f53ddd0 620 (load file nil t)))
fbce8654 621 ((string-equal argi "-insert")
cf91c6c8 622 (or (stringp (car command-line-args-left))
3f53ddd0
RS
623 (error "File name omitted from `-insert' option"))
624 (if argval
625 (setq tem argval)
626 (setq tem (car command-line-args-left)
627 command-line-args-left (cdr command-line-args-left)))
628 (insert-file-contents tem))
a726e0d1
JB
629 ((string-equal argi "-kill")
630 (kill-emacs t))
631 ((string-match "^\\+[0-9]+\\'" argi)
632 (setq line (string-to-int argi)))
633 (t
634 ;; We have almost exhausted our options. See if the
635 ;; user has made any other command-line options available
636 (let ((hooks command-line-functions);; lrs 7/31/89
637 (did-hook nil))
638 (while (and hooks
639 (not (setq did-hook (funcall (car hooks)))))
640 (setq hooks (cdr hooks)))
641 (if (not did-hook)
642 ;; Ok, presume that the argument is a file name
643 (progn
644 (setq file-count (1+ file-count))
645 (cond ((= file-count 1)
646 (setq first-file-buffer
647 (find-file (expand-file-name argi dir))))
648 (t
649 (find-file-other-window (expand-file-name argi dir))))
650 (or (zerop line)
651 (goto-line line))
652 (setq line 0))))))))
653 ;; If 3 or more files visited, and not all visible,
654 ;; show user what they all are.
655 (if (> file-count 2)
656 (or (get-buffer-window first-file-buffer)
7e0795a4 657 (progn (other-window 1)
e8997612 658 (buffer-menu)))))))
c88ab9ce
ER
659
660;;; startup.el ends here