mirror of
https://gitlab.com/dwt1/dotfiles.git
synced 2026-04-23 19:40:24 +10:00
Updating Doom Emacs.
This commit is contained in:
@@ -1,41 +1,58 @@
|
||||
;;; core.el --- the heart of the beast -*- lexical-binding: t; -*-
|
||||
|
||||
(when (version< emacs-version "26.1")
|
||||
(error "Detected Emacs %s. Doom only supports Emacs 26.1 and higher"
|
||||
emacs-version))
|
||||
(eval-when-compile
|
||||
(when (< emacs-major-version 26)
|
||||
(error "Detected Emacs v%s. Doom only supports Emacs 26 and newer"
|
||||
emacs-version)))
|
||||
|
||||
|
||||
;;
|
||||
;;; Variables
|
||||
|
||||
(defconst doom-version "2.0.9"
|
||||
"Current version of Doom Emacs.")
|
||||
|
||||
(defconst EMACS27+ (> emacs-major-version 26))
|
||||
(defconst EMACS28+ (> emacs-major-version 27))
|
||||
(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)))
|
||||
|
||||
;; Unix tools look for HOME, but this is normally not defined on Windows.
|
||||
(when (and IS-WINDOWS (null (getenv "HOME")))
|
||||
(setenv "HOME" (getenv "USERPROFILE")))
|
||||
|
||||
;; Ensure `doom-core-dir' is in `load-path'
|
||||
(add-to-list 'load-path (file-name-directory load-file-name))
|
||||
|
||||
(defvar doom--initial-load-path load-path)
|
||||
(defvar doom--initial-process-environment process-environment)
|
||||
(defvar doom--initial-exec-path exec-path)
|
||||
(defvar doom--initial-file-name-handler-alist file-name-handler-alist)
|
||||
|
||||
;; This is consulted on every `require', `load' and various path/io functions.
|
||||
;; You get a minor speed up by nooping this.
|
||||
(setq file-name-handler-alist nil)
|
||||
;; `file-name-handler-alist' is consulted on every `require', `load' and various
|
||||
;; path/io functions. You get a minor speed up by nooping this. However, this
|
||||
;; may cause problems on builds of Emacs where its site lisp files aren't
|
||||
;; byte-compiled and we're forced to load the *.el.gz files (e.g. on Alpine)
|
||||
(unless noninteractive
|
||||
(defvar doom--initial-file-name-handler-alist file-name-handler-alist)
|
||||
|
||||
;; Restore `file-name-handler-alist', because it is needed for handling
|
||||
;; encrypted or compressed files, among other things.
|
||||
(defun doom-reset-file-handler-alist-h ()
|
||||
(setq file-name-handler-alist doom--initial-file-name-handler-alist))
|
||||
(add-hook 'emacs-startup-hook #'doom-reset-file-handler-alist-h)
|
||||
(setq file-name-handler-alist nil)
|
||||
;; Restore `file-name-handler-alist', because it is needed for handling
|
||||
;; encrypted or compressed files, among other things.
|
||||
(defun doom-reset-file-handler-alist-h ()
|
||||
;; Re-add rather than `setq', because file-name-handler-alist may have
|
||||
;; changed since startup, and we want to preserve those.
|
||||
(dolist (handler file-name-handler-alist)
|
||||
(add-to-list 'doom--initial-file-name-handler-alist handler))
|
||||
(setq file-name-handler-alist doom--initial-file-name-handler-alist))
|
||||
(add-hook 'emacs-startup-hook #'doom-reset-file-handler-alist-h))
|
||||
|
||||
;; Load the bare necessities
|
||||
;; Just the bare necessities
|
||||
(require 'subr-x)
|
||||
(require 'cl-lib)
|
||||
(require 'core-lib)
|
||||
|
||||
(autoload 'doom-initialize-packages "core-packages")
|
||||
|
||||
|
||||
;;
|
||||
;;; Global variables
|
||||
@@ -46,13 +63,13 @@
|
||||
(defvar doom-init-time nil
|
||||
"The time it took, in seconds, for Doom Emacs to initialize.")
|
||||
|
||||
(defvar doom-debug-mode (or (getenv "DEBUG") init-file-debug)
|
||||
(defvar doom-debug-p (or (getenv "DEBUG") init-file-debug)
|
||||
"If non-nil, Doom will log more.
|
||||
|
||||
Use `doom/toggle-debug-mode' to toggle it. The --debug-init flag and setting the
|
||||
DEBUG envvar will enable this at startup.")
|
||||
Use `doom-debug-mode' to toggle it. The --debug-init flag and setting the DEBUG
|
||||
envvar will enable this at startup.")
|
||||
|
||||
(defvar doom-interactive-mode (not noninteractive)
|
||||
(defvar doom-interactive-p (not noninteractive)
|
||||
"If non-nil, Emacs is in interactive mode.")
|
||||
|
||||
;;; Directories/files
|
||||
@@ -110,14 +127,8 @@ whichever is found first. Must end in a slash.")
|
||||
This file is responsible for informing Emacs where to find all of Doom's
|
||||
autoloaded core functions (in core/autoload/*.el).")
|
||||
|
||||
(defconst doom-package-autoload-file (concat doom-local-dir "autoloads.pkg.el")
|
||||
"Where `doom-reload-package-autoloads' stores its package autoloads.
|
||||
|
||||
This file is compiled from the autoloads files of all installed packages
|
||||
combined.")
|
||||
|
||||
(defconst doom-env-file (concat doom-local-dir "env")
|
||||
"The location of your envvar file, generated by `doom env refresh`.
|
||||
"The location of your envvar file, generated by `doom env`.
|
||||
|
||||
This file contains environment variables scraped from your shell environment,
|
||||
which is loaded at startup (if it exists). This is helpful if Emacs can't
|
||||
@@ -127,7 +138,7 @@ users).")
|
||||
;;; Custom error types
|
||||
(define-error 'doom-error "Error in Doom Emacs core")
|
||||
(define-error 'doom-hook-error "Error in a Doom startup hook" 'doom-error)
|
||||
(define-error 'doom-autoload-error "Error in an autoloads file" 'doom-error)
|
||||
(define-error 'doom-autoload-error "Error in Doom's autoloads file" 'doom-error)
|
||||
(define-error 'doom-module-error "Error in a Doom module" 'doom-error)
|
||||
(define-error 'doom-private-error "Error in private config" 'doom-error)
|
||||
(define-error 'doom-package-error "Error with packages" 'doom-error)
|
||||
@@ -136,84 +147,99 @@ users).")
|
||||
;;
|
||||
;;; Emacs core configuration
|
||||
|
||||
;; Reduce debug output, well, unless we've asked for it.
|
||||
(setq debug-on-error doom-debug-mode
|
||||
jka-compr-verbose doom-debug-mode)
|
||||
;; lo', longer logs ahoy, so to reliably locate lapses in doom's logic later
|
||||
(setq message-log-max 8192)
|
||||
|
||||
;; UTF-8 as the default coding system
|
||||
;; Reduce debug output, well, unless we've asked for it.
|
||||
(setq debug-on-error doom-debug-p
|
||||
jka-compr-verbose doom-debug-p)
|
||||
|
||||
;; Contrary to what many Emacs users have in their configs, you really don't
|
||||
;; need more than this to make UTF-8 the default coding system:
|
||||
(when (fboundp 'set-charset-priority)
|
||||
(set-charset-priority 'unicode)) ; pretty
|
||||
(prefer-coding-system 'utf-8) ; pretty
|
||||
(setq locale-coding-system 'utf-8) ; please
|
||||
;; Except for the clipboard on Windows, where its contents could be in an
|
||||
;; encoding that's wider than utf-8, so we let Emacs/the OS decide what encoding
|
||||
;; to use.
|
||||
;; The clipboard's on Windows could be in an encoding that's wider (or thinner)
|
||||
;; than utf-8, so let Emacs/the OS decide what encoding to use there.
|
||||
(unless IS-WINDOWS
|
||||
(setq selection-coding-system 'utf-8)) ; with sugar on top
|
||||
|
||||
;; Disable warnings from legacy advice system. They aren't useful, and we can't
|
||||
;; often do anything about them besides changing packages upstream
|
||||
;; Disable warnings from legacy advice system. They aren't useful, and what can
|
||||
;; we do about them, besides changing packages upstream?
|
||||
(setq ad-redefinition-action 'accept)
|
||||
|
||||
;; Make apropos omnipotent. It's more useful this way.
|
||||
(setq apropos-do-all t)
|
||||
|
||||
;; Don't make a second case-insensitive pass over `auto-mode-alist'. If it has
|
||||
;; to, it's our (the user's) failure. One case for all!
|
||||
;; A second, case-insensitive pass over `auto-mode-alist' is time wasted, and
|
||||
;; indicates misconfiguration (or that the user needs to stop relying on case
|
||||
;; insensitivity).
|
||||
(setq auto-mode-case-fold nil)
|
||||
|
||||
;; Make all regexps case-sensitive by default. This favors correctness for
|
||||
;; programmatical regexp searches and provides a slight performance benefit to
|
||||
;; font-locking where the keywords don't let-bind `case-fold-search' themselves
|
||||
;; and are already case-correct. This could break poorly written packages!
|
||||
(setq-default case-fold-search nil)
|
||||
|
||||
;; Display the bare minimum at startup. We don't need all that noise. The
|
||||
;; dashboard/empty scratch buffer is good enough.
|
||||
;; Less noise at startup. The dashboard/empty scratch buffer is good enough.
|
||||
(setq inhibit-startup-message t
|
||||
inhibit-startup-echo-area-message user-login-name
|
||||
inhibit-default-init t
|
||||
;; Avoid pulling in many packages by starting the scratch buffer in
|
||||
;; `fundamental-mode', rather than, say, `org-mode' or `text-mode'.
|
||||
initial-major-mode 'fundamental-mode
|
||||
initial-scratch-message nil)
|
||||
(fset #'display-startup-echo-area-message #'ignore)
|
||||
|
||||
;; 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,
|
||||
;; which isn't so bad.
|
||||
(unless (daemonp)
|
||||
(advice-add #'display-startup-echo-area-message :override #'ignore))
|
||||
|
||||
;; Emacs "updates" its ui more often than it needs to, so we slow it down
|
||||
;; slightly, from 0.5s:
|
||||
(setq idle-update-delay 1)
|
||||
;; slightly from 0.5s:
|
||||
(setq idle-update-delay 1.0)
|
||||
|
||||
;; Emacs is a huge security vulnerability, what with all the dependencies it
|
||||
;; pulls in from all corners of the globe. Let's at least try to be more
|
||||
;; discerning.
|
||||
(setq gnutls-verify-error (getenv "INSECURE")
|
||||
;; 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 at
|
||||
;; least a little more discerning.
|
||||
(setq gnutls-verify-error (not (getenv "INSECURE"))
|
||||
gnutls-algorithm-priority
|
||||
(when (boundp 'libgnutls-version)
|
||||
(concat "SECURE128:+SECURE192:-VERS-ALL"
|
||||
(if (and (not IS-WINDOWS)
|
||||
(not (version< emacs-version "26.3"))
|
||||
(>= 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
|
||||
tls-program '("gnutls-cli --x509cafile %t -p %p %h"
|
||||
;; 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"
|
||||
"openssl s_client -connect %h:%p -no_ssl2 -no_ssl3 -ign_eof"))
|
||||
"gnutls-cli -p %p %h"))
|
||||
|
||||
;; Emacs stores authinfo in HOME and in plaintext. Let's not do that, mkay? This
|
||||
;; file usually stores usernames, passwords, and other such treasures for the
|
||||
;; 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 (expand-file-name "authinfo.gpg" doom-etc-dir)
|
||||
(setq auth-sources (list (concat doom-etc-dir "authinfo.gpg")
|
||||
"~/.authinfo.gpg"))
|
||||
|
||||
;; Emacs on Windows frequently confuses HOME (C:\Users\<NAME>) and APPDATA,
|
||||
;; causing `abbreviate-home-dir' to produce incorrect paths.
|
||||
(when IS-WINDOWS
|
||||
(setq abbreviated-home-dir "\\`'"))
|
||||
|
||||
;; Don't litter `doom-emacs-dir'
|
||||
;; Don't litter `doom-emacs-dir'. We don't use `no-littering' because it's a
|
||||
;; mote too opinionated for our needs.
|
||||
(setq abbrev-file-name (concat doom-local-dir "abbrev.el")
|
||||
async-byte-compile-log-file (concat doom-etc-dir "async-bytecomp.log")
|
||||
bookmark-default-file (concat doom-etc-dir "bookmarks")
|
||||
custom-file (concat doom-private-dir "init.el")
|
||||
custom-file (concat doom-private-dir "config.el")
|
||||
custom-theme-directory (concat doom-private-dir "themes/")
|
||||
desktop-dirname (concat doom-etc-dir "desktop")
|
||||
desktop-base-file-name "autosave"
|
||||
desktop-base-lock-name "autosave-lock"
|
||||
pcache-directory (concat doom-cache-dir "pcache/")
|
||||
request-storage-directory (concat doom-cache-dir "request")
|
||||
server-auth-dir (concat doom-cache-dir "server/")
|
||||
shared-game-score-directory (concat doom-etc-dir "shared-game-score/")
|
||||
tramp-auto-save-directory (concat doom-cache-dir "tramp-auto-save/")
|
||||
tramp-backup-directory-alist backup-directory-alist
|
||||
@@ -227,13 +253,21 @@ users).")
|
||||
:override #'emacs-session-filename
|
||||
(concat doom-cache-dir "emacs-session." session-id))
|
||||
|
||||
(defadvice! doom--save-enabled-commands-to-doomdir-a (orig-fn &rest args)
|
||||
"When enabling a disabled command, the `put' call is written to
|
||||
~/.emacs.d/init.el, which causes issues for Doom, so write it to the user's
|
||||
config.el instead."
|
||||
:around #'en/disable-command
|
||||
(let ((user-init-file custom-file))
|
||||
(apply orig-fn args)))
|
||||
|
||||
|
||||
;;
|
||||
;;; Optimizations
|
||||
|
||||
;; Disable bidirectional text rendering for a modest performance boost. Of
|
||||
;; course, this renders Emacs unable to detect/display right-to-left languages
|
||||
;; (sorry!), but for us left-to-right language speakers/writers, it's a boon.
|
||||
;; Disable bidirectional text rendering for a modest performance boost. I've set
|
||||
;; this to `nil' in the past, but the `bidi-display-reordering's docs say that
|
||||
;; is an undefined state and suggest this to be just as good:
|
||||
(setq-default bidi-display-reordering 'left-to-right
|
||||
bidi-paragraph-direction 'left-to-right)
|
||||
|
||||
@@ -243,7 +277,8 @@ users).")
|
||||
(setq highlight-nonselected-windows nil)
|
||||
|
||||
;; More performant rapid scrolling over unfontified regions. May cause brief
|
||||
;; spells of inaccurate fontification immediately after scrolling.
|
||||
;; spells of inaccurate syntax highlighting right after scrolling, which should
|
||||
;; quickly self-correct.
|
||||
(setq fast-but-imprecise-scrolling t)
|
||||
|
||||
;; Resizing the Emacs frame can be a terribly expensive part of changing the
|
||||
@@ -254,30 +289,42 @@ users).")
|
||||
;; Don't ping things that look like domain names.
|
||||
(setq ffap-machine-p-known 'reject)
|
||||
|
||||
;; Font compacting can be terribly expensive, especially for rendering icon
|
||||
;; fonts on Windows. Whether it has a notable affect on Linux and Mac hasn't
|
||||
;; been determined, but we inhibit it there anyway.
|
||||
(setq inhibit-compacting-font-caches t)
|
||||
|
||||
;; Performance on Windows is considerably worse than elsewhere, especially if
|
||||
;; WSL is involved. We'll need everything we can get.
|
||||
(when IS-WINDOWS
|
||||
;; Reduce the workload when doing file IO
|
||||
(setq w32-get-true-file-attributes nil)
|
||||
|
||||
;; Font compacting can be terribly expensive, especially for rendering icon
|
||||
;; fonts on Windows. Whether it has a noteable affect on Linux and Mac hasn't
|
||||
;; been determined.
|
||||
(setq inhibit-compacting-font-caches t))
|
||||
(setq w32-get-true-file-attributes nil ; slightly faster IO
|
||||
w32-pipe-read-delay 0 ; faster ipc
|
||||
w32-pipe-buffer-size (* 64 1024))) ; read more at a time (was 4K)
|
||||
|
||||
;; Remove command line options that aren't relevant to our current OS; means
|
||||
;; slightly less to process at startup.
|
||||
(unless IS-MAC (setq command-line-ns-option-alist nil))
|
||||
(unless IS-LINUX (setq command-line-x-option-alist nil))
|
||||
|
||||
;; Delete files to trash on macOS, as an extra layer of precaution against
|
||||
;; accidentally deleting wanted files.
|
||||
(setq delete-by-moving-to-trash IS-MAC)
|
||||
|
||||
;; Adopt a sneaky garbage collection strategy of waiting until idle time to
|
||||
;; collect; staving off the collector while the user is working.
|
||||
(when doom-interactive-mode
|
||||
(add-transient-hook! 'pre-command-hook (gcmh-mode +1))
|
||||
(with-eval-after-load 'gcmh
|
||||
(setq gcmh-idle-delay 10
|
||||
gcmh-verbose doom-debug-mode)
|
||||
(add-hook 'focus-out-hook #'gcmh-idle-garbage-collect)))
|
||||
(setq gcmh-idle-delay 5
|
||||
gcmh-high-cons-threshold (* 16 1024 1024) ; 16mb
|
||||
gcmh-verbose doom-debug-p)
|
||||
|
||||
;; HACK `tty-run-terminal-initialization' is *tremendously* slow for some
|
||||
;; reason. Disabling it completely could have many side-effects, so we
|
||||
;; defer it until later, at which time it (somehow) runs very quickly.
|
||||
(unless (daemonp)
|
||||
(advice-add #'tty-run-terminal-initialization :override #'ignore)
|
||||
(add-hook! 'window-setup-hook
|
||||
(defun doom-init-tty-h ()
|
||||
(advice-remove #'tty-run-terminal-initialization #'ignore)
|
||||
(tty-run-terminal-initialization (selected-frame) nil t))))
|
||||
|
||||
|
||||
;;
|
||||
@@ -290,18 +337,14 @@ users).")
|
||||
"Run MODE-local-vars-hook after local variables are initialized."
|
||||
(run-hook-wrapped (intern-soft (format "%s-local-vars-hook" major-mode))
|
||||
#'doom-try-run-hook))
|
||||
(add-hook 'hack-local-variables-hook #'doom-run-local-var-hooks-h)
|
||||
|
||||
;; 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-if-necessary-h ()
|
||||
(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)))
|
||||
(add-hook 'after-change-major-mode-hook
|
||||
#'doom-run-local-var-hooks-if-necessary-h
|
||||
'append)
|
||||
|
||||
|
||||
;;
|
||||
@@ -326,21 +369,24 @@ If you want to disable incremental loading altogether, either remove
|
||||
`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
|
||||
(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 1.5
|
||||
(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)
|
||||
(nconc doom-incremental-packages packages)
|
||||
(appendq! doom-incremental-packages packages)
|
||||
(while packages
|
||||
(let ((req (pop packages)))
|
||||
(unless (featurep req)
|
||||
@@ -357,7 +403,7 @@ intervals."
|
||||
t)
|
||||
(push req packages))
|
||||
((error debug)
|
||||
(message "Failed to load '%s' package incrementally, because: %s"
|
||||
(message "Failed to load %S package incrementally, because: %s"
|
||||
req e)))
|
||||
(if (not packages)
|
||||
(doom-log "Finished incremental loading")
|
||||
@@ -370,33 +416,32 @@ intervals."
|
||||
"Begin incrementally loading packages in `doom-incremental-packages'.
|
||||
|
||||
If this is a daemon session, load them all immediately instead."
|
||||
(if (daemonp)
|
||||
(if doom-incremental-load-immediately
|
||||
(mapc #'require (cdr doom-incremental-packages))
|
||||
(when (integerp doom-incremental-first-idle-timer)
|
||||
(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))))
|
||||
|
||||
(add-hook 'emacs-startup-hook #'doom-load-packages-incrementally-h)
|
||||
|
||||
;;
|
||||
;;; Custom hooks
|
||||
|
||||
(defvar doom-first-input-hook nil
|
||||
"Transient hooks run before the first user input.")
|
||||
|
||||
(defvar doom-first-file-hook nil
|
||||
"Transient hooks run before the first interactively opened file.")
|
||||
|
||||
(defvar doom-first-buffer-hook nil
|
||||
"Transient hooks run before the first interactively opened buffer.")
|
||||
|
||||
|
||||
;;
|
||||
;;; Bootstrap helpers
|
||||
|
||||
(defun doom-try-run-hook (hook)
|
||||
"Run HOOK (a hook function) with better error handling.
|
||||
Meant to be used with `run-hook-wrapped'."
|
||||
(doom-log "Running doom hook: %s" hook)
|
||||
(condition-case e
|
||||
(funcall hook)
|
||||
((debug error)
|
||||
(signal 'doom-hook-error (list hook e))))
|
||||
;; return nil so `run-hook-wrapped' won't short circuit
|
||||
nil)
|
||||
|
||||
(defun doom-display-benchmark-h (&optional return-p)
|
||||
"Display a benchmark, showing number of packages and modules, and how quickly
|
||||
they were loaded at startup.
|
||||
"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)
|
||||
@@ -407,58 +452,13 @@ If RETURN-P, return the message as a string instead of displaying it."
|
||||
(setq doom-init-time
|
||||
(float-time (time-subtract (current-time) before-init-time))))))
|
||||
|
||||
(defun doom-load-autoloads-file (file &optional noerror)
|
||||
"Tries to load FILE (an autoloads file).
|
||||
Return t on success, nil otherwise (but logs a warning)."
|
||||
(condition-case e
|
||||
(load (substring file 0 -3) noerror 'nomessage)
|
||||
((debug error)
|
||||
(message "Autoload file error: %s -> %s" (file-name-nondirectory file) e)
|
||||
nil)))
|
||||
|
||||
(defun doom-load-envvars-file (file &optional noerror)
|
||||
"Read and set envvars from FILE.
|
||||
If NOERROR is non-nil, don't throw an error if the file doesn't exist or is
|
||||
unreadable. Returns the names of envvars that were changed."
|
||||
(if (not (file-readable-p file))
|
||||
(unless noerror
|
||||
(signal 'file-error (list "Couldn't read envvar file" file)))
|
||||
(let (envvars environment)
|
||||
(with-temp-buffer
|
||||
(save-excursion
|
||||
(insert "\n")
|
||||
(insert-file-contents file))
|
||||
(while (re-search-forward "\n *\\([^#= \n]*\\)=" nil t)
|
||||
(push (match-string 1) envvars)
|
||||
(push (buffer-substring
|
||||
(match-beginning 1)
|
||||
(1- (or (save-excursion
|
||||
(when (re-search-forward "^\\([^= ]+\\)=" nil t)
|
||||
(line-beginning-position)))
|
||||
(point-max))))
|
||||
environment)))
|
||||
(when environment
|
||||
(setq process-environment
|
||||
(append (nreverse environment) process-environment)
|
||||
exec-path
|
||||
(if (member "PATH" envvars)
|
||||
(append (parse-colon-path (getenv "PATH"))
|
||||
(list exec-directory))
|
||||
exec-path)
|
||||
shell-file-name
|
||||
(if (member "SHELL" envvars)
|
||||
(setq shell-file-name
|
||||
(or (getenv "SHELL") shell-file-name))
|
||||
shell-file-name))
|
||||
envvars))))
|
||||
|
||||
(defun doom-initialize (&optional force-p noerror)
|
||||
(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 the essential directories exist, all core
|
||||
packages are installed, `doom-autoload-file' and `doom-package-autoload-file'
|
||||
exist and are loaded, and that `core-packages' is auto-loaded when `package' or
|
||||
`straight' are.
|
||||
The bootstrap process ensures that everything Doom needs to run is set up;
|
||||
essential directories exist, core packages are installed, `doom-autoload-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:
|
||||
|
||||
@@ -470,7 +470,7 @@ The overall load order of Doom is as follows:
|
||||
Module config.el files
|
||||
~/.doom.d/config.el
|
||||
`doom-init-modules-hook'
|
||||
`after-init-hook'
|
||||
`doom-after-init-modules-hook' (`after-init-hook')
|
||||
`emacs-startup-hook'
|
||||
`doom-init-ui-hook'
|
||||
`window-setup-hook'
|
||||
@@ -480,74 +480,67 @@ 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. Particularly useful for reloading the config.
|
||||
;; a reset function. e.g. when reloading the config.
|
||||
(setq-default exec-path doom--initial-exec-path
|
||||
load-path doom--initial-load-path
|
||||
process-environment doom--initial-process-environment)
|
||||
|
||||
;; Load shell environment, optionally generated from 'doom env'. No need to
|
||||
;; do so if we're in terminal Emacs, because Emacs will correctly inherit
|
||||
;; Doom caches a lot of information in `doom-autoload-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 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-autoload-file)
|
||||
nil 'nomessage)
|
||||
(file-missing
|
||||
;; If the autoloads file fails to load then the user forgot to sync, or
|
||||
;; aborted a doom command midway!
|
||||
(signal 'doom-error
|
||||
(list "Doom is in an incomplete state"
|
||||
"run 'bin/doom sync' on the command line to repair it"))))
|
||||
|
||||
;; 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 there.
|
||||
(when (and (or (display-graphic-p)
|
||||
(daemonp))
|
||||
(file-exists-p doom-env-file))
|
||||
(doom-load-envvars-file doom-env-file))
|
||||
(if (or (display-graphic-p)
|
||||
(daemonp))
|
||||
(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)
|
||||
(let (;; `doom-autoload-file' tells Emacs where to load all its functions
|
||||
;; from. This includes everything in core/autoload/*.el and autoload
|
||||
;; files in enabled modules.
|
||||
(core-autoloads-p (doom-load-autoloads-file doom-autoload-file noerror))
|
||||
;; Loads `doom-package-autoload-file', which loads a concatenated
|
||||
;; package autoloads file which caches `load-path', `auto-mode-alist',
|
||||
;; `Info-directory-list', and `doom-disabled-packages'. A big
|
||||
;; reduction in startup time.
|
||||
(pkg-autoloads-p (doom-load-autoloads-file doom-package-autoload-file noerror)))
|
||||
|
||||
(if (and core-autoloads-p pkg-autoloads-p (not force-p))
|
||||
;; In case we want to use package.el or straight via M-x
|
||||
(progn
|
||||
(with-eval-after-load 'package
|
||||
(require 'core-packages))
|
||||
(with-eval-after-load 'straight
|
||||
(require 'core-packages)
|
||||
(doom-initialize-packages)))
|
||||
;; There's a chance the user will want to use package.el or straight later
|
||||
;; on in this interactive session. If that's the case, make sure they're
|
||||
;; properly initialized when they do.
|
||||
(autoload 'doom-initialize-packages "core-packages")
|
||||
(autoload 'doom-initialize-core-packages "core-packages")
|
||||
(with-eval-after-load 'package (require 'core-packages))
|
||||
(with-eval-after-load 'straight (doom-initialize-packages))
|
||||
|
||||
;; Eagerly load these libraries because we may be in a session that hasn't been
|
||||
;; fully initialized (e.g. where autoloads files haven't been generated or
|
||||
;; `load-path' populated).
|
||||
(mapc (doom-rpartial #'load nil (not doom-debug-mode) 'nosuffix)
|
||||
(file-expand-wildcards (concat doom-core-dir "autoload/*.el")))
|
||||
;; Bootstrap the interactive session
|
||||
(add-hook! 'window-setup-hook
|
||||
(add-hook 'hack-local-variables-hook #'doom-run-local-var-hooks-h)
|
||||
(add-hook 'after-change-major-mode-hook #'doom-run-local-var-hooks-maybe-h 'append)
|
||||
(add-hook 'doom-first-input-hook #'gcmh-mode)
|
||||
(add-hook-trigger! 'doom-first-input-hook 'pre-command-hook)
|
||||
(add-hook-trigger! 'doom-first-file-hook 'after-find-file 'dired-initial-position-hook)
|
||||
(add-hook-trigger! 'doom-first-buffer-hook 'after-find-file 'doom-switch-buffer-hook))
|
||||
(add-hook 'emacs-startup-hook #'doom-load-packages-incrementally-h)
|
||||
(add-hook 'window-setup-hook #'doom-display-benchmark-h 'append)
|
||||
(if doom-debug-p (doom-debug-mode +1))
|
||||
|
||||
;; Create all our core directories to quell file errors
|
||||
(dolist (dir (list doom-local-dir
|
||||
doom-etc-dir
|
||||
doom-cache-dir))
|
||||
(unless (file-directory-p dir)
|
||||
(make-directory dir 'parents)))
|
||||
;; Load core/core-*.el, the user's private init.el and their config.el
|
||||
(doom-initialize-modules force-p))
|
||||
|
||||
;; Ensure the package management system (and straight) are ready for
|
||||
;; action (and all core packages/repos are installed)
|
||||
(require 'core-packages)
|
||||
(doom-initialize-packages force-p))
|
||||
|
||||
(unless (or (and core-autoloads-p pkg-autoloads-p)
|
||||
noerror)
|
||||
(unless core-autoloads-p
|
||||
(warn "Your Doom core autoloads file is missing"))
|
||||
(unless pkg-autoloads-p
|
||||
(warn "Your package autoloads file is missing"))
|
||||
(signal 'doom-autoload-error (list "Run `bin/doom refresh' to generate them"))))
|
||||
t))
|
||||
|
||||
(defun doom-initialize-core ()
|
||||
"Load Doom's core files for an interactive session."
|
||||
(require 'core-keybinds)
|
||||
(require 'core-ui)
|
||||
(require 'core-projects)
|
||||
(require 'core-editor))
|
||||
doom-init-p)
|
||||
|
||||
(provide 'core)
|
||||
;;; core.el ends here
|
||||
|
||||
Reference in New Issue
Block a user