startup.el 105 KB
Newer Older
1
;;; startup.el --- process Emacs shell arguments  -*- lexical-binding: t -*-
Eric S. Raymond's avatar
Eric S. Raymond committed
2

Paul Eggert's avatar
Paul Eggert committed
3
;; Copyright (C) 1985-1986, 1992, 1994-2016 Free Software Foundation,
Paul Eggert's avatar
Paul Eggert committed
4
;; Inc.
Eric S. Raymond's avatar
Eric S. Raymond committed
5

6
;; Maintainer: emacs-devel@gnu.org
Eric S. Raymond's avatar
Eric S. Raymond committed
7
;; Keywords: internal
8
;; Package: emacs
Eric S. Raymond's avatar
Eric S. Raymond committed
9

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

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

;; 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
23
;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
Jim Blandy's avatar
Jim Blandy committed
24

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

Kenichi Handa's avatar
Kenichi Handa committed
27 28 29
;; 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
30

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

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

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

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

(defcustom initial-buffer-choice nil
  "Buffer to show after starting Emacs.
44
If the value is nil and `inhibit-startup-screen' is nil, show the
45
startup screen.  If the value is a string, switch to a buffer
46 47 48
visiting the file or directory that the string specifies.  If the
value is a function, call it with no arguments and switch to the buffer
that it returns.  If t, open the `*scratch*' buffer.
49

50 51 52
When `initial-buffer-choice' is non-nil, the startup screen is
inhibited.

53 54
If you use `emacsclient' with no target file, then it obeys any
string or function value that this variable has."
55
  :type '(choice
56
	  (const     :tag "Startup screen" nil)
57
	  (directory :tag "Directory" :value "~/")
58
	  (file      :tag "File" :value "~/.emacs")
59 60
	  ;; Note sure about hard-coding this as an option...
	  (const     :tag "Remember Mode notes buffer" remember-notes)
61
	  (function  :tag "Function")
62
	  (const     :tag "Lisp scratch buffer" t))
63
  :version "23.1"
64
  :group 'initialization)
Richard M. Stallman's avatar
Richard M. Stallman committed
65

