refactor: how Doom starts up
Restructures Doom's primary core files and entry points to prepare for
backports (from the new CLI) coming soon.
- Removes $EMACSDIR/init.el.
- Doom configures Emacs to ignore ~/.emacs and ~/_emacs files.
- Doom's bootstrapper for interactive sessions was moved out of core.el
and doom-initialize into doom-start.el. This change is preparation for
Doom's new profile system (coming soon™️), where this bootstrapper
will be dynamically generated.
- core.el and early-init.el have been reorganized, comment headers moved
around, and comments updated to reflect these changes.
This commit is contained in:
parent
76431f699e
commit
1402db5129
5 changed files with 400 additions and 365 deletions
201
core/core-start.el
Normal file
201
core/core-start.el
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
;;; core/core-start.el --- bootstrapper for interactive sessions -*- lexical-binding: t; -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'core-modules)
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Reasonable defaults for interactive sessions
|
||||||
|
|
||||||
|
;; GUIs are inconsistent across systems, will rarely match our active Emacs
|
||||||
|
;; theme, and impose their shortcut key paradigms suddenly. Let's just avoid
|
||||||
|
;; them altogether and have Emacs handle the prompting.
|
||||||
|
(setq use-dialog-box nil)
|
||||||
|
(when (bound-and-true-p tooltip-mode)
|
||||||
|
(tooltip-mode -1))
|
||||||
|
(when IS-LINUX
|
||||||
|
(setq x-gtk-use-system-tooltips nil))
|
||||||
|
|
||||||
|
;; Favor vertical splits over horizontal ones, since monitors are trending
|
||||||
|
;; toward wide rather than tall.
|
||||||
|
(setq split-width-threshold 160
|
||||||
|
split-height-threshold nil)
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; MODE-local-vars-hook
|
||||||
|
|
||||||
|
;; File+dir local variables are initialized after the major mode and its hooks
|
||||||
|
;; have run. If you want hook functions to be aware of these customizations, add
|
||||||
|
;; them to MODE-local-vars-hook instead.
|
||||||
|
(defvar doom-inhibit-local-var-hooks nil)
|
||||||
|
|
||||||
|
(defun doom-run-local-var-hooks-h ()
|
||||||
|
"Run MODE-local-vars-hook after local variables are initialized."
|
||||||
|
(unless (or doom-inhibit-local-var-hooks delay-mode-hooks)
|
||||||
|
(setq-local doom-inhibit-local-var-hooks t)
|
||||||
|
(doom-run-hooks (intern (format "%s-local-vars-hook" major-mode)))))
|
||||||
|
|
||||||
|
;; If the user has disabled `enable-local-variables', then
|
||||||
|
;; `hack-local-variables-hook' is never triggered, so we trigger it at the end
|
||||||
|
;; of `after-change-major-mode-hook':
|
||||||
|
(defun doom-run-local-var-hooks-maybe-h ()
|
||||||
|
"Run `doom-run-local-var-hooks-h' if `enable-local-variables' is disabled."
|
||||||
|
(unless enable-local-variables
|
||||||
|
(doom-run-local-var-hooks-h)))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Incremental lazy-loading
|
||||||
|
|
||||||
|
(defvar doom-incremental-packages '(t)
|
||||||
|
"A list of packages to load incrementally after startup. Any large packages
|
||||||
|
here may cause noticeable pauses, so it's recommended you break them up into
|
||||||
|
sub-packages. For example, `org' is comprised of many packages, and can be
|
||||||
|
broken up into:
|
||||||
|
|
||||||
|
(doom-load-packages-incrementally
|
||||||
|
'(calendar find-func format-spec org-macs org-compat
|
||||||
|
org-faces org-entities org-list org-pcomplete org-src
|
||||||
|
org-footnote org-macro ob org org-clock org-agenda
|
||||||
|
org-capture))
|
||||||
|
|
||||||
|
This is already done by the lang/org module, however.
|
||||||
|
|
||||||
|
If you want to disable incremental loading altogether, either remove
|
||||||
|
`doom-load-packages-incrementally-h' from `emacs-startup-hook' or set
|
||||||
|
`doom-incremental-first-idle-timer' to nil. Incremental loading does not occur
|
||||||
|
in daemon sessions (they are loaded immediately at startup).")
|
||||||
|
|
||||||
|
(defvar doom-incremental-first-idle-timer 2.0
|
||||||
|
"How long (in idle seconds) until incremental loading starts.
|
||||||
|
|
||||||
|
Set this to nil to disable incremental loading.")
|
||||||
|
|
||||||
|
(defvar doom-incremental-idle-timer 0.75
|
||||||
|
"How long (in idle seconds) in between incrementally loading packages.")
|
||||||
|
|
||||||
|
(defvar doom-incremental-load-immediately (daemonp)
|
||||||
|
"If non-nil, load all incrementally deferred packages immediately at startup.")
|
||||||
|
|
||||||
|
(defun doom-load-packages-incrementally (packages &optional now)
|
||||||
|
"Registers PACKAGES to be loaded incrementally.
|
||||||
|
|
||||||
|
If NOW is non-nil, load PACKAGES incrementally, in `doom-incremental-idle-timer'
|
||||||
|
intervals."
|
||||||
|
(if (not now)
|
||||||
|
(appendq! doom-incremental-packages packages)
|
||||||
|
(while packages
|
||||||
|
(let* ((gc-cons-threshold most-positive-fixnum)
|
||||||
|
(req (pop packages)))
|
||||||
|
(unless (featurep req)
|
||||||
|
(doom-log "Incrementally loading %s" req)
|
||||||
|
(condition-case-unless-debug e
|
||||||
|
(or (while-no-input
|
||||||
|
;; If `default-directory' is a directory that doesn't exist
|
||||||
|
;; or is unreadable, Emacs throws up file-missing errors, so
|
||||||
|
;; we set it to a directory we know exists and is readable.
|
||||||
|
(let ((default-directory doom-emacs-dir)
|
||||||
|
(inhibit-message t)
|
||||||
|
file-name-handler-alist)
|
||||||
|
(require req nil t))
|
||||||
|
t)
|
||||||
|
(push req packages))
|
||||||
|
(error
|
||||||
|
(message "Failed to load %S package incrementally, because: %s"
|
||||||
|
req e)))
|
||||||
|
(if (not packages)
|
||||||
|
(doom-log "Finished incremental loading")
|
||||||
|
(run-with-idle-timer doom-incremental-idle-timer
|
||||||
|
nil #'doom-load-packages-incrementally
|
||||||
|
packages t)
|
||||||
|
(setq packages nil)))))))
|
||||||
|
|
||||||
|
(defun doom-load-packages-incrementally-h ()
|
||||||
|
"Begin incrementally loading packages in `doom-incremental-packages'.
|
||||||
|
|
||||||
|
If this is a daemon session, load them all immediately instead."
|
||||||
|
(if doom-incremental-load-immediately
|
||||||
|
(mapc #'require (cdr doom-incremental-packages))
|
||||||
|
(when (numberp doom-incremental-first-idle-timer)
|
||||||
|
(run-with-idle-timer doom-incremental-first-idle-timer
|
||||||
|
nil #'doom-load-packages-incrementally
|
||||||
|
(cdr doom-incremental-packages) t))))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Let 'er rip
|
||||||
|
|
||||||
|
(defvar doom-init-time nil
|
||||||
|
"The time it took, in seconds, for Doom Emacs to initialize.")
|
||||||
|
|
||||||
|
(defun doom-display-benchmark-h (&optional return-p)
|
||||||
|
"Display a benchmark including number of packages and modules loaded.
|
||||||
|
|
||||||
|
If RETURN-P, return the message as a string instead of displaying it."
|
||||||
|
(funcall (if return-p #'format #'message)
|
||||||
|
"Doom loaded %d packages across %d modules in %.03fs"
|
||||||
|
(- (length load-path) (length (get 'load-path 'initial-value)))
|
||||||
|
(hash-table-count doom-modules)
|
||||||
|
(or doom-init-time
|
||||||
|
(setq doom-init-time
|
||||||
|
(float-time (time-subtract (current-time) before-init-time))))))
|
||||||
|
|
||||||
|
;; Add support for additional file extensions.
|
||||||
|
(dolist (entry '(("/LICENSE\\'" . text-mode)
|
||||||
|
("\\.log\\'" . text-mode)
|
||||||
|
("rc\\'" . conf-mode)
|
||||||
|
("\\.\\(?:hex\\|nes\\)\\'" . hexl-mode)))
|
||||||
|
(push entry auto-mode-alist))
|
||||||
|
|
||||||
|
;; Doom caches a lot of information in `doom-autoloads-file'. Module and package
|
||||||
|
;; autoloads, autodefs like `set-company-backend!', and variables like
|
||||||
|
;; `doom-modules', `doom-disabled-packages', `load-path', `auto-mode-alist', and
|
||||||
|
;; `Info-directory-list'. etc. Compiling them into one place is a big reduction
|
||||||
|
;; in startup time.
|
||||||
|
(condition-case-unless-debug e
|
||||||
|
;; Avoid `file-name-sans-extension' for premature optimization reasons.
|
||||||
|
;; `string-remove-suffix' is cheaper because it performs no file sanity
|
||||||
|
;; checks; just plain ol' string manipulation.
|
||||||
|
(load (string-remove-suffix ".el" doom-autoloads-file) nil 'nomessage)
|
||||||
|
(file-missing
|
||||||
|
;; If the autoloads file fails to load then the user forgot to sync, or
|
||||||
|
;; aborted a doom command midway!
|
||||||
|
(if (locate-file doom-autoloads-file load-path)
|
||||||
|
;; Something inside the autoloads file is triggering this error;
|
||||||
|
;; forward it to the caller!
|
||||||
|
(signal 'doom-autoload-error e)
|
||||||
|
(signal 'doom-error
|
||||||
|
(list "Doom is in an incomplete state"
|
||||||
|
"run 'doom sync' on the command line to repair it")))))
|
||||||
|
|
||||||
|
(when (and (or (display-graphic-p)
|
||||||
|
(daemonp))
|
||||||
|
doom-env-file)
|
||||||
|
(setq-default process-environment (get 'process-environment 'initial-value))
|
||||||
|
(doom-load-envvars-file doom-env-file 'noerror))
|
||||||
|
|
||||||
|
;; Bootstrap the interactive session
|
||||||
|
(add-hook 'after-change-major-mode-hook #'doom-run-local-var-hooks-h 100)
|
||||||
|
(add-hook 'hack-local-variables-hook #'doom-run-local-var-hooks-h)
|
||||||
|
(add-hook 'emacs-startup-hook #'doom-load-packages-incrementally-h)
|
||||||
|
(add-hook 'window-setup-hook #'doom-display-benchmark-h 105)
|
||||||
|
(doom-run-hook-on 'doom-first-buffer-hook '(find-file-hook doom-switch-buffer-hook))
|
||||||
|
(doom-run-hook-on 'doom-first-file-hook '(find-file-hook dired-initial-position-hook))
|
||||||
|
(doom-run-hook-on 'doom-first-input-hook '(pre-command-hook))
|
||||||
|
|
||||||
|
(add-hook 'doom-first-buffer-hook #'gcmh-mode)
|
||||||
|
|
||||||
|
;; There's a chance the user will later use package.el or straight in this
|
||||||
|
;; interactive session. If they do, make sure they're properly initialized
|
||||||
|
;; when they do.
|
||||||
|
(autoload 'doom-initialize-packages "core-packages")
|
||||||
|
(eval-after-load 'package '(require 'core-packages))
|
||||||
|
(eval-after-load 'straight '(doom-initialize-packages))
|
||||||
|
|
||||||
|
;; Load all things.
|
||||||
|
(doom-initialize-modules)
|
||||||
|
|
||||||
|
(provide 'core-start)
|
||||||
|
;;; core-start.el ends here
|
|
@ -522,7 +522,8 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
||||||
;; User themes should live in $DOOMDIR/themes, not ~/.emacs.d
|
;; User themes should live in $DOOMDIR/themes, not ~/.emacs.d
|
||||||
(setq custom-theme-directory (concat doom-private-dir "themes/"))
|
(setq custom-theme-directory (concat doom-private-dir "themes/"))
|
||||||
|
|
||||||
;; Always prioritize the user's themes above the built-in/packaged ones.
|
;; Third party themes add themselves to `custom-theme-load-path', but the themes
|
||||||
|
;; living in $DOOMDIR/themes should always have priority.
|
||||||
(setq custom-theme-load-path
|
(setq custom-theme-load-path
|
||||||
(cons 'custom-theme-directory
|
(cons 'custom-theme-directory
|
||||||
(delq 'custom-theme-directory custom-theme-load-path)))
|
(delq 'custom-theme-directory custom-theme-load-path)))
|
||||||
|
@ -593,6 +594,7 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original
|
||||||
(when (and (not no-enable) (custom-theme-enabled-p theme))
|
(when (and (not no-enable) (custom-theme-enabled-p theme))
|
||||||
(setq doom-theme theme)
|
(setq doom-theme theme)
|
||||||
(put 'doom-theme 'previous-themes (or last-themes 'none))
|
(put 'doom-theme 'previous-themes (or last-themes 'none))
|
||||||
|
;; DEPRECATED Hook into `enable-theme-functions' when we target 29
|
||||||
(doom-run-hooks 'doom-load-theme-hook))))))
|
(doom-run-hooks 'doom-load-theme-hook))))))
|
||||||
|
|
||||||
|
|
||||||
|
|
447
core/core.el
447
core/core.el
|
@ -1,24 +1,109 @@
|
||||||
;;; core.el --- the heart of the beast -*- lexical-binding: t; -*-
|
;;; core.el --- the heart of the beast -*- lexical-binding: t; -*-
|
||||||
|
;;
|
||||||
|
;; Author: Henrik Lissner <contact@henrik.io>
|
||||||
|
;; URL: https://github.com/doomemacs/doomemacs
|
||||||
|
;;
|
||||||
|
;; ================= =============== =============== ======== ========
|
||||||
|
;; \\ . . . . . . .\\ //. . . . . . .\\ //. . . . . . .\\ \\. . .\\// . . //
|
||||||
|
;; ||. . ._____. . .|| ||. . ._____. . .|| ||. . ._____. . .|| || . . .\/ . . .||
|
||||||
|
;; || . .|| ||. . || || . .|| ||. . || || . .|| ||. . || ||. . . . . . . ||
|
||||||
|
;; ||. . || || . .|| ||. . || || . .|| ||. . || || . .|| || . | . . . . .||
|
||||||
|
;; || . .|| ||. _-|| ||-_ .|| ||. . || || . .|| ||. _-|| ||-_.|\ . . . . ||
|
||||||
|
;; ||. . || ||-' || || `-|| || . .|| ||. . || ||-' || || `|\_ . .|. .||
|
||||||
|
;; || . _|| || || || || ||_ . || || . _|| || || || |\ `-_/| . ||
|
||||||
|
;; ||_-' || .|/ || || \|. || `-_|| ||_-' || .|/ || || | \ / |-_.||
|
||||||
|
;; || ||_-' || || `-_|| || || ||_-' || || | \ / | `||
|
||||||
|
;; || `' || || `' || || `' || || | \ / | ||
|
||||||
|
;; || .===' `===. .==='.`===. .===' /==. | \/ | ||
|
||||||
|
;; || .==' \_|-_ `===. .===' _|_ `===. .===' _-|/ `== \/ | ||
|
||||||
|
;; || .==' _-' `-_ `=' _-' `-_ `=' _-' `-_ /| \/ | ||
|
||||||
|
;; || .==' _-' '-__\._-' '-_./__-' `' |. /| | ||
|
||||||
|
;; ||.==' _-' `' | /==.||
|
||||||
|
;; ==' _-' \/ `==
|
||||||
|
;; \ _-' `-_ /
|
||||||
|
;; `'' ``'
|
||||||
|
;;
|
||||||
|
;; These demons are not part of GNU Emacs.
|
||||||
|
;;
|
||||||
|
;;; Commentary:
|
||||||
|
;;
|
||||||
|
;; This is Doom's heart, where I define all its major constants and variables,
|
||||||
|
;; set its saner global defaults, then prepare Emacs to bootstrap Doom.
|
||||||
|
;;
|
||||||
|
;; The overall load order of Doom is as follows:
|
||||||
|
;;
|
||||||
|
;; $EMACSDIR/early-init.el
|
||||||
|
;; $EMACSDIR/core/core.el
|
||||||
|
;; $DOOMDIR/init.el
|
||||||
|
;; {$DOOMDIR,~/.emacs.d}/modules/*/*/init.el
|
||||||
|
;; `doom-before-init-modules-hook'
|
||||||
|
;; {$DOOMDIR,~/.emacs.d}/modules/*/*/config.el
|
||||||
|
;; `doom-init-modules-hook'
|
||||||
|
;; $DOOMDIR/config.el
|
||||||
|
;; `doom-after-init-modules-hook'
|
||||||
|
;; `after-init-hook'
|
||||||
|
;; `emacs-startup-hook'
|
||||||
|
;; `doom-init-ui-hook'
|
||||||
|
;; `window-setup-hook'
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
(when (< emacs-major-version 27)
|
(when (< emacs-major-version 27)
|
||||||
(error "Detected Emacs %s. Minimum supported version is 27.1."
|
(error "Detected Emacs %s. Minimum supported version is 27.1."
|
||||||
emacs-version))
|
emacs-version))
|
||||||
|
|
||||||
;; Ensure Doom's core libraries are visible for loading
|
|
||||||
(add-to-list 'load-path (file-name-directory load-file-name))
|
|
||||||
|
|
||||||
;; Remember these variables' initial values, so we can safely reset them at a
|
;; Remember these variables' initial values, so we can safely reset them at a
|
||||||
;; later time, or consult them without fear of contamination.
|
;; later time, or consult them without fear of contamination.
|
||||||
(dolist (var '(exec-path load-path process-environment))
|
(dolist (var '(exec-path load-path process-environment))
|
||||||
(unless (get var 'initial-value)
|
(unless (get var 'initial-value)
|
||||||
(put var 'initial-value (default-value var))))
|
(put var 'initial-value (default-value var))))
|
||||||
|
|
||||||
|
;; Prevent unwanted runtime compilation for gccemacs (native-comp) users;
|
||||||
|
;; packages are compiled ahead-of-time when they are installed and site files
|
||||||
|
;; are compiled when gccemacs is installed.
|
||||||
|
(setq native-comp-deferred-compilation nil)
|
||||||
|
|
||||||
|
;; Since Emacs 27, package initialization occurs before `user-init-file' is
|
||||||
|
;; loaded, but after `early-init-file'. Doom handles package initialization, so
|
||||||
|
;; we must prevent Emacs from doing it again.
|
||||||
|
(setq package-enable-at-startup nil)
|
||||||
|
|
||||||
;; Just the... bear necessities~
|
;; Just the... bear necessities~
|
||||||
(require 'core-lib)
|
(require 'cl-lib)
|
||||||
|
(require 'subr-x)
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;;; Initialize internal state
|
;;; Global constants
|
||||||
|
|
||||||
|
;; Emacs features
|
||||||
|
(defconst EMACS28+ (> emacs-major-version 27))
|
||||||
|
(defconst EMACS29+ (> emacs-major-version 28))
|
||||||
|
(defconst MODULES (bound-and-true-p module-file-suffix))
|
||||||
|
(defconst NATIVECOMP (if (fboundp 'native-comp-available-p) (native-comp-available-p)))
|
||||||
|
|
||||||
|
;; Operating system
|
||||||
|
(defconst IS-MAC (eq system-type 'darwin))
|
||||||
|
(defconst IS-LINUX (eq system-type 'gnu/linux))
|
||||||
|
(defconst IS-WINDOWS (memq system-type '(cygwin windows-nt ms-dos)))
|
||||||
|
(defconst IS-BSD (or IS-MAC (eq system-type 'berkeley-unix)))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Cross-platform fixes
|
||||||
|
|
||||||
|
(when IS-WINDOWS
|
||||||
|
(when-let (realhome
|
||||||
|
;; Fix HOME on Windows, where it's not normally defined (though
|
||||||
|
;; many unix tools expect it).
|
||||||
|
(and (null (getenv-internal "HOME"))
|
||||||
|
(getenv "USERPROFILE")))
|
||||||
|
(setenv "HOME" realhome)
|
||||||
|
(setq abbreviated-home-dir nil)))
|
||||||
|
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Core variables
|
||||||
|
|
||||||
(defgroup doom nil
|
(defgroup doom nil
|
||||||
"An Emacs framework for the stubborn martian hacker."
|
"An Emacs framework for the stubborn martian hacker."
|
||||||
|
@ -39,27 +124,9 @@ envvar will enable this at startup.")
|
||||||
(defvar doom-init-p nil
|
(defvar doom-init-p nil
|
||||||
"Non-nil if Doom has been initialized.")
|
"Non-nil if Doom has been initialized.")
|
||||||
|
|
||||||
(defvar doom-init-time nil
|
|
||||||
"The time it took, in seconds, for Doom Emacs to initialize.")
|
|
||||||
|
|
||||||
(defconst doom-interactive-p (not noninteractive)
|
(defconst doom-interactive-p (not noninteractive)
|
||||||
"If non-nil, Emacs is in interactive mode.")
|
"If non-nil, Emacs is in interactive mode.")
|
||||||
|
|
||||||
(defconst NATIVECOMP (if (fboundp 'native-comp-available-p) (native-comp-available-p)))
|
|
||||||
(defconst EMACS28+ (> emacs-major-version 27))
|
|
||||||
(defconst EMACS29+ (> emacs-major-version 28))
|
|
||||||
(defconst IS-MAC (eq system-type 'darwin))
|
|
||||||
(defconst IS-LINUX (eq system-type 'gnu/linux))
|
|
||||||
(defconst IS-WINDOWS (memq system-type '(cygwin windows-nt ms-dos)))
|
|
||||||
(defconst IS-BSD (or IS-MAC (eq system-type 'berkeley-unix)))
|
|
||||||
|
|
||||||
(when-let (realhome
|
|
||||||
(and IS-WINDOWS
|
|
||||||
(null (getenv-internal "HOME"))
|
|
||||||
(getenv "USERPROFILE")))
|
|
||||||
(setenv "HOME" realhome)
|
|
||||||
(setq abbreviated-home-dir nil))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;;; Directory variables
|
;;; Directory variables
|
||||||
|
@ -84,12 +151,14 @@ Use this as a storage location for this system's installation of Doom Emacs.
|
||||||
These files should not be shared across systems. By default, it is used by
|
These files should not be shared across systems. By default, it is used by
|
||||||
`doom-etc-dir' and `doom-cache-dir'. Must end with a slash.")
|
`doom-etc-dir' and `doom-cache-dir'. Must end with a slash.")
|
||||||
|
|
||||||
|
;; DEPRECATED
|
||||||
(defconst doom-etc-dir (concat doom-local-dir "etc/")
|
(defconst doom-etc-dir (concat doom-local-dir "etc/")
|
||||||
"Directory for non-volatile local storage.
|
"Directory for non-volatile local storage.
|
||||||
|
|
||||||
Use this for files that don't change much, like server binaries, external
|
Use this for files that don't change much, like server binaries, external
|
||||||
dependencies or long-term shared data. Must end with a slash.")
|
dependencies or long-term shared data. Must end with a slash.")
|
||||||
|
|
||||||
|
;; DEPRECATED
|
||||||
(defconst doom-cache-dir (concat doom-local-dir "cache/")
|
(defconst doom-cache-dir (concat doom-local-dir "cache/")
|
||||||
"Directory for volatile local storage.
|
"Directory for volatile local storage.
|
||||||
|
|
||||||
|
@ -112,6 +181,7 @@ Use this for files that change often, like cache files. Must end with a slash.")
|
||||||
Defaults to ~/.config/doom, ~/.doom.d or the value of the DOOMDIR envvar;
|
Defaults to ~/.config/doom, ~/.doom.d or the value of the DOOMDIR envvar;
|
||||||
whichever is found first. Must end in a slash.")
|
whichever is found first. Must end in a slash.")
|
||||||
|
|
||||||
|
;; DEPRECATED
|
||||||
(defconst doom-autoloads-file
|
(defconst doom-autoloads-file
|
||||||
(concat doom-local-dir "autoloads." emacs-version ".el")
|
(concat doom-local-dir "autoloads." emacs-version ".el")
|
||||||
"Where `doom-reload-core-autoloads' stores its core autoloads.
|
"Where `doom-reload-core-autoloads' stores its core autoloads.
|
||||||
|
@ -165,8 +235,8 @@ users).")
|
||||||
;;; Native Compilation support (http://akrl.sdf.org/gccemacs.html)
|
;;; Native Compilation support (http://akrl.sdf.org/gccemacs.html)
|
||||||
|
|
||||||
(when NATIVECOMP
|
(when NATIVECOMP
|
||||||
;; Don't store eln files in ~/.emacs.d/eln-cache (they are likely to be purged
|
;; Don't store eln files in ~/.emacs.d/eln-cache (where they can easily be
|
||||||
;; when upgrading Doom).
|
;; deleted by 'doom upgrade').
|
||||||
(add-to-list 'native-comp-eln-load-path (concat doom-cache-dir "eln/"))
|
(add-to-list 'native-comp-eln-load-path (concat doom-cache-dir "eln/"))
|
||||||
|
|
||||||
(with-eval-after-load 'comp
|
(with-eval-after-load 'comp
|
||||||
|
@ -213,64 +283,20 @@ Otherwise, `en/disable-command' (in novice.el.gz) is hardcoded to write them to
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;;; MODE-local-vars-hook
|
;;; Bootstrap
|
||||||
|
|
||||||
;; File+dir local variables are initialized after the major mode and its hooks
|
;; Ensure Doom's core libraries are visible for loading
|
||||||
;; have run. If you want hook functions to be aware of these customizations, add
|
(add-to-list 'load-path doom-core-dir)
|
||||||
;; them to MODE-local-vars-hook instead.
|
|
||||||
(defvar doom-inhibit-local-var-hooks nil)
|
|
||||||
|
|
||||||
(defun doom-run-local-var-hooks-h ()
|
;; ...then load *the* one
|
||||||
"Run MODE-local-vars-hook after local variables are initialized."
|
(require 'core-lib)
|
||||||
(unless doom-inhibit-local-var-hooks
|
|
||||||
(setq-local doom-inhibit-local-var-hooks t)
|
|
||||||
(doom-run-hooks (intern (format "%s-local-vars-hook" major-mode)))))
|
|
||||||
|
|
||||||
;; If the user has disabled `enable-local-variables', then
|
|
||||||
;; `hack-local-variables-hook' is never triggered, so we trigger it at the end
|
|
||||||
;; of `after-change-major-mode-hook':
|
|
||||||
(defun doom-run-local-var-hooks-maybe-h ()
|
|
||||||
"Run `doom-run-local-var-hooks-h' if `enable-local-variables' is disabled."
|
|
||||||
(unless enable-local-variables
|
|
||||||
(doom-run-local-var-hooks-h)))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;;; Reasonable defaults
|
;;; Runtime/startup optimizations
|
||||||
|
|
||||||
;; Emacs is essentially one huge security vulnerability, what with all the
|
;; A second, case-insensitive pass over `auto-mode-alist' is time wasted and
|
||||||
;; dependencies it pulls in from all corners of the globe. Let's try to be at
|
;; indicates misconfiguration.
|
||||||
;; least a little more discerning.
|
|
||||||
(setq gnutls-verify-error noninteractive
|
|
||||||
gnutls-algorithm-priority
|
|
||||||
(when (boundp 'libgnutls-version)
|
|
||||||
(concat "SECURE128:+SECURE192:-VERS-ALL"
|
|
||||||
(if (and (not IS-WINDOWS)
|
|
||||||
(>= libgnutls-version 30605))
|
|
||||||
":+VERS-TLS1.3")
|
|
||||||
":+VERS-TLS1.2"))
|
|
||||||
;; `gnutls-min-prime-bits' is set based on recommendations from
|
|
||||||
;; https://www.keylength.com/en/4/
|
|
||||||
gnutls-min-prime-bits 3072
|
|
||||||
tls-checktrust gnutls-verify-error
|
|
||||||
;; Emacs is built with `gnutls' by default, so `tls-program' would not be
|
|
||||||
;; used in that case. Otherwise, people have reasons to not go with
|
|
||||||
;; `gnutls', we use `openssl' instead. For more details, see
|
|
||||||
;; https://redd.it/8sykl1
|
|
||||||
tls-program '("openssl s_client -connect %h:%p -CAfile %t -nbio -no_ssl3 -no_tls1 -no_tls1_1 -ign_eof"
|
|
||||||
"gnutls-cli -p %p --dh-bits=3072 --ocsp --x509cafile=%t \
|
|
||||||
--strict-tofu --priority='SECURE192:+SECURE128:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3' %h"
|
|
||||||
;; compatibility fallbacks
|
|
||||||
"gnutls-cli -p %p %h"))
|
|
||||||
|
|
||||||
;; Emacs stores `authinfo' in $HOME and in plain-text. Let's not do that, mkay?
|
|
||||||
;; This file stores usernames, passwords, and other such treasures for the
|
|
||||||
;; aspiring malicious third party.
|
|
||||||
(setq auth-sources (list (concat doom-etc-dir "authinfo.gpg")
|
|
||||||
"~/.authinfo.gpg"))
|
|
||||||
|
|
||||||
;; A second, case-insensitive pass over `auto-mode-alist' is time wasted, and
|
|
||||||
;; indicates misconfiguration (don't rely on case insensitivity for file names).
|
|
||||||
(setq auto-mode-case-fold nil)
|
(setq auto-mode-case-fold nil)
|
||||||
|
|
||||||
;; Disable bidirectional text scanning for a modest performance boost. I've set
|
;; Disable bidirectional text scanning for a modest performance boost. I've set
|
||||||
|
@ -316,8 +342,8 @@ Otherwise, `en/disable-command' (in novice.el.gz) is hardcoded to write them to
|
||||||
|
|
||||||
;; Font compacting can be terribly expensive, especially for rendering icon
|
;; Font compacting can be terribly expensive, especially for rendering icon
|
||||||
;; fonts on Windows. Whether disabling it has a notable affect on Linux and Mac
|
;; fonts on Windows. Whether disabling it has a notable affect on Linux and Mac
|
||||||
;; hasn't been determined, but do it there anyway, just in case. This increases
|
;; hasn't been determined, but do it anyway, just in case. This increases memory
|
||||||
;; memory usage, however!
|
;; usage, however!
|
||||||
(setq inhibit-compacting-font-caches t)
|
(setq inhibit-compacting-font-caches t)
|
||||||
|
|
||||||
;; PGTK builds only: this timeout adds latency to frame operations, like
|
;; PGTK builds only: this timeout adds latency to frame operations, like
|
||||||
|
@ -340,11 +366,7 @@ Otherwise, `en/disable-command' (in novice.el.gz) is hardcoded to write them to
|
||||||
(when (boundp 'w32-get-true-file-attributes)
|
(when (boundp 'w32-get-true-file-attributes)
|
||||||
(setq w32-get-true-file-attributes nil ; decrease file IO workload
|
(setq w32-get-true-file-attributes nil ; decrease file IO workload
|
||||||
w32-pipe-read-delay 0 ; faster IPC
|
w32-pipe-read-delay 0 ; faster IPC
|
||||||
w32-pipe-buffer-size (* 64 1024)) ; read more at a time (was 4K)
|
w32-pipe-buffer-size (* 64 1024))) ; read more at a time (was 4K)
|
||||||
|
|
||||||
;; The clipboard on Windows could be in another encoding (likely utf-16), so
|
|
||||||
;; let Emacs/the OS decide what to use there.
|
|
||||||
(setq selection-coding-system 'utf-8))
|
|
||||||
|
|
||||||
;; Remove command line options that aren't relevant to our current OS; means
|
;; Remove command line options that aren't relevant to our current OS; means
|
||||||
;; slightly less to process at startup.
|
;; slightly less to process at startup.
|
||||||
|
@ -362,18 +384,42 @@ Otherwise, `en/disable-command' (in novice.el.gz) is hardcoded to write them to
|
||||||
(advice-remove #'tty-run-terminal-initialization #'ignore)
|
(advice-remove #'tty-run-terminal-initialization #'ignore)
|
||||||
(tty-run-terminal-initialization (selected-frame) nil t))))
|
(tty-run-terminal-initialization (selected-frame) nil t))))
|
||||||
|
|
||||||
|
;; Shave seconds off startup time by starting the scratch buffer in
|
||||||
|
;; `fundamental-mode', rather than, say, `org-mode' or `text-mode', which pull
|
||||||
|
;; in a ton of packages. `doom/open-scratch-buffer' provides a better scratch
|
||||||
|
;; buffer anyway.
|
||||||
|
(setq initial-major-mode 'fundamental-mode
|
||||||
|
initial-scratch-message nil)
|
||||||
|
|
||||||
|
|
||||||
;;
|
;;
|
||||||
;;; Reasonable defaults for interactive sessions
|
;;; Reasonable, global defaults
|
||||||
|
|
||||||
;; Disable warnings from legacy advice system. They aren't useful, and what can
|
;; Contrary to what many Emacs users have in their configs, you don't need more
|
||||||
;; we do about them, besides changing packages upstream?
|
;; than this to make UTF-8 the default coding system:
|
||||||
|
(set-language-environment "UTF-8")
|
||||||
|
;; ...but `set-language-environment' also sets `default-input-method', which is
|
||||||
|
;; a step too opinionated.
|
||||||
|
(setq default-input-method nil)
|
||||||
|
;; ...And the clipboard on Windows could be in a wider encoding (UTF-16), so
|
||||||
|
;; leave Emacs to its own devices.
|
||||||
|
(unless IS-WINDOWS
|
||||||
|
(setq selection-coding-system 'utf-8))
|
||||||
|
|
||||||
|
;; Disable warnings from the legacy advice API. They aren't actionable or
|
||||||
|
;; useful, and often come from third party packages.
|
||||||
(setq ad-redefinition-action 'accept)
|
(setq ad-redefinition-action 'accept)
|
||||||
|
|
||||||
;; Reduce debug output, well, unless we've asked for it.
|
;; Reduce debug output unless we've asked for it.
|
||||||
(setq debug-on-error init-file-debug
|
(setq debug-on-error init-file-debug
|
||||||
jka-compr-verbose init-file-debug)
|
jka-compr-verbose init-file-debug)
|
||||||
|
|
||||||
|
;; Emacs stores `authinfo' in $HOME and in plain-text. Let's not do that, mkay?
|
||||||
|
;; This file stores usernames, passwords, and other treasures for the aspiring
|
||||||
|
;; malicious third party. However, for this to work you need a GPG setup.
|
||||||
|
(setq auth-sources (list (concat doom-etc-dir "authinfo.gpg")
|
||||||
|
"~/.authinfo.gpg"))
|
||||||
|
|
||||||
;; Get rid of "For information about GNU Emacs..." message at startup, unless
|
;; Get rid of "For information about GNU Emacs..." message at startup, unless
|
||||||
;; we're in a daemon session where it'll say "Starting Emacs daemon." instead,
|
;; we're in a daemon session where it'll say "Starting Emacs daemon." instead,
|
||||||
;; which isn't so bad.
|
;; which isn't so bad.
|
||||||
|
@ -384,207 +430,32 @@ Otherwise, `en/disable-command' (in novice.el.gz) is hardcoded to write them to
|
||||||
;; is more than enough.
|
;; is more than enough.
|
||||||
(setq inhibit-startup-screen t
|
(setq inhibit-startup-screen t
|
||||||
inhibit-startup-echo-area-message user-login-name
|
inhibit-startup-echo-area-message user-login-name
|
||||||
inhibit-default-init t
|
inhibit-default-init t)
|
||||||
;; Shave seconds off startup time by starting the scratch buffer in
|
|
||||||
;; `fundamental-mode', rather than, say, `org-mode' or `text-mode', which
|
|
||||||
;; pull in a ton of packages. `doom/open-scratch-buffer' provides a better
|
|
||||||
;; scratch buffer anyway.
|
|
||||||
initial-major-mode 'fundamental-mode
|
|
||||||
initial-scratch-message nil)
|
|
||||||
|
|
||||||
|
;; Emacs is essentially one huge security vulnerability, what with all the
|
||||||
;;
|
;; dependencies it pulls in from all corners of the globe. Let's try to be a
|
||||||
;;; Incremental lazy-loading
|
;; *little* more discerning.
|
||||||
|
(setq gnutls-verify-error noninteractive
|
||||||
(defvar doom-incremental-packages '(t)
|
gnutls-algorithm-priority
|
||||||
"A list of packages to load incrementally after startup. Any large packages
|
(when (boundp 'libgnutls-version)
|
||||||
here may cause noticeable pauses, so it's recommended you break them up into
|
(concat "SECURE128:+SECURE192:-VERS-ALL"
|
||||||
sub-packages. For example, `org' is comprised of many packages, and can be
|
(if (and (not IS-WINDOWS)
|
||||||
broken up into:
|
(>= libgnutls-version 30605))
|
||||||
|
":+VERS-TLS1.3")
|
||||||
(doom-load-packages-incrementally
|
":+VERS-TLS1.2"))
|
||||||
'(calendar find-func format-spec org-macs org-compat
|
;; `gnutls-min-prime-bits' is set based on recommendations from
|
||||||
org-faces org-entities org-list org-pcomplete org-src
|
;; https://www.keylength.com/en/4/
|
||||||
org-footnote org-macro ob org org-clock org-agenda
|
gnutls-min-prime-bits 3072
|
||||||
org-capture))
|
tls-checktrust gnutls-verify-error
|
||||||
|
;; Emacs is built with gnutls.el by default, so `tls-program' won't
|
||||||
This is already done by the lang/org module, however.
|
;; typically be used, but in the odd case that it does, we ensure a more
|
||||||
|
;; secure default for it (falling back to `openssl' if absolutely
|
||||||
If you want to disable incremental loading altogether, either remove
|
;; necessary). See https://redd.it/8sykl1 for details.
|
||||||
`doom-load-packages-incrementally-h' from `emacs-startup-hook' or set
|
tls-program '("openssl s_client -connect %h:%p -CAfile %t -nbio -no_ssl3 -no_tls1 -no_tls1_1 -ign_eof"
|
||||||
`doom-incremental-first-idle-timer' to nil. Incremental loading does not occur
|
"gnutls-cli -p %p --dh-bits=3072 --ocsp --x509cafile=%t \
|
||||||
in daemon sessions (they are loaded immediately at startup).")
|
--strict-tofu --priority='SECURE192:+SECURE128:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3' %h"
|
||||||
|
;; compatibility fallbacks
|
||||||
(defvar doom-incremental-first-idle-timer 2.0
|
"gnutls-cli -p %p %h"))
|
||||||
"How long (in idle seconds) until incremental loading starts.
|
|
||||||
|
|
||||||
Set this to nil to disable incremental loading.")
|
|
||||||
|
|
||||||
(defvar doom-incremental-idle-timer 0.75
|
|
||||||
"How long (in idle seconds) in between incrementally loading packages.")
|
|
||||||
|
|
||||||
(defvar doom-incremental-load-immediately (daemonp)
|
|
||||||
"If non-nil, load all incrementally deferred packages immediately at startup.")
|
|
||||||
|
|
||||||
(defun doom-load-packages-incrementally (packages &optional now)
|
|
||||||
"Registers PACKAGES to be loaded incrementally.
|
|
||||||
|
|
||||||
If NOW is non-nil, load PACKAGES incrementally, in `doom-incremental-idle-timer'
|
|
||||||
intervals."
|
|
||||||
(if (not now)
|
|
||||||
(appendq! doom-incremental-packages packages)
|
|
||||||
(while packages
|
|
||||||
(let* ((gc-cons-threshold most-positive-fixnum)
|
|
||||||
(req (pop packages)))
|
|
||||||
(unless (featurep req)
|
|
||||||
(doom-log "Incrementally loading %s" req)
|
|
||||||
(condition-case-unless-debug e
|
|
||||||
(or (while-no-input
|
|
||||||
;; If `default-directory' is a directory that doesn't exist
|
|
||||||
;; or is unreadable, Emacs throws up file-missing errors, so
|
|
||||||
;; we set it to a directory we know exists and is readable.
|
|
||||||
(let ((default-directory doom-emacs-dir)
|
|
||||||
(inhibit-message t)
|
|
||||||
file-name-handler-alist)
|
|
||||||
(require req nil t))
|
|
||||||
t)
|
|
||||||
(push req packages))
|
|
||||||
(error
|
|
||||||
(message "Failed to load %S package incrementally, because: %s"
|
|
||||||
req e)))
|
|
||||||
(if (not packages)
|
|
||||||
(doom-log "Finished incremental loading")
|
|
||||||
(run-with-idle-timer doom-incremental-idle-timer
|
|
||||||
nil #'doom-load-packages-incrementally
|
|
||||||
packages t)
|
|
||||||
(setq packages nil)))))))
|
|
||||||
|
|
||||||
(defun doom-load-packages-incrementally-h ()
|
|
||||||
"Begin incrementally loading packages in `doom-incremental-packages'.
|
|
||||||
|
|
||||||
If this is a daemon session, load them all immediately instead."
|
|
||||||
(if doom-incremental-load-immediately
|
|
||||||
(mapc #'require (cdr doom-incremental-packages))
|
|
||||||
(when (numberp doom-incremental-first-idle-timer)
|
|
||||||
(run-with-idle-timer doom-incremental-first-idle-timer
|
|
||||||
nil #'doom-load-packages-incrementally
|
|
||||||
(cdr doom-incremental-packages) t))))
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;;; Fixes/hacks
|
|
||||||
|
|
||||||
;; Produce more helpful (and visible) error messages from errors emitted from
|
|
||||||
;; hooks (particularly mode hooks, that usually go unnoticed otherwise.
|
|
||||||
(advice-add #'run-hooks :override #'doom-run-hooks)
|
|
||||||
|
|
||||||
|
|
||||||
;;
|
|
||||||
;;; Bootstrapper
|
|
||||||
|
|
||||||
(defun doom-display-benchmark-h (&optional return-p)
|
|
||||||
"Display a benchmark including number of packages and modules loaded.
|
|
||||||
|
|
||||||
If RETURN-P, return the message as a string instead of displaying it."
|
|
||||||
(funcall (if return-p #'format #'message)
|
|
||||||
"Doom loaded %d packages across %d modules in %.03fs"
|
|
||||||
(- (length load-path) (length (get 'load-path 'initial-value)))
|
|
||||||
(if doom-modules (hash-table-count doom-modules) 0)
|
|
||||||
(or doom-init-time
|
|
||||||
(setq doom-init-time
|
|
||||||
(float-time (time-subtract (current-time) before-init-time))))))
|
|
||||||
|
|
||||||
(defun doom-initialize (&optional force-p)
|
|
||||||
"Bootstrap Doom, if it hasn't already (or if FORCE-P is non-nil).
|
|
||||||
|
|
||||||
The bootstrap process ensures that everything Doom needs to run is set up;
|
|
||||||
essential directories exist, core packages are installed, `doom-autoloads-file'
|
|
||||||
is loaded (failing if it isn't), that all the needed hooks are in place, and
|
|
||||||
that `core-packages' will load when `package' or `straight' is used.
|
|
||||||
|
|
||||||
The overall load order of Doom is as follows:
|
|
||||||
|
|
||||||
~/.emacs.d/init.el
|
|
||||||
~/.emacs.d/core/core.el
|
|
||||||
~/.doom.d/init.el
|
|
||||||
Module init.el files
|
|
||||||
`doom-init-modules-hook'
|
|
||||||
Module config.el files
|
|
||||||
`doom-configure-modules-hook'
|
|
||||||
~/.doom.d/config.el
|
|
||||||
`after-init-hook'
|
|
||||||
`emacs-startup-hook'
|
|
||||||
`doom-init-ui-hook'
|
|
||||||
`window-setup-hook'
|
|
||||||
|
|
||||||
Module load order is determined by your `doom!' block. See `doom-modules-dirs'
|
|
||||||
for a list of all recognized module trees. Order defines precedence (from most
|
|
||||||
to least)."
|
|
||||||
(when (or force-p (not doom-init-p))
|
|
||||||
(setq doom-init-p t)
|
|
||||||
(doom-log "Initializing Doom")
|
|
||||||
|
|
||||||
;; Reset as much state as possible, so `doom-initialize' can be treated like
|
|
||||||
;; a reset function. e.g. when reloading the config.
|
|
||||||
(dolist (var '(exec-path load-path))
|
|
||||||
(set-default var (get var 'initial-value)))
|
|
||||||
|
|
||||||
;; Doom caches a lot of information in `doom-autoloads-file'. Module and
|
|
||||||
;; package autoloads, autodefs like `set-company-backend!', and variables
|
|
||||||
;; like `doom-modules', `doom-disabled-packages', `load-path',
|
|
||||||
;; `auto-mode-alist', and `Info-directory-list'. etc. Compiling them into
|
|
||||||
;; one place is a big reduction in startup time.
|
|
||||||
(condition-case-unless-debug e
|
|
||||||
;; Avoid `file-name-sans-extension' for premature optimization reasons.
|
|
||||||
;; `string-remove-suffix' is cheaper because it performs no file sanity
|
|
||||||
;; checks; just plain ol' string manipulation.
|
|
||||||
(load (string-remove-suffix ".el" doom-autoloads-file) nil 'nomessage)
|
|
||||||
(file-missing
|
|
||||||
;; If the autoloads file fails to load then the user forgot to sync, or
|
|
||||||
;; aborted a doom command midway!
|
|
||||||
(if (locate-file doom-autoloads-file load-path)
|
|
||||||
;; Something inside the autoloads file is triggering this error;
|
|
||||||
;; forward it to the caller!
|
|
||||||
(signal 'doom-autoload-error e)
|
|
||||||
(signal 'doom-error
|
|
||||||
(list "Doom is in an incomplete state"
|
|
||||||
"run 'doom sync' on the command line to repair it")))))
|
|
||||||
|
|
||||||
(if doom-debug-p (doom-debug-mode +1))
|
|
||||||
|
|
||||||
;; Load shell environment, optionally generated from 'doom env'. No need
|
|
||||||
;; to do so if we're in terminal Emacs, where Emacs correctly inherits
|
|
||||||
;; your shell environment.
|
|
||||||
(when (and (or (display-graphic-p)
|
|
||||||
(daemonp))
|
|
||||||
doom-env-file)
|
|
||||||
(setq-default process-environment (get 'process-environment 'initial-value))
|
|
||||||
(doom-load-envvars-file doom-env-file 'noerror))
|
|
||||||
|
|
||||||
;; Loads `use-package' and all the helper macros modules (and users) can use
|
|
||||||
;; to configure their packages.
|
|
||||||
(require 'core-modules)
|
|
||||||
|
|
||||||
;; There's a chance the user will later use package.el or straight in this
|
|
||||||
;; interactive session. If they do, make sure they're properly initialized
|
|
||||||
;; when they do.
|
|
||||||
(autoload 'doom-initialize-packages "core-packages")
|
|
||||||
(eval-after-load 'package '(require 'core-packages))
|
|
||||||
(eval-after-load 'straight '(doom-initialize-packages))
|
|
||||||
|
|
||||||
(unless noninteractive
|
|
||||||
;; Bootstrap the interactive session
|
|
||||||
(add-hook 'after-change-major-mode-hook #'doom-run-local-var-hooks-maybe-h 100)
|
|
||||||
(add-hook 'hack-local-variables-hook #'doom-run-local-var-hooks-h)
|
|
||||||
(add-hook 'emacs-startup-hook #'doom-load-packages-incrementally-h)
|
|
||||||
(add-hook 'window-setup-hook #'doom-display-benchmark-h)
|
|
||||||
(doom-run-hook-on 'doom-first-buffer-hook '(find-file-hook doom-switch-buffer-hook))
|
|
||||||
(doom-run-hook-on 'doom-first-file-hook '(find-file-hook dired-initial-position-hook))
|
|
||||||
(doom-run-hook-on 'doom-first-input-hook '(pre-command-hook))
|
|
||||||
|
|
||||||
(add-hook 'doom-first-buffer-hook #'gcmh-mode)))
|
|
||||||
|
|
||||||
doom-init-p)
|
|
||||||
|
|
||||||
(provide 'core)
|
(provide 'core)
|
||||||
;;; core.el ends here
|
;;; core.el ends here
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
;;; early-init.el -*- lexical-binding: t; -*-
|
;;; early-init.el -*- lexical-binding: t; -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;
|
||||||
;; Emacs 27.1 introduced early-init.el, which is run before init.el, before
|
;; Emacs 27.1 introduced early-init.el, which is run before init.el, before
|
||||||
;; package and UI initialization happens, and before site files are loaded.
|
;; package and UI initialization happens, and before site files are loaded. This
|
||||||
|
;; is the best time to make all our changes (though any UI work will have to be
|
||||||
|
;; deferred).
|
||||||
|
;;
|
||||||
|
;; This file is the entry point into Doom Emacs for your standard, interactive
|
||||||
|
;; Emacs session, and houses our most pressing and hackiest startup
|
||||||
|
;; optimizations. That said, only the "bootstrap" section at the bottom is
|
||||||
|
;; required for Doom to function.
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
;; A big contributor to startup times is garbage collection. We up the gc
|
;; A big contributor to startup times is garbage collection. We up the gc
|
||||||
;; threshold to temporarily prevent it from running, then reset it later by
|
;; threshold to temporarily prevent it from running, then reset it later by
|
||||||
;; enabling `gcmh-mode'. Not resetting it will cause stuttering/freezes.
|
;; enabling `gcmh-mode'. Not resetting it will cause stuttering/freezes.
|
||||||
(setq gc-cons-threshold most-positive-fixnum)
|
(setq gc-cons-threshold most-positive-fixnum)
|
||||||
|
|
||||||
;; Prevent unwanted runtime compilation for gccemacs (native-comp) users;
|
|
||||||
;; packages are compiled ahead-of-time when they are installed and site files
|
|
||||||
;; are compiled when gccemacs is installed.
|
|
||||||
(setq native-comp-deferred-compilation nil)
|
|
||||||
|
|
||||||
;; In Emacs 27+, package initialization occurs before `user-init-file' is
|
|
||||||
;; loaded, but after `early-init-file'. Doom handles package initialization, so
|
|
||||||
;; we must prevent Emacs from doing it early!
|
|
||||||
(setq package-enable-at-startup nil)
|
|
||||||
|
|
||||||
;; In noninteractive sessions, prioritize non-byte-compiled source files to
|
;; In noninteractive sessions, prioritize non-byte-compiled source files to
|
||||||
;; prevent the use of stale byte-code. Otherwise, it saves us a little IO time
|
;; prevent the use of stale byte-code. Otherwise, it saves us a little IO time
|
||||||
;; to skip the mtime checks on every *.elc file.
|
;; to skip the mtime checks on every *.elc file.
|
||||||
|
@ -69,15 +69,33 @@
|
||||||
;;
|
;;
|
||||||
;;; Bootstrap
|
;;; Bootstrap
|
||||||
|
|
||||||
;; Contrary to what many Emacs users have in their configs, you don't need
|
|
||||||
;; more than this to make UTF-8 the default coding system:
|
|
||||||
(set-language-environment "UTF-8")
|
|
||||||
|
|
||||||
;; set-language-enviornment sets default-input-method, which is unwanted
|
|
||||||
(setq default-input-method nil)
|
|
||||||
|
|
||||||
;; Ensure Doom is running out of this file's directory
|
;; Ensure Doom is running out of this file's directory
|
||||||
(setq user-emacs-directory (file-name-directory load-file-name))
|
(setq user-emacs-directory (file-name-directory load-file-name))
|
||||||
|
|
||||||
;; Load the heart of Doom Emacs
|
;; Load the heart of Doom Emacs
|
||||||
(load (concat user-emacs-directory "core/core") nil 'nomessage)
|
(load (concat user-emacs-directory "core/core") nil 'nomessage)
|
||||||
|
|
||||||
|
;; We hijack Emacs' initfile resolver to inject our own entry point. Why do
|
||||||
|
;; this? Because:
|
||||||
|
;;
|
||||||
|
;; - It spares Emacs the effort of looking for/loading useless initfiles, like
|
||||||
|
;; ~/.emacs and ~/_emacs. And skips ~/.emacs.d/init.el, which won't exist if
|
||||||
|
;; you're using Doom (fyi: doom hackers or chemacs users could then use
|
||||||
|
;; $EMACSDIR as their $DOOMDIR, if they wanted).
|
||||||
|
;; - Later, 'doom sync' will dynamically generate its bootstrap file, which is
|
||||||
|
;; important for Doom's soon-to-be profile system (which can replace Chemacs).
|
||||||
|
;; Until then, we'll use core/core-start.el.
|
||||||
|
;; - A "fallback" initfile can be trivially specified, in case the bootstrapper
|
||||||
|
;; is missing (if the user hasn't run 'doom sync' or is a first-timer). This
|
||||||
|
;; is an opportunity to display a "safe mode" environment that's less
|
||||||
|
;; intimidating and more helpful than the broken state errors would've left
|
||||||
|
;; Emacs in, otherwise.
|
||||||
|
;; - A generated config allows for a file IO optimized startup.
|
||||||
|
(define-advice startup--load-user-init-file (:filter-args (args) init-doom)
|
||||||
|
"Initialize Doom Emacs in an interactive session."
|
||||||
|
(list (lambda ()
|
||||||
|
(expand-file-name "core-start" doom-core-dir))
|
||||||
|
nil ; TODO Replace with safe mode initfile
|
||||||
|
(caddr args)))
|
||||||
|
|
||||||
|
;;; early-init.el ends here
|
||||||
|
|
57
init.el
57
init.el
|
@ -1,57 +0,0 @@
|
||||||
;;; init.el -*- lexical-binding: t; -*-
|
|
||||||
;;
|
|
||||||
;; Author: Henrik Lissner <contact@henrik.io>
|
|
||||||
;; URL: https://github.com/hlissner/doom-emacs
|
|
||||||
;;
|
|
||||||
;; ================= =============== =============== ======== ========
|
|
||||||
;; \\ . . . . . . .\\ //. . . . . . .\\ //. . . . . . .\\ \\. . .\\// . . //
|
|
||||||
;; ||. . ._____. . .|| ||. . ._____. . .|| ||. . ._____. . .|| || . . .\/ . . .||
|
|
||||||
;; || . .|| ||. . || || . .|| ||. . || || . .|| ||. . || ||. . . . . . . ||
|
|
||||||
;; ||. . || || . .|| ||. . || || . .|| ||. . || || . .|| || . | . . . . .||
|
|
||||||
;; || . .|| ||. _-|| ||-_ .|| ||. . || || . .|| ||. _-|| ||-_.|\ . . . . ||
|
|
||||||
;; ||. . || ||-' || || `-|| || . .|| ||. . || ||-' || || `|\_ . .|. .||
|
|
||||||
;; || . _|| || || || || ||_ . || || . _|| || || || |\ `-_/| . ||
|
|
||||||
;; ||_-' || .|/ || || \|. || `-_|| ||_-' || .|/ || || | \ / |-_.||
|
|
||||||
;; || ||_-' || || `-_|| || || ||_-' || || | \ / | `||
|
|
||||||
;; || `' || || `' || || `' || || | \ / | ||
|
|
||||||
;; || .===' `===. .==='.`===. .===' /==. | \/ | ||
|
|
||||||
;; || .==' \_|-_ `===. .===' _|_ `===. .===' _-|/ `== \/ | ||
|
|
||||||
;; || .==' _-' `-_ `=' _-' `-_ `=' _-' `-_ /| \/ | ||
|
|
||||||
;; || .==' _-' '-__\._-' '-_./__-' `' |. /| | ||
|
|
||||||
;; ||.==' _-' `' | /==.||
|
|
||||||
;; ==' _-' \/ `==
|
|
||||||
;; \ _-' `-_ /
|
|
||||||
;; `'' ``'
|
|
||||||
;;
|
|
||||||
;; These demons are not part of GNU Emacs.
|
|
||||||
;;
|
|
||||||
;;; License: MIT
|
|
||||||
|
|
||||||
;; In the strange case that early-init.el wasn't loaded (e.g. you're using
|
|
||||||
;; Chemacs 1? Or you're loading this file directly?), we do it explicitly:
|
|
||||||
(unless (boundp 'doom-version)
|
|
||||||
(load (concat (file-name-directory load-file-name) "early-init")
|
|
||||||
nil t))
|
|
||||||
|
|
||||||
;; Ensure Doom's core libraries are properly initialized, autoloads file is
|
|
||||||
;; loaded, and hooks set up for an interactive session.
|
|
||||||
(doom-initialize)
|
|
||||||
|
|
||||||
;; Now we load all enabled modules in the order dictated by your `doom!' block
|
|
||||||
;; in $DOOMDIR/init.el. `doom-initialize-modules' loads them (and hooks) in the
|
|
||||||
;; given order:
|
|
||||||
;;
|
|
||||||
;; $DOOMDIR/init.el
|
|
||||||
;; {$DOOMDIR,~/.emacs.d}/modules/*/*/init.el
|
|
||||||
;; `doom-before-init-modules-hook'
|
|
||||||
;; {$DOOMDIR,~/.emacs.d}/modules/*/*/config.el
|
|
||||||
;; `doom-init-modules-hook'
|
|
||||||
;; $DOOMDIR/config.el
|
|
||||||
;; `doom-after-init-modules-hook'
|
|
||||||
;; `after-init-hook'
|
|
||||||
;; `emacs-startup-hook'
|
|
||||||
;; `doom-init-ui-hook'
|
|
||||||
;; `window-setup-hook'
|
|
||||||
;;
|
|
||||||
;; And then we're good to go!
|
|
||||||
(doom-initialize-modules)
|
|
Loading…
Add table
Add a link
Reference in a new issue