startup.el 69.3 KB
Newer Older
Eric S. Raymond's avatar
Eric S. Raymond committed
1 2
;;; startup.el --- process Emacs shell arguments

3
;; Copyright (C) 1985, 1986, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
4
;;   2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
Eric S. Raymond's avatar
Eric S. Raymond committed
5

Eric S. Raymond's avatar
Eric S. Raymond committed
6
;; Maintainer: FSF
Eric S. Raymond's avatar
Eric S. Raymond committed
7
;; Keywords: internal
Eric S. Raymond's avatar
Eric S. Raymond committed
8

Jim Blandy's avatar
Jim Blandy committed
9 10 11 12
;; This file is part of GNU Emacs.

;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
Jim Blandy's avatar
Jim Blandy committed
13
;; the Free Software Foundation; either version 2, or (at your option)
Jim Blandy's avatar
Jim Blandy committed
14 15 16 17 18 19 20 21
;; any later version.

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
Erik Naggum's avatar
Erik Naggum committed
22
;; along with GNU Emacs; see the file COPYING.  If not, write to the
Lute Kamstra's avatar
Lute Kamstra committed
23 24
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
Jim Blandy's avatar
Jim Blandy committed
25

Eric S. Raymond's avatar
Eric S. Raymond committed
26
;;; Commentary:
Jim Blandy's avatar
Jim Blandy committed
27

28 29 30
;; This file parses the command line and gets Emacs running.  Options
;; on the command line are handled in precedence order.  For priorities
;; see the structure standard_args in the emacs.c file.
Jim Blandy's avatar
Jim Blandy committed
31

Eric S. Raymond's avatar
Eric S. Raymond committed
32 33
;;; Code:

Jim Blandy's avatar
Jim Blandy committed
34 35
(setq top-level '(normal-top-level))

Richard M. Stallman's avatar
Richard M. Stallman committed
36
(defvar command-line-processed nil
37
  "Non-nil once command line has been processed.")
Jim Blandy's avatar
Jim Blandy committed
38

Richard M. Stallman's avatar
Richard M. Stallman committed
39
(defgroup initialization nil
40
  "Emacs start-up procedure."
Richard M. Stallman's avatar
Richard M. Stallman committed
41 42 43
  :group 'internal)

(defcustom inhibit-startup-message nil
44
  "*Non-nil inhibits the initial startup message.
Jim Blandy's avatar
Jim Blandy committed
45
This is for use in your personal init file, once you are familiar
Richard M. Stallman's avatar
Richard M. Stallman committed
46 47 48
with the contents of the startup message."
  :type 'boolean
  :group 'initialization)
Jim Blandy's avatar
Jim Blandy committed
49

50 51
(defvaralias 'inhibit-splash-screen 'inhibit-startup-message)

Richard M. Stallman's avatar
Richard M. Stallman committed
52
(defcustom inhibit-startup-echo-area-message nil
53
  "*Non-nil inhibits the initial startup echo area message.
Richard M. Stallman's avatar
Richard M. Stallman committed
54 55
Setting this variable takes effect
only if you do it with the customization buffer
Karl Heuer's avatar
Karl Heuer committed
56
or if your `.emacs' file contains a line of this form:
57
 (setq inhibit-startup-echo-area-message \"YOUR-USER-NAME\")
58 59
If your `.emacs' file is byte-compiled, use the following form instead:
 (eval '(setq inhibit-startup-echo-area-message \"YOUR-USER-NAME\"))
60
Thus, someone else using a copy of your `.emacs' file will see
Richard M. Stallman's avatar
Richard M. Stallman committed
61 62 63 64
the startup message unless he personally acts to inhibit it."
  :type '(choice (const :tag "Don't inhibit")
		 (string :tag "Enter your user name, to inhibit"))
  :group 'initialization)
65

Richard M. Stallman's avatar
Richard M. Stallman committed
66 67 68 69
(defcustom inhibit-default-init nil
  "*Non-nil inhibits loading the `default' library."
  :type 'boolean
  :group 'initialization)
Jim Blandy's avatar
Jim Blandy committed
70

71 72 73 74 75
(defcustom inhibit-startup-buffer-menu nil
  "*Non-nil inhibits display of buffer list when more than 2 files are loaded."
  :type 'boolean
  :group 'initialization)

76
(defvar command-switch-alist nil
Jim Blandy's avatar
Jim Blandy committed
77 78
  "Alist of command-line switches.
Elements look like (SWITCH-STRING . HANDLER-FUNCTION).
79 80
HANDLER-FUNCTION receives the switch string as its sole argument;
the remaining command-line args are in the variable `command-line-args-left'.")
Jim Blandy's avatar
Jim Blandy committed
81

82 83 84
(defvar command-line-args-left nil
  "List of command-line args not yet processed.")

Jim Blandy's avatar
Jim Blandy committed
85 86 87
(defvar command-line-functions nil    ;; lrs 7/31/89
  "List of functions to process unrecognized command-line arguments.
Each function should access the dynamically bound variables
Richard M. Stallman's avatar
Richard M. Stallman committed
88
`argi' (the current argument) and `command-line-args-left' (the remaining
Jim Blandy's avatar
Jim Blandy committed
89
arguments).  The function should return non-nil only if it recognizes and
Richard M. Stallman's avatar
Richard M. Stallman committed
90 91
processes `argi'.  If it does so, it may consume successive arguments by
altering `command-line-args-left' to remove them.")
Jim Blandy's avatar
Jim Blandy committed
92

93 94 95 96
(defvar command-line-default-directory nil
  "Default directory to use for command line arguments.
This is normally copied from `default-directory' when Emacs starts.")

97 98
;;; This is here, rather than in x-win.el, so that we can ignore these
;;; options when we are not using X.
99
(defconst command-line-x-option-alist
100 101 102
  '(("-bw" 1 x-handle-numeric-switch border-width)
    ("-d" 1 x-handle-display)
    ("-display" 1 x-handle-display)
103
    ("-name" 1 x-handle-name-switch)
104 105
    ("-title" 1 x-handle-switch title)
    ("-T" 1 x-handle-switch title)
106 107 108 109 110 111
    ("-r" 0 x-handle-switch reverse t)
    ("-rv" 0 x-handle-switch reverse t)
    ("-reverse" 0 x-handle-switch reverse t)
    ("-reverse-video" 0 x-handle-switch reverse t)
    ("-fn" 1 x-handle-switch font)
    ("-font" 1 x-handle-switch font)
112 113 114
    ("-fs" 0 x-handle-initial-switch fullscreen fullboth)
    ("-fw" 0 x-handle-initial-switch fullscreen fullwidth)
    ("-fh" 0 x-handle-initial-switch fullscreen fullheight)
115
    ("-ib" 1 x-handle-numeric-switch internal-border-width)
116
    ("-g" 1 x-handle-geometry)
117
    ("-lsp" 1 x-handle-numeric-switch line-spacing)
118
    ("-geometry" 1 x-handle-geometry)
119 120 121 122 123
    ("-fg" 1 x-handle-switch foreground-color)
    ("-foreground" 1 x-handle-switch foreground-color)
    ("-bg" 1 x-handle-switch background-color)
    ("-background" 1 x-handle-switch background-color)
    ("-ms" 1 x-handle-switch mouse-color)
124
    ("-nbi" 0 x-handle-switch icon-type nil)
125 126 127 128 129 130 131 132
    ("-iconic" 0 x-handle-iconic)
    ("-xrm" 1 x-handle-xrm-switch)
    ("-cr" 1 x-handle-switch cursor-color)
    ("-vb" 0 x-handle-switch vertical-scroll-bars t)
    ("-hb" 0 x-handle-switch horizontal-scroll-bars t)
    ("-bd" 1 x-handle-switch)
    ("--border-width" 1 x-handle-numeric-switch border-width)
    ("--display" 1 x-handle-display)
133
    ("--name" 1 x-handle-name-switch)
134
    ("--title" 1 x-handle-switch title)
135 136
    ("--reverse-video" 0 x-handle-switch reverse t)
    ("--font" 1 x-handle-switch font)
137 138 139
    ("--fullscreen" 0 x-handle-initial-switch fullscreen fullboth)
    ("--fullwidth" 0 x-handle-initial-switch fullscreen fullwidth)
    ("--fullheight" 0 x-handle-initial-switch fullscreen fullheight)
140
    ("--internal-border" 1 x-handle-numeric-switch internal-border-width)
141
    ("--geometry" 1 x-handle-geometry)
142 143 144
    ("--foreground-color" 1 x-handle-switch foreground-color)
    ("--background-color" 1 x-handle-switch background-color)
    ("--mouse-color" 1 x-handle-switch mouse-color)
145
    ("--no-bitmap-icon" 0 x-handle-switch icon-type nil)
146 147 148 149
    ("--iconic" 0 x-handle-iconic)
    ("--xrm" 1 x-handle-xrm-switch)
    ("--cursor-color" 1 x-handle-switch cursor-color)
    ("--vertical-scroll-bars" 0 x-handle-switch vertical-scroll-bars t)
150
    ("--line-spacing" 1 x-handle-numeric-switch line-spacing)
151
    ("--border-color" 1 x-handle-switch border-color)
152
    ("--smid" 1 x-handle-smid))
153 154 155 156 157 158 159 160 161
  "Alist of X Windows options.
Each element has the form
  (NAME NUMARGS HANDLER FRAME-PARAM VALUE)
where NAME is the option name string, NUMARGS is the number of arguments
that the option accepts, HANDLER is a function to call to handle the option.
FRAME-PARAM (optional) is the frame parameter this option specifies,
and VALUE is the value which is given to that frame parameter
\(most options use the argument for this, so VALUE is not present).")

Roland McGrath's avatar
Roland McGrath committed
162
(defvar before-init-hook nil
163
  "Normal hook run after handling urgent options but before loading init files.")
Jim Blandy's avatar
Jim Blandy committed
164

Roland McGrath's avatar
Roland McGrath committed
165
(defvar after-init-hook nil
166 167 168 169 170 171 172
  "Normal hook run after loading the init files, `~/.emacs' and `default.el'.
There is no `condition-case' around the running of these functions;
therefore, if you set `debug-on-error' non-nil in `.emacs',
an error in one of these functions will invoke the debugger.")

(defvar emacs-startup-hook nil
  "Normal hook run after loading init files and handling the command line.")
Roland McGrath's avatar
Roland McGrath committed
173

Jim Blandy's avatar
Jim Blandy committed
174
(defvar term-setup-hook nil
175 176
  "Normal hook run after loading terminal-specific Lisp code.
It also follows `emacs-startup-hook'.  This hook exists for users to set,
Jim Blandy's avatar
Jim Blandy committed
177 178 179
so as to override the definitions made by the terminal-specific file.
Emacs never sets this variable itself.")

180 181 182 183
(defvar inhibit-startup-hooks nil
  "Non-nil means don't run `term-setup-hook' and `emacs-startup-hook'.
This is because we already did so.")

Jim Blandy's avatar
Jim Blandy committed
184
(defvar keyboard-type nil
Richard M. Stallman's avatar
Richard M. Stallman committed
185
  "The brand of keyboard you are using.
186 187 188
This variable is used to define the proper function and keypad
keys for use under X.  It is used in a fashion analogous to the
environment variable TERM.")
Jim Blandy's avatar
Jim Blandy committed
189 190

(defvar window-setup-hook nil
Richard M. Stallman's avatar
Richard M. Stallman committed
191 192 193
  "Normal hook run to initialize window system display.
Emacs runs this hook after processing the command line arguments and loading
the user's init file.")
Jim Blandy's avatar
Jim Blandy committed
194

Richard M. Stallman's avatar
Richard M. Stallman committed
195 196
(defcustom initial-major-mode 'lisp-interaction-mode
  "Major mode command symbol to use for the initial *scratch* buffer."
197
  :type 'function
Richard M. Stallman's avatar
Richard M. Stallman committed
198
  :group 'initialization)
Jim Blandy's avatar
Jim Blandy committed
199

Richard M. Stallman's avatar
Richard M. Stallman committed
200
(defcustom init-file-user nil
Jim Blandy's avatar
Jim Blandy committed
201
  "Identity of user whose `.emacs' file is or was read.
202 203 204 205 206 207
The value is nil if `-q' or `--no-init-file' was specified,
meaning do not load any init file.

Otherwise, the value may be the null string, meaning use the init file
for the user that originally logged in, or it may be a
string containing a user's name meaning use that person's init file.
Jim Blandy's avatar
Jim Blandy committed
208

Karl Heuer's avatar
Karl Heuer committed
209 210
In either of the latter cases, `(concat \"~\" init-file-user \"/\")'
evaluates to the name of the directory where the `.emacs' file was
211 212 213
looked for.

Setting `init-file-user' does not prevent Emacs from loading
Richard M. Stallman's avatar
Richard M. Stallman committed
214 215 216
`site-start.el'.  The only way to do that is to use `--no-site-file'."
  :type '(choice (const :tag "none" nil) string)
  :group 'initialization)
Jim Blandy's avatar
Jim Blandy committed
217

Richard M. Stallman's avatar
Richard M. Stallman committed
218
(defcustom site-run-file "site-start"
219 220 221
  "File containing site-wide run-time initializations.
This file is loaded at run-time before `~/.emacs'.  It contains inits
that need to be in place for the entire site, but which, due to their
222
higher incidence of change, don't make sense to load into Emacs's
223
dumped image.  Thus, the run-time load order is: 1. file described in
224 225 226 227 228 229 230
this variable, if non-nil; 2. `~/.emacs'; 3. `default.el'.

Don't use the `site-start.el' file for things some users may not like.
Put them in `default.el' instead, so that users can more easily
override them.  Users can prevent loading `default.el' with the `-q'
option or by setting `inhibit-default-init' in their own init files,
but inhibiting `site-start.el' requires `--no-site-file', which
231 232 233 234 235
is less convenient.

This variable is defined for customization so as to make
it visible in the relevant context.  However, actually customizing it
is not allowed, since it would not work anyway.  The only way to set
236
this variable usefully is to set it while building and dumping Emacs."
237
  :type '(choice (const :tag "none" nil) string)
238 239 240 241
  :group 'initialization
  :initialize 'custom-initialize-default
  :set '(lambda (variable value)
	  (error "Customizing `site-run-file' does not work")))
242

Richard M. Stallman's avatar
Richard M. Stallman committed
243 244 245 246
(defcustom mail-host-address nil
  "*Name of this machine, for purposes of naming users."
  :type '(choice (const nil) string)
  :group 'mail)
247

248 249 250 251 252 253
(defcustom user-mail-address (if command-line-processed
				 (concat (user-login-name) "@"
					 (or mail-host-address
					     (system-name)))
			       ;; Empty string means "not set yet".
			       "")
254 255
  "*Full mailing address of this user.
This is initialized based on `mail-host-address',
Richard M. Stallman's avatar
Richard M. Stallman committed
256 257 258
after your init file is read, in case it sets `mail-host-address'."
  :type 'string
  :group 'mail)
259

Richard M. Stallman's avatar
Richard M. Stallman committed
260
(defcustom auto-save-list-file-prefix
261 262
  (cond ((eq system-type 'ms-dos)
	 ;; MS-DOS cannot have initial dot, and allows only 8.3 names
263
	 "~/_emacs.d/auto-save.list/_s")
264 265
	(t
	 "~/.emacs.d/auto-save-list/.saves-"))
266 267 268 269
  "Prefix for generating `auto-save-list-file-name'.
This is used after reading your `.emacs' file to initialize
`auto-save-list-file-name', by appending Emacs's pid and the system name,
if you have not already set `auto-save-list-file-name' yourself.
270
Directories in the prefix will be created if necessary.
271
Set this to nil if you want to prevent `auto-save-list-file-name'
Richard M. Stallman's avatar
Richard M. Stallman committed
272
from being initialized."
273 274
  :type '(choice (const :tag "Don't record a session's auto save list" nil)
		 string)
Richard M. Stallman's avatar
Richard M. Stallman committed
275
  :group 'auto-save)
276

277 278
(defvar emacs-quick-startup nil)

279 280
(defvar emacs-basic-display nil)

Jim Blandy's avatar
Jim Blandy committed
281 282
(defvar init-file-debug nil)

283 284
(defvar init-file-had-error nil)

285 286
(defvar normal-top-level-add-subdirs-inode-list nil)

287 288
(defvar no-blinking-cursor nil)

289 290
(defvar default-frame-background-mode)

291 292 293
(defvar pure-space-overflow nil
  "Non-nil if building Emacs overflowed pure space.")

294
(defun normal-top-level-add-subdirs-to-load-path ()
295 296
  "Add all subdirectories of current directory to `load-path'.
More precisely, this uses only the subdirectories whose names
297 298
start with letters or digits; it excludes any subdirectory named `RCS'
or `CVS', and any subdirectory that contains a file named `.nosearch'."
299
  (let (dirs
300
	attrs
301 302 303 304
	(pending (list default-directory)))
    ;; This loop does a breadth-first tree walk on DIR's subtree,
    ;; putting each subdir into DIRS as its contents are examined.
    (while pending
305
      (push (pop pending) dirs)
306 307 308
      (let* ((this-dir (car dirs))
	     (contents (directory-files this-dir))
	     (default-directory this-dir)
309 310
	     (canonicalized (if (fboundp 'untranslated-canonical-name)
				(untranslated-canonical-name this-dir))))
311 312 313 314 315
	;; The Windows version doesn't report meaningful inode
	;; numbers, so use the canonicalized absolute file name of the
	;; directory instead.
	(setq attrs (or canonicalized
			(nthcdr 10 (file-attributes this-dir))))
316
	(unless (member attrs normal-top-level-add-subdirs-inode-list)
317 318
	  (push attrs normal-top-level-add-subdirs-inode-list)
	  (dolist (file contents)
319
	    ;; The lower-case variants of RCS and CVS are for DOS/Windows.
320 321
	    (unless (member file '("." ".." "RCS" "CVS" "rcs" "cvs"))
	      (when (and (string-match "\\`[[:alnum:]]" file)
322 323 324
			 ;; Avoid doing a `stat' when it isn't necessary
			 ;; because that can cause trouble when an NFS server
			 ;; is down.
325 326 327
			 (not (string-match "\\.elc?\\'" file))
			 (file-directory-p file))
		(let ((expanded (expand-file-name file)))
328 329
		  (unless (file-exists-p (expand-file-name ".nosearch"
							   expanded))
330
		    (setq pending (nconc pending (list expanded)))))))))))
331
    (normal-top-level-add-to-load-path (cdr (nreverse dirs)))))
332

Richard M. Stallman's avatar
Richard M. Stallman committed
333 334 335 336 337
;; This function is called from a subdirs.el file.
;; It assumes that default-directory is the directory
;; in which the subdirs.el file exists,
;; and it adds to load-path the subdirs of that directory
;; as specified in DIRS.  Normally the elements of DIRS are relative.
338
(defun normal-top-level-add-to-load-path (dirs)
339 340 341
  (let ((tail load-path)
	(thisdir (directory-file-name default-directory)))
    (while (and tail
342 343
		;;Don't go all the way to the nil terminator.
		(cdr tail)
344 345 346 347
		(not (equal thisdir (car tail)))
		(not (and (memq system-type '(ms-dos windows-nt))
			  (equal (downcase thisdir) (downcase (car tail))))))
      (setq tail (cdr tail)))
348 349 350
    ;;Splice the new section in.
    (when tail
      (setcdr tail (append (mapcar 'expand-file-name dirs) (cdr tail))))))
351

Jim Blandy's avatar
Jim Blandy committed
352 353 354 355
(defun normal-top-level ()
  (if command-line-processed
      (message "Back to top level.")
    (setq command-line-processed t)
356 357 358
    ;; Give *Messages* the same default-directory as *scratch*,
    ;; just to keep things predictable.
    (let ((dir default-directory))
359
      (with-current-buffer "*Messages*"
360
	(setq default-directory dir)))
361 362 363
    ;; `user-full-name' is now known; reset its standard-value here.
    (put 'user-full-name 'standard-value
	 (list (default-value 'user-full-name)))
Karl Heuer's avatar
Karl Heuer committed
364 365 366
    ;; For root, preserve owner and group when editing files.
    (if (equal (user-uid) 0)
	(setq backup-by-copying-when-mismatch t))
367 368 369
    ;; Look in each dir in load-path for a subdirs.el file.
    ;; If we find one, load it, which will add the appropriate subdirs
    ;; of that dir into load-path,
370 371
    ;; Look for a leim-list.el file too.  Loading it will register
    ;; available input methods.
372 373 374 375 376 377 378 379 380 381 382
    (let ((tail load-path) dir)
      (while tail
        (setq dir (car tail))
        (let ((default-directory dir))
          (load (expand-file-name "subdirs.el") t t t))
        (let ((default-directory dir))
          (load (expand-file-name "leim-list.el") t t t))
        ;; We don't use a dolist loop and we put this "setq-cdr" command at
        ;; the end, because the subdirs.el files may add elements to the end
        ;; of load-path and we want to take it into account.
        (setq tail (cdr tail))))
383 384 385 386 387 388 389 390 391 392 393 394 395 396
    (unless (eq system-type 'vax-vms)
      ;; If the PWD environment variable isn't accurate, delete it.
      (let ((pwd (getenv "PWD")))
	(and (stringp pwd)
	     ;; Use FOO/., so that if FOO is a symlink, file-attributes
	     ;; describes the directory linked to, not FOO itself.
	     (or (equal (file-attributes
			 (concat (file-name-as-directory pwd) "."))
			(file-attributes
			 (concat (file-name-as-directory default-directory)
				 ".")))
		 (setq process-environment
		       (delete (concat "PWD=" pwd)
			       process-environment))))))
Jim Blandy's avatar
Jim Blandy committed
397
    (setq default-directory (abbreviate-file-name default-directory))
398 399 400 401 402
    (let ((menubar-bindings-done nil))
      (unwind-protect
	  (command-line)
	;; Do this again, in case .emacs defined more abbreviations.
	(setq default-directory (abbreviate-file-name default-directory))
403 404
	;; Specify the file for recording all the auto save files of this session.
	;; This is used by recover-session.
405 406 407
	(or auto-save-list-file-name
	    (and auto-save-list-file-prefix
		 (setq auto-save-list-file-name
408 409
		       ;; Under MS-DOS our PID is almost always reused between
		       ;; Emacs invocations.  We need something more unique.
410 411 412 413 414 415
		       (cond ((eq system-type 'ms-dos)
			      ;; We are going to access the auto-save
			      ;; directory, so make sure it exists.
			      (make-directory
			       (file-name-directory auto-save-list-file-prefix)
			       t)
416
			      (concat
417 418 419 420 421 422 423 424 425 426
			       (make-temp-name
				(expand-file-name
				 auto-save-list-file-prefix))
			       "~"))
			     (t
			      (expand-file-name
			       (format "%s%d-%s~"
				       auto-save-list-file-prefix
				       (emacs-pid)
				       (system-name))))))))
427 428 429 430
	(unless inhibit-startup-hooks
	  (run-hooks 'emacs-startup-hook)
	  (and term-setup-hook
	       (run-hooks 'term-setup-hook)))
431 432 433

	;; Don't do this if we failed to create the initial frame,
	;; for instance due to a dense colormap.
434 435 436 437 438
	(when (or frame-initial-frame
		  ;; If frame-initial-frame has no meaning, do this anyway.
		  (not (and window-system
			    (not noninteractive)
			    (not (eq window-system 'pc)))))
439 440 441 442 443 444 445 446 447
	  ;; Modify the initial frame based on what .emacs puts into
	  ;; ...-frame-alist.
	  (if (fboundp 'frame-notice-user-settings)
	      (frame-notice-user-settings))
	  (if (fboundp 'frame-set-background-mode)
	      ;; Set the faces for the initial background mode even if
	      ;; frame-notice-user-settings didn't (such as on a tty).
	      ;; frame-set-background-mode is idempotent, so it won't
	      ;; cause any harm if it's already been done.
448
	      (let ((frame (selected-frame))
449 450
		    term)
		(when (and (null window-system)
451 452
			   ;; Don't override default set by files in lisp/term.
			   (null default-frame-background-mode)
453 454
			   (let ((bg (frame-parameter frame 'background-color)))
			     (or (null bg)
455 456 457
				 (member bg '(unspecified "unspecified-bg"
							  "unspecified-fg")))))

458
		  (setq term (getenv "TERM"))
459 460 461
		  ;; Some files in lisp/term do a better job with the
		  ;; background mode, but we leave this here anyway, in
		  ;; case they remove those files.
462 463
		  (if (string-match "^\\(xterm\\|rxvt\\|dtterm\\|eterm\\)"
				    term)
464
		      (setq default-frame-background-mode 'light)))
465
		(frame-set-background-mode (selected-frame)))))
Miles Bader's avatar
Miles Bader committed
466

467 468 469 470 471 472
	;; Now we know the user's default font, so add it to the menu.
	(if (fboundp 'font-menu-add-default)
	    (font-menu-add-default))
	(and window-setup-hook
	     (run-hooks 'window-setup-hook))
	(or menubar-bindings-done
473 474
	    (if (display-popup-menus-p)
		(precompute-menubar-bindings)))))))
475 476 477

;; Precompute the keyboard equivalents in the menu bar items.
(defun precompute-menubar-bindings ()
478 479 480 481 482 483
  (let ((submap (lookup-key global-map [menu-bar])))
    (while submap
      (and (consp (car submap))
	   (symbolp (car (car submap)))
	   (stringp (car-safe (cdr (car submap))))
	   (keymapp (cdr (cdr (car submap))))
484 485 486 487
	   (progn
	     (x-popup-menu nil (cdr (cdr (car submap))))
	     (if purify-flag
		 (garbage-collect))))
488
      (setq submap (cdr submap))))
489
    (setq define-key-rebound-commands t))
Jim Blandy's avatar
Jim Blandy committed
490

491 492
;; Command-line options supported by tty's:
(defconst tty-long-option-alist
493 494 495
  '(("--name"		  . "-name")
    ("--title"		  . "-T")
    ("--reverse-video"	  . "-reverse")
496
    ("--foreground-color" . "-fg")
497 498
    ("--background-color" . "-bg")
    ("--color"		  . "-color")))
499

500 501 502
(defconst tool-bar-images-pixel-height 24
  "Height in pixels of images in the tool bar.")

503 504 505
(defvar tool-bar-originally-present nil
  "Non-nil if tool-bars are present before user and site init files are read.")

506
;; Handle the X-like command-line arguments "-fg", "-bg", "-name", etc.
507
(defun tty-handle-args (args)
508
  (let (rest)
509 510 511
    (message "%s" args)
    (while (and args
		(not (equal (car args) "--")))
512 513 514
      (let* ((argi (pop args))
	     (orig-argi argi)
	     argval completion)
515 516
	;; Check for long options with attached arguments
	;; and separate out the attached option argument into argval.
517 518 519 520 521
	(when (string-match "^\\(--[^=]*\\)=" argi)
          (setq argval (substring argi (match-end 0))
                argi (match-string 1 argi)))
	(when (string-match "^--" argi)
	  (setq completion (try-completion argi tty-long-option-alist))
522 523
	  (if (eq completion t)
	      ;; Exact match for long option.
524
	      (setq argi (cdr (assoc argi tty-long-option-alist)))
525 526 527 528
	    (if (stringp completion)
		(let ((elt (assoc completion tty-long-option-alist)))
		  ;; Check for abbreviated long option.
		  (or elt
529 530
		      (error "Option `%s' is ambiguous" argi))
		  (setq argi (cdr elt)))
531
	      ;; Check for a short option.
532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570
	      (setq argval nil
                    argi orig-argi))))
	(cond ((member argi '("-fg" "-foreground"))
	       (push (cons 'foreground-color (or argval (pop args)))
                     default-frame-alist))
	      ((member argi '("-bg" "-background"))
	       (push (cons 'background-color (or argval (pop args)))
                     default-frame-alist))
	      ((member argi '("-T" "-name"))
	       (unless argval (setq argval (pop args)))
	       (push (cons 'title
                           (if (stringp argval)
                               argval
                             (let ((case-fold-search t)
                                   i)
                               (setq argval (invocation-name))

                               ;; Change any . or * characters in name to
                               ;; hyphens, so as to emulate behavior on X.
                               (while
                                   (setq i (string-match "[.*]" argval))
                                 (aset argval i ?-))
                               argval)))
                     default-frame-alist))
	      ((member argi '("-r" "-rv" "-reverse"))
	       (push '(reverse . t)
                     default-frame-alist))
	      ((equal argi "-color")
	       (unless argval (setq argval 8)) ; default --color means 8 ANSI colors
	       (push (cons 'tty-color-mode
                           (cond
                            ((numberp argval) argval)
                            ((string-match "-?[0-9]+" argval)
                             (string-to-number argval))
                            (t (intern argval))))
                     default-frame-alist))
	      (t
               (push argi rest)))))
    (nreverse rest)))
571

Jim Blandy's avatar
Jim Blandy committed
572
(defun command-line ()
573 574
  (setq command-line-default-directory default-directory)

575
  ;; Choose a reasonable location for temporary files.
576
  (custom-reevaluate-setting 'temporary-file-directory)
577
  (custom-reevaluate-setting 'small-temporary-file-directory)
578
  (custom-reevaluate-setting 'auto-save-file-name-transforms)
579

Roland McGrath's avatar
Roland McGrath committed
580
  ;; See if we should import version-control from the environment variable.
Jim Blandy's avatar
Jim Blandy committed
581 582
  (let ((vc (getenv "VERSION_CONTROL")))
    (cond ((eq vc nil))			;don't do anything if not set
583
	  ((member vc '("t" "numbered"))
Jim Blandy's avatar
Jim Blandy committed
584
	   (setq version-control t))
585
	  ((member vc '("nil" "existing"))
Jim Blandy's avatar
Jim Blandy committed
586
	   (setq version-control nil))
587
	  ((member vc '("never" "simple"))
Jim Blandy's avatar
Jim Blandy committed
588 589
	   (setq version-control 'never))))

Jim Blandy's avatar
Jim Blandy committed
590 591 592 593 594
  ;;! This has been commented out; I currently find the behavior when
  ;;! split-window-keep-point is nil disturbing, but if I can get used
  ;;! to it, then it would be better to eliminate the option.
  ;;! ;; Choose a good default value for split-window-keep-point.
  ;;! (setq split-window-keep-point (> baud-rate 2400))
Jim Blandy's avatar
Jim Blandy committed
595

596 597 598 599
  ;; Set the default strings to display in mode line for
  ;; end-of-line formats that aren't native to this platform.
  (cond
   ((memq system-type '(ms-dos windows-nt emx))
600 601
    (setq eol-mnemonic-unix "(Unix)"
          eol-mnemonic-mac  "(Mac)"))
602 603 604 605
   ;; Both Mac and Unix EOLs are now "native" on Mac OS so keep the
   ;; abbreviated strings `/' and `:' set in coding.c for them.
   ((eq system-type 'macos)
    (setq eol-mnemonic-dos  "(DOS)"))
606 607 608
   (t                                   ; this is for Unix/GNU/Linux systems
    (setq eol-mnemonic-dos  "(DOS)"
          eol-mnemonic-mac  "(Mac)")))
609

Jim Blandy's avatar
Jim Blandy committed
610
  ;; Read window system's init file if using a window system.
611 612 613 614 615 616 617 618 619 620
  (condition-case error
      (if (and window-system (not noninteractive))
	  (load (concat term-file-prefix
			(symbol-name window-system)
			"-win")
		;; Every window system should have a startup file;
		;; barf if we can't find it.
		nil t))
    ;; If we can't read it, print the error message and exit.
    (error
621 622 623 624 625
     (princ
      (if (eq (car error) 'error)
	  (apply 'concat (cdr error))
	(if (memq 'file-error (get (car error) 'error-conditions))
	    (format "%s: %s"
626 627 628
                    (nth 1 error)
                    (mapconcat (lambda (obj) (prin1-to-string obj t))
                               (cdr (cdr error)) ", "))
629
	  (format "%s: %s"
630 631 632
                  (get (car error) 'error-message)
                  (mapconcat (lambda (obj) (prin1-to-string obj t))
                             (cdr error) ", "))))
633
      'external-debugging-output)
634
     (terpri 'external-debugging-output)
635
     (setq window-system nil)
636
     (kill-emacs)))
Jim Blandy's avatar
Jim Blandy committed
637

638
  ;; Windowed displays do this inside their *-win.el.
639
  (unless (or (display-graphic-p) noninteractive)
640 641
    (setq command-line-args (tty-handle-args command-line-args)))

642 643
  (set-locale-environment nil)

644 645 646 647 648 649 650 651 652 653 654
  ;; Convert preloaded file names to absolute.
  (setq load-history
	(mapcar (lambda (elt)
		  (if (and (stringp (car elt))
			   (not (file-name-absolute-p (car elt))))
		      (cons (locate-file (car elt) load-path
					 load-suffixes)
			    (cdr elt))
		    elt))
		load-history))

655 656 657 658 659
  ;; Convert the arguments to Emacs internal representation.
  (let ((args (cdr command-line-args)))
    (while args
      (setcar args
	      (decode-coding-string (car args) locale-coding-system t))
660
      (pop args)))
661

Jim Blandy's avatar
Jim Blandy committed
662 663 664
  (let ((done nil)
	(args (cdr command-line-args)))

Jim Blandy's avatar
Jim Blandy committed
665 666 667 668
    ;; Figure out which user's init file to load,
    ;; either from the environment or from the options.
    (setq init-file-user (if noninteractive nil (user-login-name)))
    ;; If user has not done su, use current $HOME to find .emacs.
669 670
    (and init-file-user
         (equal init-file-user (user-real-login-name))
Jim Blandy's avatar
Jim Blandy committed
671
	 (setq init-file-user ""))
Jim Blandy's avatar
Jim Blandy committed
672 673 674 675

    ;; Process the command-line args, and delete the arguments
    ;; processed.  This is consistent with the way main in emacs.c
    ;; does things.
Jim Blandy's avatar
Jim Blandy committed
676
    (while (and (not done) args)
677 678 679
      (let* ((longopts '(("--no-init-file") ("--no-site-file") ("--debug-init")
                         ("--user") ("--iconic") ("--icon-type") ("--quick")
			 ("--no-blinking-cursor") ("--basic-display")))
680 681 682
             (argi (pop args))
             (orig-argi argi)
             argval)
683
	;; Handle --OPTION=VALUE format.
684
	(when (string-match "^\\(--[^=]*\\)=" argi)
685
	  (setq argval (substring argi (match-end 0))
686
                argi (match-string 1 argi)))
687 688 689 690 691 692 693 694 695
	(unless (equal argi "--")
	  (let ((completion (try-completion argi longopts)))
	    (if (eq completion t)
		(setq argi (substring argi 1))
	      (if (stringp completion)
		  (let ((elt (assoc completion longopts)))
		    (or elt
			(error "Option `%s' is ambiguous" argi))
		    (setq argi (substring (car elt) 1)))
696 697
		(setq argval nil
                      argi orig-argi)))))
Jim Blandy's avatar
Jim Blandy committed
698
	(cond
699
	 ((member argi '("-Q" "-quick"))
700 701
	  (setq init-file-user nil
		site-run-file nil
702 703 704 705
		emacs-quick-startup t))
	 ((member argi '("-D" "-basic-display"))
	  (setq no-blinking-cursor t
		emacs-basic-display t)
706
	  (push '(vertical-scroll-bars . nil) initial-frame-alist))
707 708 709
	 ((member argi '("-q" "-no-init-file"))
	  (setq init-file-user nil))
	 ((member argi '("-u" "-user"))
710
	  (setq init-file-user (or argval (pop args))
711
		argval nil))
712
	 ((equal argi "-no-site-file")
713
	  (setq site-run-file nil))
714
	 ((equal argi "-debug-init")
715
	  (setq init-file-debug t))
716
	 ((equal argi "-iconic")
717
	  (push '(visibility . icon) initial-frame-alist))
718
	 ((member argi '("-icon-type" "-i" "-itype"))
719
	  (push '(icon-type . t) default-frame-alist))
720 721
	 ((member argi '("-nbc" "-no-blinking-cursor"))
	  (setq no-blinking-cursor t))
722
	 ;; Push the popped arg back on the list of arguments.
723 724 725
	 (t
          (push argi args)
          (setq done t)))
726 727 728 729
	;; Was argval set but not used?
	(and argval
	     (error "Option `%s' doesn't allow an argument" argi))))

Jim Blandy's avatar
Jim Blandy committed
730
    ;; Re-attach the program name to the front of the arg list.
731 732
    (and command-line-args
         (setcdr command-line-args args)))
Jim Blandy's avatar
Jim Blandy committed
733

734 735
  (run-hooks 'before-init-hook)

736
  ;; Under X Window, this creates the X frame and deletes the terminal frame.
737 738 739
  (when (fboundp 'frame-initialize)
    (frame-initialize))

740
  ;; Turn off blinking cursor if so specified in X resources.  This is here
Jan Djärv's avatar
Jan Djärv committed
741
  ;; only because all other settings of no-blinking-cursor are here.
742 743 744 745 746 747 748
  (unless (or noninteractive
	      emacs-basic-display
	      (and (memq window-system '(x w32 mac))
		   (not (member (x-get-resource "cursorBlink" "CursorBlink")
				'("off" "false")))))
    (setq no-blinking-cursor t))

749
  ;; If frame was created with a menu bar, set menu-bar-mode on.
750
  (unless (or noninteractive
751
	      emacs-basic-display
752 753
              (and (memq window-system '(x w32))
                   (<= (frame-parameter nil 'menu-bar-lines) 0)))
754
    (menu-bar-mode 1))
755

756
  ;; If frame was created with a tool bar, switch tool-bar-mode on.
757
  (unless (or noninteractive
758
	      emacs-basic-display
759 760
              (not (display-graphic-p))
              (<= (frame-parameter nil 'tool-bar-lines) 0))
761
    (tool-bar-mode 1))
762

763
  ;; Can't do this init in defcustom because the relevant variables
764 765 766
  ;; are not set.
  (custom-reevaluate-setting 'blink-cursor-mode)
  (custom-reevaluate-setting 'normal-erase-is-backspace)
767
  (custom-reevaluate-setting 'tooltip-mode)
768

769 770
  ;; Register default TTY colors for the case the terminal hasn't a
  ;; terminal init file.
771 772 773 774 775
  (unless (memq window-system '(x w32))
    ;; We do this regardles of whether the terminal supports colors
    ;; or not, since they can switch that support on or off in
    ;; mid-session by setting the tty-color-mode frame parameter.
    (tty-register-default-colors))
776

777 778 779 780 781 782 783 784
  ;; Record whether the tool-bar is present before the user and site
  ;; init files are processed.  frame-notice-user-settings uses this
  ;; to determine if the tool-bar has been disabled by the init files,
  ;; and the frame needs to be resized.
  (when (fboundp 'frame-notice-user-settings)
    (let ((tool-bar-lines (or (assq 'tool-bar-lines initial-frame-alist)
                              (assq 'tool-bar-lines default-frame-alist))))
      (setq tool-bar-originally-present
785 786 787
            (and tool-bar-lines
                 (cdr tool-bar-lines)
                 (not (eq 0 (cdr tool-bar-lines)))))))
788

789 790 791 792 793 794 795
  (let ((old-scalable-fonts-allowed scalable-fonts-allowed)
	(old-font-list-limit font-list-limit)
	(old-face-ignored-fonts face-ignored-fonts))

    ;; Run the site-start library if it exists.  The point of this file is
    ;; that it is run before .emacs.  There is no point in doing this after
    ;; .emacs; that is useless.
796
    (if site-run-file
797 798 799 800 801 802
	(load site-run-file t t))

    ;; Sites should not disable this.  Only individuals should disable
    ;; the startup message.
    (setq inhibit-startup-message nil)

803
    ;; Warn for invalid user name.
804 805 806 807 808 809 810 811 812 813 814 815
    (when init-file-user
      (if (string-match "[~/:\n]" init-file-user)
	  (display-warning 'initialization
			   (format "Invalid user name %s"
				   init-file-user)
			   :error)
	(if (file-directory-p (expand-file-name (concat "~" init-file-user)))
	    nil
	  (display-warning 'initialization
			   (format "User %s has no home directory"
				   init-file-user)
			   :error))))
816

817 818 819 820 821 822 823 824 825 826 827 828 829
    ;; Load that user's init file, or the default one, or none.
    (let (debug-on-error-from-init-file
	  debug-on-error-should-be-set
	  (debug-on-error-initial
	   (if (eq init-file-debug t) 'startup init-file-debug))
	  (orig-enable-multibyte default-enable-multibyte-characters))
      (let ((debug-on-error debug-on-error-initial)
	    ;; This function actually reads the init files.
	    (inner
	     (function
	      (lambda ()
		(if init-file-user
		    (let ((user-init-file-1
830
			   (cond
831 832 833
			    ((eq system-type 'ms-dos)
			     (concat "~" init-file-user "/_emacs"))
			    ((eq system-type 'windows-nt)
834
			     ;; Prefer .emacs on Windows.
835 836
			     (if (directory-files "~" nil "^\\.emacs\\(\\.elc?\\)?$")
				 "~/.emacs"
837 838 839 840 841
			       ;; Also support _emacs for compatibility.
			       (if (directory-files "~" nil "^_emacs\\(\\.elc?\\)?$")
				   "~/_emacs"
				 ;; But default to .emacs if _emacs does not exist.
				 "~/.emacs")))
842
			    ((eq system-type 'vax-vms)
843
			     "sys$login:.emacs")
844
			    (t
845 846 847 848 849
			     (concat "~" init-file-user "/.emacs")))))
		      ;; This tells `load' to store the file name found
		      ;; into user-init-file.
		      (setq user-init-file t)
		      (load user-init-file-1 t t)
850

851 852
		      (when (eq user-init-file t)
			;; If we did not find ~/.emacs, try
853
			;; ~/.emacs.d/init.el.
854 855
			(let ((otherfile
			       (expand-file-name
856
				"init"
857
				(file-name-as-directory
858
				 (concat "~" init-file-user "/.emacs.d")))))
859 860 861 862 863 864 865
			  (load otherfile t t)

			  ;; If we did not find the user's init file,
			  ;; set user-init-file conclusively.
			  ;; Don't let it be set from default.el.
			  (when (eq user-init-file t)
			    (setq user-init-file user-init-file-1))))
866

867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883
		      ;; If we loaded a compiled file, set
		      ;; `user-init-file' to the source version if that
		      ;; exists.
		      (when (and user-init-file
				 (equal (file-name-extension user-init-file)
					"elc"))
			(let* ((source (file-name-sans-extension user-init-file))
			       (alt (concat source ".el")))
			  (setq source (cond ((file-exists-p alt) alt)
					     ((file-exists-p source) source)
					     (t nil)))
			  (when source
			    (when (file-newer-than-file-p source user-init-file)
			      (message "Warning: %s is newer than %s"
				       source user-init-file)
			      (sit-for 1))
			    (setq user-init-file source))))
884

885 886 887 888 889 890 891
		      (unless inhibit-default-init
                        (let ((inhibit-startup-message nil))
                          ;; Users are supposed to be told their rights.
                          ;; (Plus how to get help and how to undo.)
                          ;; Don't you dare turn this off for anyone
                          ;; except yourself.
                          (load "default" t t)))))))))
892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908
	(if init-file-debug
	    ;; Do this without a condition-case if the user wants to debug.
	    (funcall inner)
	  (condition-case error
	      (progn
		(funcall inner)
		(setq init-file-had-error nil))
	    (error
	     (let ((message-log-max nil))
	       (save-excursion
		 (set-buffer (get-buffer-create "*Messages*"))
		 (insert "\n\n"
			 (format "An error has occurred while loading `%s':\n\n"
				 user-init-file)
			 (format "%s%s%s"
				 (get (car error) 'error-message)
				 (if (cdr error) ": " "")
909
				 (mapconcat (lambda (s) (prin1-to-string s t)) (cdr error) ", "))
910
			 "\n\n"
911 912 913
			 "To ensure normal operation, you should investigate and remove the\n"
			 "cause of the error in your initialization file.  Start Emacs with\n"
			 "the `--debug-init' option to view a complete error backtrace.\n\n"))
914 915 916 917
	       (message "Error in init file: %s%s%s"
			(get (car error) 'error-message)
			(if (cdr error) ": " "")
			(mapconcat 'prin1-to-string (cdr error) ", "))
918 919
	       (let ((pop-up-windows nil))
		 (pop-to-buffer "*Messages*"))
920
	       (setq init-file-had-error t)))))
921 922 923 924 925

	;; If the user has a file of abbrevs, read it.
	(if (file-exists-p abbrev-file-name)
	    (quietly-read-abbrev-file abbrev-file-name))

926 927 928