66
(defcustom inhibit-startup-screen nil
67 68
  "Non-nil inhibits the startup screen.

69 70
This is for use in your personal init file (but NOT site-start.el),
once you are familiar with the contents of the startup screen."
Richard M. Stallman's avatar
Richard M. Stallman committed
71 72
  :type 'boolean
  :group 'initialization)
Jim Blandy's avatar
Jim Blandy committed
73

74 75
(defvaralias 'inhibit-splash-screen 'inhibit-startup-screen)
(defvaralias 'inhibit-startup-message 'inhibit-startup-screen)
76

77
(defvar startup-screen-inhibit-startup-screen nil)
78

Dmitry Gutov's avatar
Dmitry Gutov committed
79
;; The mechanism used to ensure that only end users can disable this
80
;; message is not complex.  Clearly, it is possible for a determined
81 82 83
;; system administrator to inhibit this message anyway, but at least
;; they will do so with knowledge of why the Emacs developers think
;; this is a bad idea.
Richard M. Stallman's avatar
Richard M. Stallman committed
84
(defcustom inhibit-startup-echo-area-message nil
85
  "Non-nil inhibits the initial startup echo area message.
86

Dmitry Gutov's avatar
Dmitry Gutov committed
87
The startup message is in the echo area as it provides information
88
about GNU Emacs and the GNU system in general, which we want all
89
users to see.  As this is the least intrusive startup message,
90 91 92 93 94 95 96
this variable gets specialized treatment to prevent the message
from being disabled site-wide by systems administrators, while
still allowing individual users to do so.

Setting this variable takes effect only if you do it with the
customization buffer or if your init file contains a line of this
form:
97
 (setq inhibit-startup-echo-area-message \"YOUR-USER-NAME\")
98 99
If your init file is byte-compiled, use the following form
instead:
100
 (eval \\='(setq inhibit-startup-echo-area-message \"YOUR-USER-NAME\"))
101 102
Thus, someone else using a copy of your init file will see the
startup message unless he personally acts to inhibit it."
Richard M. Stallman's avatar
Richard M. Stallman committed
103 104 105
  :type '(choice (const :tag "Don't inhibit")
		 (string :tag "Enter your user name, to inhibit"))
  :group 'initialization)
106

Richard M. Stallman's avatar
Richard M. Stallman committed
107
(defcustom inhibit-default-init nil
108
  "Non-nil inhibits loading the `default' library."
Richard M. Stallman's avatar
Richard M. Stallman committed
109 110
  :type 'boolean
  :group 'initialization)
Jim Blandy's avatar
Jim Blandy committed
111

112
(defcustom inhibit-startup-buffer-menu nil
113
  "Non-nil inhibits display of buffer list when more than 2 files are loaded."
114 115 116
  :type 'boolean
  :group 'initialization)

117
(defvar command-switch-alist nil
Jim Blandy's avatar
Jim Blandy committed
118 119
  "Alist of command-line switches.
Elements look like (SWITCH-STRING . HANDLER-FUNCTION).
Kenichi Handa's avatar
Kenichi Handa committed
120 121
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
122

123 124 125
(defvar command-line-args-left nil
  "List of command-line args not yet processed.")

126 127
(defvaralias 'argv 'command-line-args-left
  "List of command-line args not yet processed.
128
This is a convenience alias, so that one can write \(pop argv)
129 130
inside of --eval command line arguments in order to access
following arguments.")
131
(internal-make-var-non-special 'argv)
132

133 134 135
(defvar argi nil
  "Current command-line argument.")
(internal-make-var-non-special 'argi)
136

Jim Blandy's avatar
Jim Blandy committed
137 138 139
(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
140
`argi' (the current argument) and `command-line-args-left' (the remaining
Jim Blandy's avatar
Jim Blandy committed
141
arguments).  The function should return non-nil only if it recognizes and
Richard M. Stallman's avatar
Richard M. Stallman committed
142 143
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
144

145 146 147 148
(defvar command-line-default-directory nil
  "Default directory to use for command line arguments.
This is normally copied from `default-directory' when Emacs starts.")

Stefan Monnier's avatar
Stefan Monnier committed
149 150
;; This is here, rather than in x-win.el, so that we can ignore these
;; options when we are not using X.
151
(defconst command-line-x-option-alist
152 153 154
  '(("-bw" 1 x-handle-numeric-switch border-width)
    ("-d" 1 x-handle-display)
    ("-display" 1 x-handle-display)
155
    ("-name" 1 x-handle-name-switch)
156 157
    ("-title" 1 x-handle-switch title)
    ("-T" 1 x-handle-switch title)
158 159 160 161 162 163
    ("-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)
164 165 166
    ("-fs" 0 x-handle-initial-switch fullscreen fullboth)
    ("-fw" 0 x-handle-initial-switch fullscreen fullwidth)
    ("-fh" 0 x-handle-initial-switch fullscreen fullheight)
167
    ("-mm" 0 x-handle-initial-switch fullscreen maximized)
168
    ("-ib" 1 x-handle-numeric-switch internal-border-width)
169
    ("-g" 1 x-handle-geometry)
170
    ("-lsp" 1 x-handle-numeric-switch line-spacing)
171
    ("-geometry" 1 x-handle-geometry)
172 173 174 175 176
    ("-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)
177
    ("-nbi" 0 x-handle-switch icon-type nil)
178 179 180 181 182 183 184 185
    ("-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)
186
    ("--name" 1 x-handle-name-switch)
187
    ("--title" 1 x-handle-switch title)
188 189
    ("--reverse-video" 0 x-handle-switch reverse t)
    ("--font" 1 x-handle-switch font)
190 191 192
    ("--fullscreen" 0 x-handle-initial-switch fullscreen fullboth)
    ("--fullwidth" 0 x-handle-initial-switch fullscreen fullwidth)
    ("--fullheight" 0 x-handle-initial-switch fullscreen fullheight)
193
    ("--maximized" 0 x-handle-initial-switch fullscreen maximized)
194
    ("--internal-border" 1 x-handle-numeric-switch internal-border-width)
195
    ("--geometry" 1 x-handle-geometry)
196 197 198
    ("--foreground-color" 1 x-handle-switch foreground-color)
    ("--background-color" 1 x-handle-switch background-color)
    ("--mouse-color" 1 x-handle-switch mouse-color)
199
    ("--no-bitmap-icon" 0 x-handle-no-bitmap-icon)
200 201 202 203
    ("--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)
204
    ("--line-spacing" 1 x-handle-numeric-switch line-spacing)
205
    ("--border-color" 1 x-handle-switch border-color)
206 207
    ("--smid" 1 x-handle-smid)
    ("--parent-id" 1 x-handle-parent-id))
208 209 210 211 212 213 214 215 216
  "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).")

217 218 219
(defconst command-line-ns-option-alist
  '(("-NSAutoLaunch" 1 ns-ignore-1-arg)
    ("-NXAutoLaunch" 1 ns-ignore-1-arg)
220
    ("-macosx" 0 ignore)
221 222 223 224 225 226 227 228 229 230 231
    ("-NSHost" 1 ns-ignore-1-arg)
    ("-_NSMachLaunch" 1 ns-ignore-1-arg)
    ("-MachLaunch" 1 ns-ignore-1-arg)
    ("-NXOpen" 1 ns-ignore-1-arg)
    ("-NSOpen" 1 ns-handle-nxopen)
    ("-NXOpenTemp" 1 ns-ignore-1-arg)
    ("-NSOpenTemp" 1 ns-handle-nxopentemp)
    ("-GSFilePath" 1 ns-handle-nxopen)
    ;;("-bw" .              x-handle-numeric-switch)
    ;;("-d" .               x-handle-display)
    ;;("-display" .         x-handle-display)
232 233 234 235 236 237 238 239 240
    ("-name" 1 x-handle-name-switch)
    ("-title" 1 x-handle-switch title)
    ("-T" 1 x-handle-switch title)
    ("-r" 0 x-handle-switch reverse t)
    ("-rv" 0 x-handle-switch reverse t)
    ("-reverse" 0 x-handle-switch reverse t)
    ("-fn" 1 x-handle-switch font)
    ("-font" 1 x-handle-switch font)
    ("-ib" 1 x-handle-numeric-switch internal-border-width)
241 242
    ("-g" 1 x-handle-geometry)
    ("-geometry" 1 x-handle-geometry)
243 244 245 246 247 248 249 250
    ("-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)
    ("-itype" 0 x-handle-switch icon-type t)
    ("-i" 0 x-handle-switch icon-type t)
    ("-iconic" 0 x-handle-iconic icon-type t)
251
    ;;("-xrm" .             x-handle-xrm-switch)
252 253 254 255 256
    ("-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)
257
    ;; ("--display" 1 ns-handle-display)
258 259 260 261 262
    ("--name" 1 x-handle-name-switch)
    ("--title" 1 x-handle-switch title)
    ("--reverse-video" 0 x-handle-switch reverse t)
    ("--font" 1 x-handle-switch font)
    ("--internal-border" 1 x-handle-numeric-switch internal-border-width)
263
    ;; ("--geometry" 1 ns-handle-geometry)
264 265 266 267 268
    ("--foreground-color" 1 x-handle-switch foreground-color)
    ("--background-color" 1 x-handle-switch background-color)
    ("--mouse-color" 1 x-handle-switch mouse-color)
    ("--icon-type" 0 x-handle-switch icon-type t)
    ("--iconic" 0 x-handle-iconic)
269
    ;; ("--xrm" 1 ns-handle-xrm-switch)
270 271 272
    ("--cursor-color" 1 x-handle-switch cursor-color)
    ("--vertical-scroll-bars" 0 x-handle-switch vertical-scroll-bars t)
    ("--border-color" 1 x-handle-switch border-width))
273 274 275 276 277 278 279 280 281 282
  "Alist of NS 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
283
(defvar before-init-hook nil
284
  "Normal hook run after handling urgent options but before loading init files.")
Jim Blandy's avatar
Jim Blandy committed
285

Roland McGrath's avatar
Roland McGrath committed
286
(defvar after-init-hook nil
287 288 289 290 291 292 293 294
  "Normal hook run after initializing the Emacs session.
It is run after Emacs loads the init file, `default' library, the
abbrevs file, and additional Lisp packages (if any), and setting
the value of `after-init-time'.

There is no `condition-case' around the running of this hook;
therefore, if `debug-on-error' is non-nil, an error in one of
these functions will invoke the debugger.")
295 296 297

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

Jim Blandy's avatar
Jim Blandy committed
299
(defvar term-setup-hook nil
300 301 302 303 304 305 306 307 308
  "Normal hook run immediately after `emacs-startup-hook'.
In new code, there is no reason to use this instead of `emacs-startup-hook'.
If you want to execute terminal-specific Lisp code, for example
to override the definitions made by the terminal-specific file,
see `tty-setup-hook'.")

(make-obsolete-variable 'term-setup-hook
			"use either `emacs-startup-hook' or \
`tty-setup-hook' instead." "24.4")
Jim Blandy's avatar
Jim Blandy committed
309

310
(defvar inhibit-startup-hooks nil
311 312 313
  "Non-nil means don't run some startup hooks, because we already did.
Currently this applies to: `emacs-startup-hook', `term-setup-hook',
and `window-setup-hook'.")
314

Jim Blandy's avatar
Jim Blandy committed
315
(defvar keyboard-type nil
Richard M. Stallman's avatar
Richard M. Stallman committed
316
  "The brand of keyboard you are using.
317 318 319
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
320 321

(defvar window-setup-hook nil
322 323 324 325 326 327
  "Normal hook run after loading init files and handling the command line.
This is very similar to `emacs-startup-hook'.  The only difference
is that this hook runs after frame parameters have been set up in
response to any settings from your init file.  Unless this matters
to you, use `emacs-startup-hook' instead.  (The name of this hook
is due to historical reasons, and does not reflect its purpose very well.)")
Jim Blandy's avatar
Jim Blandy committed
328

Richard M. Stallman's avatar
Richard M. Stallman committed
329
(defcustom initial-major-mode 'lisp-interaction-mode
330
  "Major mode command symbol to use for the initial `*scratch*' buffer."
331
  :type 'function
Richard M. Stallman's avatar
Richard M. Stallman committed
332
  :group 'initialization)
Jim Blandy's avatar
Jim Blandy committed
333

334
(defvar init-file-user nil
335
  "Identity of user whose init file is or was read.
336 337 338
The value is nil if `-q' or `--no-init-file' was specified,
meaning do not load any init file.

Eli Zaretskii's avatar
Eli Zaretskii committed
339 340 341 342
Otherwise, the value may be an empty string, meaning
use the init file for the user who 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
343

Karl Heuer's avatar
Karl Heuer committed
344
In either of the latter cases, `(concat \"~\" init-file-user \"/\")'
345
evaluates to the name of the directory where the init file was
346 347 348
looked for.

Setting `init-file-user' does not prevent Emacs from loading
349
`site-start.el'.  The only way to do that is to use `--no-site-file'.")
Jim Blandy's avatar
Jim Blandy committed
350

351
(defcustom site-run-file (purecopy "site-start")
352 353 354
  "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
355
higher incidence of change, don't make sense to load into Emacs's
356
dumped image.  Thus, the run-time load order is: 1. file described in
357 358 359 360 361 362 363
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
364 365 366 367 368
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
369
this variable usefully is to set it while building and dumping Emacs."
370
  :type '(choice (const :tag "none" nil) string)
371
  :group 'initialization
372
  :initialize #'custom-initialize-default
373
  :set (lambda (_variable _value)
374
	  (error "Customizing `site-run-file' does not work")))
375

376 377
(make-obsolete-variable 'system-name "use (system-name) instead" "25.1")

Richard M. Stallman's avatar
Richard M. Stallman committed
378
(defcustom mail-host-address nil
379 380 381
  "Name of this machine, for purposes of naming users.
If non-nil, Emacs uses this instead of `system-name' when constructing
email addresses."
Richard M. Stallman's avatar
Richard M. Stallman committed
382 383
  :type '(choice (const nil) string)
  :group 'mail)
384

385
(defcustom user-mail-address (if command-line-processed
386 387 388 389
				 (or (getenv "EMAIL")
				     (concat (user-login-name) "@"
					     (or mail-host-address
						 (system-name))))
390 391
			       ;; Empty string means "not set yet".
			       "")
392
  "Full mailing address of this user.
393
This is initialized with environment variable `EMAIL' or, as a
394
fallback, using `mail-host-address'.  This is done after your
395
init file is read, in case it sets `mail-host-address'."
Richard M. Stallman's avatar
Richard M. Stallman committed
396 397
  :type 'string
  :group 'mail)
398

Richard M. Stallman's avatar
Richard M. Stallman committed
399
(defcustom auto-save-list-file-prefix
400 401
  (cond ((eq system-type 'ms-dos)
	 ;; MS-DOS cannot have initial dot, and allows only 8.3 names
402
	 (concat user-emacs-directory "auto-save.list/_s"))
403
	(t
404
	 (concat user-emacs-directory "auto-save-list/.saves-")))
405
  "Prefix for generating `auto-save-list-file-name'.
406
This is used after reading your init file to initialize
407 408
`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.
409
Directories in the prefix will be created if necessary.
410
Set this to nil if you want to prevent `auto-save-list-file-name'
Richard M. Stallman's avatar
Richard M. Stallman committed
411
from being initialized."
412 413
  :type '(choice (const :tag "Don't record a session's auto save list" nil)
		 string)
Richard M. Stallman's avatar
Richard M. Stallman committed
414
  :group 'auto-save)
415

416 417
(defvar emacs-basic-display nil)

Jim Blandy's avatar
Jim Blandy committed
418 419
(defvar init-file-debug nil)

420 421
(defvar init-file-had-error nil
  "Non-nil if there was an error loading the user's init file.")
422

423 424
(defvar normal-top-level-add-subdirs-inode-list nil)

425 426
(defvar no-blinking-cursor nil)

427 428 429
(defvar pure-space-overflow nil
  "Non-nil if building Emacs overflowed pure space.")

430
(defvar pure-space-overflow-message (purecopy "\
431
Warning Warning!!!  Pure space overflow    !!!Warning Warning
432
\(See the node Pure Storage in the Lisp manual for details.)\n"))
433

434 435 436 437 438
(defcustom tutorial-directory
  (file-name-as-directory (expand-file-name "tutorials" data-directory))
  "Directory containing the Emacs TUTORIAL files."
  :group 'installation
  :type 'directory
439
  :initialize #'custom-initialize-delay)
440

441
(defun normal-top-level-add-subdirs-to-load-path ()
442
  "Recursively add all subdirectories of `default-directory' to `load-path'.
443
More precisely, this uses only the subdirectories whose names
444 445
start with letters or digits; it excludes any subdirectory named `RCS'
or `CVS', and any subdirectory that contains a file named `.nosearch'."
446
  (let (dirs
447
	attrs
448 449 450 451
	(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
452
      (push (pop pending) dirs)
453 454 455
      (let* ((this-dir (car dirs))
	     (contents (directory-files this-dir))
	     (default-directory this-dir)
456 457
	     (canonicalized (if (fboundp 'w32-untranslated-canonical-name)
				(w32-untranslated-canonical-name this-dir))))
Glenn Morris's avatar
Glenn Morris committed
458 459
	;; The Windows version doesn't report meaningful inode numbers, so
	;; use the canonicalized absolute file name of the directory instead.
460 461
	(setq attrs (or canonicalized
			(nthcdr 10 (file-attributes this-dir))))
462
	(unless (member attrs normal-top-level-add-subdirs-inode-list)
463 464
	  (push attrs normal-top-level-add-subdirs-inode-list)
	  (dolist (file contents)
Glenn Morris's avatar
Glenn Morris committed
465 466 467 468 469 470 471 472 473 474
	    (and (string-match "\\`[[:alnum:]]" file)
		 ;; The lower-case variants of RCS and CVS are for DOS/Windows.
		 (not (member file '("RCS" "CVS" "rcs" "cvs")))
		 ;; Avoid doing a `stat' when it isn't necessary because
		 ;; that can cause trouble when an NFS server is down.
		 (not (string-match "\\.elc?\\'" file))
		 (file-directory-p file)
		 (let ((expanded (expand-file-name file)))
		   (or (file-exists-p (expand-file-name ".nosearch" expanded))
		       (setq pending (nconc pending (list expanded))))))))))
475
    (normal-top-level-add-to-load-path (cdr (nreverse dirs)))))
476

477
(defun normal-top-level-add-to-load-path (dirs)
Glenn Morris's avatar
Glenn Morris committed
478 479 480 481 482
  "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."
483 484 485
  (let ((tail load-path)
	(thisdir (directory-file-name default-directory)))
    (while (and tail
486 487
		;;Don't go all the way to the nil terminator.
		(cdr tail)
488 489 490 491
		(not (equal thisdir (car tail)))
		(not (and (memq system-type '(ms-dos windows-nt))
			  (equal (downcase thisdir) (downcase (car tail))))))
      (setq tail (cdr tail)))
492 493 494
    ;;Splice the new section in.
    (when tail
      (setcdr tail (append (mapcar 'expand-file-name dirs) (cdr tail))))))
495

Jim Blandy's avatar
Jim Blandy committed
496
(defun normal-top-level ()
Glenn Morris's avatar
Glenn Morris committed
497 498 499 500
  "Emacs calls this function when it first starts up.
It sets `command-line-processed', processes the command-line,
reads the initialization files, etc.
It is the default value of the variable `top-level'."
Jim Blandy's avatar
Jim Blandy committed
501
  (if command-line-processed
502
      (message internal--top-level-message)
Jim Blandy's avatar
Jim Blandy committed
503
    (setq command-line-processed t)
504

505 506 507 508 509 510 511 512 513 514 515 516 517 518
    ;; 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.  This needs to be done before setting
    ;; the locale environment, because the latter might need to load
    ;; some support files.
    ;; Look for a leim-list.el file too.  Loading it will register
    ;; available input methods.
    (let ((tail load-path)
          (lispdir (expand-file-name "../lisp" data-directory))
          dir)
      (while tail
        (setq dir (car tail))
        (let ((default-directory dir))
          (load (expand-file-name "subdirs.el") t t t))
Glenn Morris's avatar
Glenn Morris committed
519 520
        ;; Do not scan standard directories that won't contain a leim-list.el.
        ;; http://lists.gnu.org/archive/html/emacs-devel/2009-10/msg00502.html
521
        ;; (Except the preloaded one in lisp/leim.)
Glenn Morris's avatar
Glenn Morris committed
522 523 524
        (or (string-prefix-p lispdir dir)
            (let ((default-directory dir))
              (load (expand-file-name "leim-list.el") t t t)))
525 526 527 528 529
        ;; 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))))

530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
    ;; Set the default strings to display in mode line for end-of-line
    ;; formats that aren't native to this platform.  This should be
    ;; done before calling set-locale-environment, as the latter might
    ;; use these mnemonics.
    (cond
     ((memq system-type '(ms-dos windows-nt))
      (setq eol-mnemonic-unix "(Unix)"
	    eol-mnemonic-mac  "(Mac)"))
     (t                                   ; this is for Unix/GNU/Linux systems
      (setq eol-mnemonic-dos  "(DOS)"
	    eol-mnemonic-mac  "(Mac)")))

    (set-locale-environment nil)
    ;; Decode all default-directory's (probably, only *scratch* exists
    ;; at this point).  default-directory of *scratch* is the basis
    ;; for many other file-name variables and directory lists, so it
    ;; is important to decode it ASAP.
    (when locale-coding-system
548 549 550 551 552 553 554 555 556 557
      (let ((coding (if (eq system-type 'windows-nt)
			;; MS-Windows build converts all file names to
			;; UTF-8 during startup.
			'utf-8
		      locale-coding-system)))
	(save-excursion
	  (dolist (elt (buffer-list))
	    (set-buffer elt)
	    (if default-directory
		(setq default-directory
558 559 560 561 562
                      (if (eq system-type 'windows-nt)
                          ;; Convert backslashes to forward slashes.
                          (expand-file-name
                           (decode-coding-string default-directory coding t))
                        (decode-coding-string default-directory coding t))))))
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590

	;; Decode all the important variables and directory lists, now
	;; that we know the locale's encoding.  This is because the
	;; values of these variables are until here unibyte undecoded
	;; strings created by build_unibyte_string.  data-directory in
	;; particular is used to construct many other standard
	;; directory names, so it must be decoded ASAP.  Note that
	;; charset-map-path cannot be decoded here, since we could
	;; then be trapped in infinite recursion below, when we load
	;; subdirs.el, because encoding a directory name might need to
	;; load a charset map, which will want to encode
	;; charset-map-path, which will want to load the same charset
	;; map...  So decoding of charset-map-path is delayed until
	;; further down below.
	(dolist (pathsym '(load-path exec-path))
	  (let ((path (symbol-value pathsym)))
	    (if (listp path)
		(set pathsym (mapcar (lambda (dir)
				       (decode-coding-string dir coding t))
				     path)))))
	(dolist (filesym '(data-directory doc-directory exec-directory
					  installation-directory
					  invocation-directory invocation-name
					  source-directory
					  shared-game-score-directory))
	  (let ((file (symbol-value filesym)))
	    (if (stringp file)
		(set filesym (decode-coding-string file coding t)))))))
591

592
    (let ((dir default-directory))
593
      (with-current-buffer "*Messages*"
594
        (messages-buffer-mode)
595 596 597 598
        ;; Make it easy to do like "tail -f".
        (set (make-local-variable 'window-point-insertion-type) t)
        ;; Give *Messages* the same default-directory as *scratch*,
        ;; just to keep things predictable.
599
	(setq default-directory (or dir (expand-file-name "~/")))))
600 601 602
    ;; `user-full-name' is now known; reset its standard-value here.
    (put 'user-full-name 'standard-value
	 (list (default-value 'user-full-name)))
Dan Nicolaescu's avatar
Dan Nicolaescu committed
603 604 605 606 607
    ;; 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.
608 609
	   (or (and default-directory
		    (equal (file-attributes
Dan Nicolaescu's avatar
Dan Nicolaescu committed
610
		       (concat (file-name-as-directory pwd) "."))
611 612 613
		      (file-attributes
		       (concat (file-name-as-directory default-directory)
			       "."))))
Dan Nicolaescu's avatar
Dan Nicolaescu committed
614 615 616
	       (setq process-environment
		     (delete (concat "PWD=" pwd)
			     process-environment)))))
617 618 619 620
    ;; Now, that other directories were searched, and any charsets we
    ;; need for encoding them are already loaded, we are ready to
    ;; decode charset-map-path.
    (if (listp charset-map-path)
621 622 623 624 625 626 627
	(let ((coding (if (eq system-type 'windows-nt)
			  'utf-8
			locale-coding-system)))
	  (setq charset-map-path
		(mapcar (lambda (dir)
			  (decode-coding-string dir coding t))
			charset-map-path))))
628 629
    (if default-directory
	(setq default-directory (abbreviate-file-name default-directory))
630
      (display-warning 'initialization "Error setting default-directory"))
631
    (let ((old-face-font-rescale-alist face-font-rescale-alist))
632 633 634
      (unwind-protect
	  (command-line)
	;; Do this again, in case .emacs defined more abbreviations.
635 636
	(if default-directory
	    (setq default-directory (abbreviate-file-name default-directory)))
637 638
	;; Specify the file for recording all the auto save files of this session.
	;; This is used by recover-session.
639 640 641
	(or auto-save-list-file-name
	    (and auto-save-list-file-prefix
		 (setq auto-save-list-file-name
642 643
		       ;; Under MS-DOS our PID is almost always reused between
		       ;; Emacs invocations.  We need something more unique.
644 645 646 647 648 649
		       (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)
650
			      (concat
651 652 653 654 655 656 657 658 659 660
			       (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))))))))
661
	(unless inhibit-startup-hooks
662
	  (run-hooks 'emacs-startup-hook 'term-setup-hook))
663 664 665

	;; Don't do this if we failed to create the initial frame,
	;; for instance due to a dense colormap.
666 667
	(when (or frame-initial-frame
		  ;; If frame-initial-frame has no meaning, do this anyway.
668
		  (not (and initial-window-system
669
			    (not noninteractive)
670
			    (not (eq initial-window-system 'pc)))))
671 672 673 674 675 676 677 678 679 680 681 682 683

	  ;; FIXME: The user's init file may change
	  ;; face-font-rescale-alist.  However, the default face
	  ;; already has an assigned font object, which does not take
	  ;; face-font-rescale-alist into account.  For such
	  ;; situations, we ought to have a way to find all font
	  ;; objects and regenerate them; currently we do not.  As a
	  ;; workaround, we specifically reset te default face's :font
	  ;; attribute here.  See bug#1785.
	  (unless (eq face-font-rescale-alist
		      old-face-font-rescale-alist)
	    (set-face-attribute 'default nil :font (font-spec)))

684 685 686 687
	  ;; Modify the initial frame based on what .emacs puts into
	  ;; ...-frame-alist.
	  (if (fboundp 'frame-notice-user-settings)
	      (frame-notice-user-settings))
688 689 690 691
	  ;; 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.
692
	  (if (fboundp 'frame-set-background-mode)
693
	      (frame-set-background-mode (selected-frame))))
Miles Bader's avatar
Miles Bader committed
694

695 696 697
	;; Now we know the user's default font, so add it to the menu.
	(if (fboundp 'font-menu-add-default)
	    (font-menu-add-default))
698 699
	(unless inhibit-startup-hooks
	  (run-hooks 'window-setup-hook))))
700 701 702 703
    ;; Subprocesses of Emacs do not have direct access to the terminal, so
    ;; unless told otherwise they should only assume a dumb terminal.
    ;; We are careful to do it late (after term-setup-hook), although the
    ;; new multi-tty code does not use $TERM any more there anyway.
704 705 706 707 708 709 710 711 712 713 714 715 716 717
    (setenv "TERM" "dumb")
    ;; Remove DISPLAY from the process-environment as well.  This allows
    ;; `callproc.c' to give it a useful adaptive default which is either
    ;; the value of the `display' frame-parameter or the DISPLAY value
    ;; from initial-environment.
    (let ((display (frame-parameter nil 'display)))
      ;; Be careful which DISPLAY to remove from process-environment: follow
      ;; the logic of `callproc.c'.
      (if (stringp display) (setq display (concat "DISPLAY=" display))
        (dolist (varval initial-environment)
          (if (string-match "\\`DISPLAY=" varval)
              (setq display varval))))
      (when display
        (delete display process-environment)))))
718 719

;; Precompute the keyboard equivalents in the menu bar items.
720 721
;; Command-line options supported by tty's:
(defconst tty-long-option-alist
722 723 724
  '(("--name"		  . "-name")
    ("--title"		  . "-T")
    ("--reverse-video"	  . "-reverse")
725
    ("--foreground-color" . "-fg")
726 727
    ("--background-color" . "-bg")
    ("--color"		  . "-color")))
728

729
(defconst tool-bar-images-pixel-height 24
730
  "Height in pixels of images in the tool-bar.")
731

732
(cl-defgeneric handle-args-function (args)
Stefan Monnier's avatar
Stefan Monnier committed
733
  "Method for processing window-system dependent command-line arguments.
734
Window system startup files should add their own function to this
Stefan Monnier's avatar
Stefan Monnier committed
735
method, which should parse the command line arguments.  Those
736 737
pertaining to the window system should be processed and removed
from the returned command line.")
738
(cl-defmethod handle-args-function (args &context (window-system nil))
739
  (tty-handle-args args))
740

741
(cl-defgeneric window-system-initialization (&optional _display)
Stefan Monnier's avatar
Stefan Monnier committed
742 743
  "Method for window-system initialization.
Window-system startup files should add their own implementation
744 745 746
to this method.  The function should initialize the window system environment
to prepare for opening the first frame (e.g. open a connection to an X server)."
  nil)
747

748
(defun tty-handle-args (args)
Glenn Morris's avatar
Glenn Morris committed
749
  "Handle the X-like command-line arguments \"-fg\", \"-bg\", \"-name\", etc."
750
  (let (rest)
751 752
    (while (and args
		(not (equal (car args) "--")))
753 754 755
      (let* ((argi (pop args))
	     (orig-argi argi)
	     argval completion)
756 757
	;; Check for long options with attached arguments
	;; and separate out the attached option argument into argval.
758 759 760 761 762
	(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))
763 764
	  (if (eq completion t)
	      ;; Exact match for long option.
765
	      (setq argi (cdr (assoc argi tty-long-option-alist)))
766 767 768 769
	    (if (stringp completion)
		(let ((elt (assoc completion tty-long-option-alist)))
		  ;; Check for abbreviated long option.
		  (or elt
770
		      (error "Option `%s' is ambiguous" argi))
771
		  (setq argi (cdr elt)))
772
	      ;; Check for a short option.
773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810
	      (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)))))
811
    (nconc (nreverse rest) args)))
812

813 814 815
(declare-function x-get-resource "frame.c"
		  (attribute class &optional component subclass))
(declare-function tool-bar-mode "tool-bar" (&optional arg))
816
(declare-function tool-bar-setup "tool-bar")
817

818
(defvar server-name)
819
(defvar server-process)
820

821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875
(defun startup--setup-quote-display (&optional style)
  "If needed, display ASCII approximations to curved quotes.
Do this by modifying `standard-display-table'.  Optional STYLE
specifies the desired quoting style, as in `text-quoting-style'.
If STYLE is nil, display appropriately for the terminal."
  (let ((repls (let ((style-repls (assq style '((grave . "`'\"\"")
                                                (straight . "''\"\"")))))
                 (if style-repls (cdr style-repls) (make-vector 4 nil))))
        glyph-count)
    ;; REPLS is a sequence of the four replacements for "‘’“”", respectively.
    ;; If STYLE is nil, infer REPLS from terminal characteristics.
    (unless style
      ;; On a terminal that supports glyph codes,
      ;; GLYPH-COUNT[i] is the number of times that glyph code I
      ;; represents either an ASCII character or one of the 4
      ;; quote characters.  This assumes glyph codes are valid
      ;; Elisp characters, which is a safe assumption in practice.
      (when (integerp (internal-char-font nil (max-char)))
        (setq glyph-count (make-char-table nil 0))
        (dotimes (i 132)
          (let ((glyph (internal-char-font
                        nil (if (< i 128) i (aref "‘’“”" (- i 128))))))
            (when (<= 0 glyph)
              (aset glyph-count glyph (1+ (aref glyph-count glyph)))))))
      (dotimes (i 2)
        (let ((lq (aref "‘“" i)) (rq (aref "’”" i))
              (lr (aref "`\"" i)) (rr (aref "'\"" i))
              (i2 (* i 2)))
          (unless (if glyph-count
                      ;; On a terminal that supports glyph codes, use
                      ;; ASCII replacements unless both quotes are displayable.
                      ;; If not using ASCII replacements, highlight
                      ;; quotes unless they are both unique among the
                      ;; 128 + 4 characters of concern.
                      (let ((lglyph (internal-char-font nil lq))
                            (rglyph (internal-char-font nil rq)))
                        (when (and (<= 0 lglyph) (<= 0 rglyph))
                          (setq lr lq rr rq)
                          (and (= 1 (aref glyph-count lglyph))
                               (= 1 (aref glyph-count rglyph)))))
                    ;; On a terminal that does not support glyph codes, use
                    ;; ASCII replacements unless both quotes are displayable.
                    (and (char-displayable-p lq)
                         (char-displayable-p rq)))
            (aset repls i2 lr)
            (aset repls (1+ i2) rr)))))
    (dotimes (i 4)
      (let ((char (aref "‘’“”" i))
            (repl (aref repls i)))
        (if repl
            (aset (or standard-display-table
                      (setq standard-display-table (make-display-table)))
                  char (vector (make-glyph-code repl 'escape-glyph)))
          (when standard-display-table
            (aset standard-display-table char nil)))))))
876

Jim Blandy's avatar
Jim Blandy committed
877
(defun command-line ()
Glenn Morris's avatar
Glenn Morris committed
878 879
  "A subroutine of `normal-top-level'.
Amongst another things, it parses the command-line arguments."
880
  (setq before-init-time (current-time)
881
	after-init-time nil
882
        command-line-default-directory default-directory)
883

884 885
  ;; Force recomputation, in case it was computed during the dump.
  (setq abbreviated-home-dir nil)
886

Roland McGrath's avatar
Roland McGrath committed
887
  ;; See if we should import version-control from the environment variable.
Jim Blandy's avatar
Jim Blandy committed
888 889
  (let ((vc (getenv "VERSION_CONTROL")))
    (cond ((eq vc nil))			;don't do anything if not set
890
	  ((member vc '("t" "numbered"))
Jim Blandy's avatar
Jim Blandy committed
891
	   (setq version-control t))
892
	  ((member vc '("nil" "existing"))
Jim Blandy's avatar
Jim Blandy committed
893
	   (setq version-control nil))
894
	  ((member vc '("never" "simple"))
Jim Blandy's avatar
Jim Blandy committed
895 896
	   (setq version-control 'never))))

Jim Blandy's avatar
Jim Blandy committed
897 898 899 900 901
  ;;! 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
902

903 904
  ;; Convert preloaded file names in load-history to absolute.
  (let ((simple-file-name
905 906
	 ;; Look for simple.el or simple.elc and use their directory
	 ;; as the place where all Lisp files live.
907 908 909
	 (locate-file "simple" load-path (get-load-suffixes)))
	lisp-dir)
    ;; Don't abort if simple.el cannot be found, but print a warning.
910 911
    ;; Although in most usage we are going to cryptically abort a moment
    ;; later anyway, due to missing required bidi data files (eg bug#13430).
912
    (if (null simple-file-name)
913 914 915 916 917 918 919 920 921 922 923
	(let ((standard-output 'external-debugging-output)
	      (lispdir (expand-file-name "../lisp" data-directory)))
	  (princ "Warning: Could not find simple.el or simple.elc")
	  (terpri)
	  (when (getenv "EMACSLOADPATH")
	    (princ "The EMACSLOADPATH environment variable is set, \
please check its value")
	    (terpri))
	  (unless (file-readable-p lispdir)
	    (princ (format "Lisp directory %s not readable?" lispdir))
	    (terpri)))
924 925 926 927 928 929 930 931 932 933
      (setq lisp-dir (file-truename (file-name-directory simple-file-name)))
      (setq load-history
	    (mapcar (lambda (elt)
		      (if (and (stringp (car elt))
			       (not (file-name-absolute-p (car elt))))
			  (cons (concat lisp-dir
					(car elt))
				(cdr elt))
			elt))
		    load-history))))
934

935
  ;; Convert the arguments to Emacs internal representation.