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