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))))))