Function: normal-top-level
normal-top-level is a byte-compiled function defined in startup.el.gz.
Signature
(normal-top-level)
Documentation
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(var)/top-level(fun).
Source Code
;; Defined in /usr/src/emacs/lisp/startup.el.gz
(defun normal-top-level ()
"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'."
;; Initialize the Android font driver late.
;; This is done here because it needs the `mac-roman' coding system
;; to be loaded.
(when (and (featurep 'android)
(fboundp 'android-enumerate-fonts)
(not android-fonts-enumerated))
(funcall 'android-enumerate-fonts)
(setq android-fonts-enumerated t))
(if command-line-processed
(message internal--top-level-message)
(setq command-line-processed t)
(setq startup--xdg-config-home-emacs
(let ((xdg-config-home (getenv-internal "XDG_CONFIG_HOME")))
(if xdg-config-home
(concat xdg-config-home "/emacs/")
startup--xdg-config-default)))
(setq user-emacs-directory
(startup--xdg-or-homedot startup--xdg-config-home-emacs nil))
(when (featurep 'native-compile)
(unless (native-comp-available-p)
;; Disable deferred async compilation and trampoline synthesis
;; in this session. This is necessary if libgccjit is not
;; available on MS-Windows, but Emacs was built with
;; native-compilation support.
(setq native-comp-jit-compilation nil
native-comp-enable-subr-trampolines nil))
;; Form `native-comp-eln-load-path'.
(let ((path-env (getenv "EMACSNATIVELOADPATH")))
(when path-env
(dolist (path (split-string path-env path-separator))
(unless (string= "" path)
(push path native-comp-eln-load-path)))))
(push (expand-file-name "eln-cache/" user-emacs-directory)
native-comp-eln-load-path))
;; 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)
(warning-inhibit-types '((files missing-lexbind-cookie))))
(load (expand-file-name "subdirs.el") t t t))
;; Do not scan standard directories that won't contain a leim-list.el.
;; https://lists.gnu.org/r/emacs-devel/2009-10/msg00502.html
;; (Except the preloaded one in lisp/leim.)
(or (string-prefix-p lispdir dir)
(let ((default-directory dir)
(warning-inhibit-types '((files missing-lexbind-cookie))))
(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))))
;; 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)")))
(if (and (featurep 'android)
(eq system-type 'android)
(fboundp 'android-locale-for-system-language)
initial-window-system)
;; If Android windowing is enabled, derive a proper locale
;; from the system's language preferences. On Android, LANG
;; and LC_* must be set to one of the two locales the C
;; library supports, but, by contrast with other systems, the
;; C library locale does not reflect the configured system
;; language.
;;
;; For this reason, the locale from which Emacs derives a
;; default language environment is computed from such
;; preferences, rather than environment variables that the C
;; library refers to.
(set-locale-environment
(funcall 'android-locale-for-system-language))
(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
(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
(if (eq system-type 'windows-nt)
;; We pass the decoded default-directory as
;; the 2nd arg to expand-file-name to make
;; sure it sees a multibyte string as the
;; default directory; this avoids the side
;; effect of returning a unibyte string from
;; expand-file-name because it still sees
;; the undecoded value of default-directory.
(let ((defdir (decode-coding-string default-directory
coding t)))
;; Convert backslashes to forward slashes.
(expand-file-name defdir defdir))
(decode-coding-string default-directory coding t))))))
;; 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)))))
(when (featurep 'native-compile)
(let ((npath (symbol-value 'native-comp-eln-load-path)))
(set 'native-comp-eln-load-path
(mapcar (lambda (dir)
;; Call expand-file-name to remove all the
;; pesky ".." from the directory names in
;; native-comp-eln-load-path.
(expand-file-name
(decode-coding-string dir coding t)))
npath)))
(setq startup--original-eln-load-path
(copy-sequence native-comp-eln-load-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)))))))
(let ((dir default-directory))
(with-current-buffer "*Messages*"
(messages-buffer-mode)
;; Give *Messages* the same default-directory as *scratch*,
;; just to keep things predictable.
(setq default-directory (or dir (expand-file-name "~/")))))
;; `user-full-name' is now known; reset its standard-value here.
(put 'user-full-name 'standard-value
(list (default-value 'user-full-name)))
;; If the PWD environment variable isn't accurate, delete it.
(let ((pwd (getenv "PWD")))
(and pwd
(or (and default-directory
(ignore-errors
(equal (file-attributes
(file-name-as-directory pwd))
(file-attributes
(file-name-as-directory default-directory)))))
(setq process-environment
(delete (concat "PWD=" pwd)
process-environment)))))
;; 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)
(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))))
(if default-directory
(setq default-directory (abbreviate-file-name default-directory))
(display-warning 'initialization "Error setting default-directory"))
(let ((old-face-font-rescale-alist face-font-rescale-alist))
(unwind-protect
(command-line)
(when (featurep 'native-compile)
(startup--update-eln-cache))
;; Do this again, in case .emacs defined more abbreviations.
(if default-directory
(setq default-directory (abbreviate-file-name default-directory)))
;; Specify the file for recording all the auto save files of this session.
;; This is used by recover-session.
(or auto-save-list-file-name
(and auto-save-list-file-prefix
(setq auto-save-list-file-name
;; Under MS-DOS our PID is almost always reused between
;; Emacs invocations. We need something more unique.
(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)
(concat
(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))))))))
(unless inhibit-startup-hooks
(run-hooks 'emacs-startup-hook 'term-setup-hook))
;; Don't do this if we failed to create the initial frame,
;; for instance due to a dense colormap.
(when (or frame-initial-frame
;; If frame-initial-frame has no meaning, do this anyway.
(not (and initial-window-system
(not noninteractive)
(not (eq initial-window-system 'pc)))))
;; 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 the default face's :font
;; attribute here, if it was rescaled. See bug#1785.
(when (and (display-multi-font-p)
(not (eq face-font-rescale-alist
old-face-font-rescale-alist))
(assoc (face-attribute 'default :font)
face-font-rescale-alist
#'startup--rescale-elt-match-p))
(set-face-attribute 'default nil :font (font-spec)))
;; Modify the initial frame based on what .emacs puts into
;; ...-frame-alist.
(if (fboundp 'frame-notice-user-settings)
(frame-notice-user-settings))
;; 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.
(if (fboundp 'frame-set-background-mode)
(frame-set-background-mode (selected-frame))))
;; Now we know the user's default font, so add it to the menu.
(if (fboundp 'font-menu-add-default)
(font-menu-add-default))
(unless inhibit-startup-hooks
(run-hooks 'window-setup-hook))))
;; 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.
(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))
(let ((env initial-environment))
(while (and env (or (not (string-match "\\`DISPLAY=" (car env)))
(progn
(setq display (car env))
nil)))
(setq env (cdr env)))))
(when display
(setq process-environment (delete display process-environment))))))