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