Simplify and decouple init files

The two doom-gc-* variables in init.el couples the rest of the config to
these two files. The bulk of GC/file-handler optimization was moved into
core.el and simplified (all that idle-timer voodoo was overkill).

Also adds (setq frame-inhibit-implied-reize t) to early-init, which
speeds up startup a fair bit in some edge cases with larger fonts.

squash! Simplify and decouple init files
This commit is contained in:
Henrik Lissner 2019-07-21 03:01:15 +02:00
parent 8147bc1aee
commit 81ab3dbc5d
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
4 changed files with 118 additions and 136 deletions

View file

@ -1,9 +1,10 @@
;;; core.el --- the heart of the beast -*- lexical-binding: t; -*- ;;; core.el --- the heart of the beast -*- lexical-binding: t; -*-
(eval-when-compile (defvar doom-init-p nil
(and (version< emacs-version "25.3") "Non-nil if Doom has been initialized.")
(error "Detected Emacs %s. Doom only supports Emacs 25.3 and higher"
emacs-version))) (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-mode (or (getenv "DEBUG") init-file-debug)
"If non-nil, Doom will log more. "If non-nil, Doom will log more.
@ -11,10 +12,11 @@
Use `doom/toggle-debug-mode' to toggle it. The --debug-init flag and setting the Use `doom/toggle-debug-mode' to toggle it. The --debug-init flag and setting the
DEBUG envvar will enable this at startup.") DEBUG envvar will enable this at startup.")
(defvar doom-gc-cons-threshold 16777216 ; 16mb
"The default value to use for `gc-cons-threshold'. If you experience freezing,
decrease this. If you experience stuttering, increase this.")
;;
;;; Constants ;;; Constants
(defconst doom-version "2.0.9" (defconst doom-version "2.0.9"
"Current version of Doom Emacs.") "Current version of Doom Emacs.")
@ -26,10 +28,8 @@ DEBUG envvar will enable this at startup.")
(defconst IS-WINDOWS (memq system-type '(cygwin windows-nt ms-dos))) (defconst IS-WINDOWS (memq system-type '(cygwin windows-nt ms-dos)))
(defconst IS-BSD (or IS-MAC (eq system-type 'berkeley-unix))) (defconst IS-BSD (or IS-MAC (eq system-type 'berkeley-unix)))
;;; Directories/files
;; (defvar doom-emacs-dir user-emacs-directory
(defvar doom-emacs-dir
(eval-when-compile (file-truename user-emacs-directory))
"The path to the currently loaded .emacs.d directory. Must end with a slash.") "The path to the currently loaded .emacs.d directory. Must end with a slash.")
(defvar doom-core-dir (concat doom-emacs-dir "core/") (defvar doom-core-dir (concat doom-emacs-dir "core/")
@ -97,44 +97,12 @@ which is loaded at startup (if it exists). This is helpful if Emacs can't
\(easily) be launched from the correct shell session (particularly for MacOS \(easily) be launched from the correct shell session (particularly for MacOS
users).") users).")
(defvar doom--initial-load-path (cons doom-core-dir 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)
;;
;;; Doom core variables
(defvar doom-init-p nil
"Non-nil if Doom has been initialized.")
(defvar doom-init-time nil
"The time it took, in seconds, for Doom Emacs to initialize.")
(defvar doom-emacs-changed-p nil
"If non-nil, the running version of Emacs is different from the first time
Doom was setup, which may cause problems.")
(defvar doom-site-load-path (cons doom-core-dir load-path)
"The initial value of `load-path', before it was altered by
`doom-initialize'.")
(defvar doom-site-process-environment process-environment
"The initial value of `process-environment', before it was altered by
`doom-initialize'.")
(defvar doom-site-exec-path exec-path
"The initial value of `exec-path', before it was altered by
`doom-initialize'.")
(defvar doom-site-shell-file-name shell-file-name
"The initial value of `shell-file-name', before it was altered by
`doom-initialize'.")
(defvar doom--last-emacs-file (concat doom-local-dir "emacs-version.el"))
(defvar doom--last-emacs-version nil)
(defvar doom--refreshed-p nil)
;;
;;; Custom error types ;;; Custom error types
(define-error 'doom-error "Error in Doom Emacs core") (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-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 an autoloads file" 'doom-error)
@ -143,13 +111,6 @@ Doom was setup, which may cause problems.")
(define-error 'doom-package-error "Error with packages" 'doom-error) (define-error 'doom-package-error "Error with packages" 'doom-error)
;;
;;; Custom hooks
(defvar doom-reload-hook nil
"A list of hooks to run when `doom/reload' is called.")
;; ;;
;;; Emacs core configuration ;;; Emacs core configuration
@ -250,6 +211,67 @@ enable multiple minor modes for the same regexp.")
(add-hook 'find-file-hook #'doom-enable-minor-mode-maybe-h) (add-hook 'find-file-hook #'doom-enable-minor-mode-maybe-h)
;;
;;; Optimizations
;; 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)
(add-hook 'emacs-startup-hook
(defun doom-restore-file-name-handler-alist-h ()
(setq file-name-handler-alist doom--initial-file-name-handler-alist)))
;; To speed up minibuffer commands (like helm and ivy), we defer garbage
;; collection while the minibuffer is active.
(defun doom-defer-garbage-collection-h ()
"TODO"
(setq gc-cons-threshold most-positive-fixnum))
(defun doom-restore-garbage-collection-h ()
"TODO"
;; Defer it so that commands launched immediately after will enjoy the
;; benefits.
(run-at-time
1 nil (lambda () (setq gc-cons-threshold doom-gc-cons-threshold))))
(add-hook 'minibuffer-setup-hook #'doom-defer-garbage-collection-h)
(add-hook 'minibuffer-exit-hook #'doom-restore-garbage-collection-h)
;; Not restoring these to their defaults will cause stuttering/freezes.
(add-hook 'emacs-startup-hook #'doom-restore-garbage-collection-h)
;; When Emacs loses focus seems like a great time to do some garbage collection
;; all sneaky breeky like, so we can return a fresh(er) Emacs.
(add-hook 'focus-out-hook #'garbage-collect)
;;
;;; Minor mode version of `auto-mode-alist'
(defvar doom-auto-minor-mode-alist '()
"Alist mapping filename patterns to corresponding minor mode functions, like
`auto-mode-alist'. All elements of this alist are checked, meaning you can
enable multiple minor modes for the same regexp.")
(defun doom-enable-minor-mode-maybe-h ()
"Check file name against `doom-auto-minor-mode-alist'."
(when (and buffer-file-name doom-auto-minor-mode-alist)
(let ((name buffer-file-name)
(remote-id (file-remote-p buffer-file-name))
(alist doom-auto-minor-mode-alist))
;; Remove backup-suffixes from file name.
(setq name (file-name-sans-versions name))
;; Remove remote file name identification.
(when (and (stringp remote-id)
(string-match (regexp-quote remote-id) name))
(setq name (substring name (match-end 0))))
(while (and alist (caar alist) (cdar alist))
(if (string-match-p (caar alist) name)
(funcall (cdar alist) 1))
(setq alist (cdr alist))))))
(add-hook 'find-file-hook #'doom-enable-minor-mode-maybe-h)
;; ;;
;;; MODE-local-vars-hook ;;; MODE-local-vars-hook
@ -317,7 +339,7 @@ intervals."
(if (not now) (if (not now)
(nconc doom-incremental-packages packages) (nconc doom-incremental-packages packages)
(when packages (when packages
(let ((gc-cons-threshold doom-gc-cons-upper-limit) (let ((gc-cons-threshold most-positive-fixnum)
(reqs (cl-delete-if #'featurep packages)) (reqs (cl-delete-if #'featurep packages))
file-name-handler-alist) file-name-handler-alist)
(when-let (req (if reqs (ignore-errors (pop reqs)))) (when-let (req (if reqs (ignore-errors (pop reqs))))
@ -478,17 +500,13 @@ The overall load order of Doom is as follows:
Module load order is determined by your `doom!' block. See `doom-modules-dirs' 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 for a list of all recognized module trees. Order defines precedence (from most
to least)." to least)."
(add-to-list 'load-path doom-core-dir)
(require 'core-lib)
(when (or force-p (not doom-init-p)) (when (or force-p (not doom-init-p))
(setq doom-init-p t) ; Prevent infinite recursion (setq doom-init-p t)
;; Reset as much state as possible ;; Reset as much state as possible
(setq exec-path doom-site-exec-path (setq exec-path doom--initial-exec-path
load-path doom-site-load-path load-path doom--initial-load-path
process-environment doom-site-process-environment process-environment doom--initial-process-environment)
shell-file-name doom-site-shell-file-name)
;; `doom-autoload-file' tells Emacs where to load all its autoloaded ;; `doom-autoload-file' tells Emacs where to load all its autoloaded
;; functions from. This includes everything in core/autoload/*.el and all ;; functions from. This includes everything in core/autoload/*.el and all
@ -518,26 +536,26 @@ to least)."
(unless noninteractive (unless noninteractive
(doom-load-env-vars doom-env-file))) (doom-load-env-vars doom-env-file)))
(require 'core-modules) ;; In case we want to use package.el's API
(require 'core-os) (with-eval-after-load 'package
(if noninteractive (require 'core-packages)))
(require 'core-cli)
(add-hook 'window-setup-hook #'doom-display-benchmark-h)
(require 'core-keybinds)
(require 'core-ui)
(require 'core-projects)
(require 'core-editor)))
;; ;;
;;; Bootstrap Doom ;;; Bootstrap Doom
(add-to-list 'load-path doom-core-dir)
(require 'core-lib)
(require 'core-modules)
(if noninteractive (require 'core-cli))
(doom-initialize noninteractive) (doom-initialize noninteractive)
(unless noninteractive (unless noninteractive
(add-hook 'window-setup-hook #'doom-display-benchmark-h)
(require 'core-keybinds)
(require 'core-ui)
(require 'core-projects)
(require 'core-editor)
(doom-initialize-modules)) (doom-initialize-modules))
(with-eval-after-load 'package
(require 'core-packages)
(doom-initialize-packages))
(provide 'core) (provide 'core)
;;; core.el ends here ;;; core.el ends here

View file

@ -4,17 +4,19 @@
;; before package and UI initialization happens. ;; before package and UI initialization happens.
;; Defer garbage collection further back in the startup process ;; Defer garbage collection further back in the startup process
(setq gc-cons-threshold 268435456) (setq gc-cons-threshold most-positive-fixnum)
;; Package initialize occurs automatically, before `user-init-file' is ;; In Emacs 27+, package initialization occurs before `user-init-file' is
;; loaded, but after `early-init-file'. Doom handles package ;; loaded, but after `early-init-file'. Doom handles package initialization, so
;; initialization, so we must prevent Emacs from doing it early! ;; we must prevent Emacs from doing it early!
(setq package-enable-at-startup nil) (setq package-enable-at-startup nil)
;; Prevent the glimpse of un-styled Emacs by setting these early. ;; Prevent the glimpse of un-styled Emacs by disable these UI elements early.
(add-to-list 'default-frame-alist '(tool-bar-lines . 0)) (push '(menu-bar-lines . 0) default-frame-alist)
(add-to-list 'default-frame-alist '(menu-bar-lines . 0)) (push '(tool-bar-lines . 0) default-frame-alist)
(add-to-list 'default-frame-alist '(vertical-scroll-bars)) (push '(vertical-scroll-bars) default-frame-alist)
;; One less file to load at startup ;; Resizing the Emacs frame can be a terribly expensive part of changing the
(setq site-run-file nil) ;; font. By inhibiting this, we easily halve startup times with fonts that are
;; larger than the system default.
(setq frame-inhibit-implied-resize t)

64
init.el
View file

@ -27,61 +27,23 @@
;; ;;
;;; License: MIT ;;; License: MIT
(defvar doom-gc-cons-threshold 16777216 ; 16mb (when (version< emacs-version "25.3")
"The default value to use for `gc-cons-threshold'. If you experience freezing, (error "Detected Emacs %s. Doom only supports Emacs 25.3 and higher"
decrease this. If you experience stuttering, increase this.") emacs-version))
(defvar doom-gc-cons-upper-limit 536870912 ; 512mb
"The temporary value for `gc-cons-threshold' to defer it.")
(defvar doom--file-name-handler-alist file-name-handler-alist)
(defun doom-restore-startup-optimizations-h ()
"Resets garbage collection settings to reasonable defaults (a large
`gc-cons-threshold' can cause random freezes otherwise) and resets
`file-name-handler-alist'."
(setq file-name-handler-alist doom--file-name-handler-alist)
;; Do this on idle timer to defer a possible GC pause that could result; also
;; allows deferred packages to take advantage of these optimizations.
(run-with-idle-timer
3 nil
(lambda ()
(setq-default gc-cons-threshold doom-gc-cons-threshold)
;; To speed up minibuffer commands (like helm and ivy), we defer garbage
;; collection while the minibuffer is active.
(defun doom-defer-garbage-collection-h ()
(setq gc-cons-threshold doom-gc-cons-upper-limit))
(defun doom-restore-garbage-collection-h ()
;; Defer it so that commands launched from the minibuffer can enjoy the
;; benefits.
(run-at-time 1 nil (lambda () (setq gc-cons-threshold doom-gc-cons-threshold))))
(add-hook 'minibuffer-setup-hook #'doom-defer-garbage-collection-h)
(add-hook 'minibuffer-exit-hook #'doom-restore-garbage-collection-h)
;; GC all sneaky breeky like
(add-hook 'focus-out-hook #'garbage-collect))))
(if (ignore-errors (or after-init-time noninteractive))
(setq gc-cons-threshold doom-gc-cons-threshold)
;; A big contributor to startup times is garbage collection. We up the gc
;; threshold to temporarily prevent it from running, then reset it later in
;; `doom-restore-startup-optimizations-h'.
(setq gc-cons-threshold doom-gc-cons-upper-limit)
;; 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)
;; Not restoring these to their defaults will cause stuttering/freezes.
(add-hook 'after-init-hook #'doom-restore-startup-optimizations-h))
;; 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))
;; In noninteractive sessions, prioritize non-byte-compiled source files to
;; prevent stale, byte-compiled code from running. However, if you're getting
;; recursive load errors, it may help to set this to nil.
(setq load-prefer-newer noninteractive)
;; A big contributor to startup times is garbage collection. We up the gc
;; threshold to temporarily prevent it from running, then reset it later with
;; `doom-restore-garbage-collection-h'. Not resetting it will cause
;; stuttering/freezes.
(setq gc-cons-threshold most-positive-fixnum)
;; 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
;; to skip the mtime checks on every *.elc file we load.
(setq load-prefer-newer noninteractive)
;; Let 'er rip! ;; Let 'er rip!
(require 'core (concat user-emacs-directory "core/core")) (require 'core (concat user-emacs-directory "core/core"))

View file

@ -19,7 +19,7 @@ you will be prompted to select one.
If there are conflicting keys across the two camps, the built-in ones are If there are conflicting keys across the two camps, the built-in ones are
ignored. This makes it easy to override built-in snippets with private ones." ignored. This makes it easy to override built-in snippets with private ones."
(when (eq this-command 'yas-expand) (when (eq this-command 'yas-expand)
(let* ((gc-cons-threshold doom-gc-cons-upper-limit) (let* ((gc-cons-threshold most-positive-fixnum)
(choices (cl-remove-duplicates choices :test #'+snippets--remove-p))) (choices (cl-remove-duplicates choices :test #'+snippets--remove-p)))
(if (cdr choices) (if (cdr choices)
(cl-loop for fn in (cdr (memq '+snippets-prompt-private yas-prompt-functions)) (cl-loop for fn in (cdr (memq '+snippets-prompt-private yas-prompt-functions))