2017-06-08 11:47:56 +02:00
|
|
|
;;; core.el --- the heart of the beast -*- lexical-binding: t; -*-
|
2017-01-16 23:15:48 -05:00
|
|
|
|
2018-05-19 18:01:49 +02:00
|
|
|
(eval-when-compile
|
2018-06-04 21:13:19 +02:00
|
|
|
(and (version< emacs-version "25")
|
2018-06-12 01:47:43 +02:00
|
|
|
(error "Detected Emacs %s. Doom only supports Emacs 25.1 and higher"
|
|
|
|
emacs-version)))
|
2018-05-19 18:01:49 +02:00
|
|
|
|
2018-06-15 00:25:20 +02:00
|
|
|
(defvar doom-debug-mode (or (getenv "DEBUG") init-file-debug)
|
|
|
|
"If non-nil, all doom functions will be verbose. Set DEBUG=1 in the command
|
|
|
|
line or use --debug-init to enable this.")
|
|
|
|
|
2018-06-12 01:48:09 +02:00
|
|
|
|
|
|
|
;;
|
|
|
|
;; Constants
|
|
|
|
|
|
|
|
(defconst doom-version "2.0.9"
|
2017-02-13 04:53:16 -05:00
|
|
|
"Current version of DOOM emacs.")
|
2016-10-05 12:48:12 +02:00
|
|
|
|
2018-09-07 21:43:32 -04:00
|
|
|
(defconst EMACS26+ (> emacs-major-version 25))
|
|
|
|
(defconst EMACS27+ (> emacs-major-version 26))
|
2018-06-12 01:48:09 +02:00
|
|
|
|
2018-06-08 13:31:45 +02:00
|
|
|
(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)))
|
|
|
|
|
2018-05-14 13:05:33 +02:00
|
|
|
|
2018-04-03 19:46:22 -04:00
|
|
|
;;
|
2018-09-07 21:43:32 -04:00
|
|
|
(defvar doom-emacs-dir user-emacs-directory
|
2018-05-24 11:44:17 +02:00
|
|
|
"The path to this emacs.d directory. Must end in a slash.")
|
2016-10-02 23:25:08 +02:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-core-dir (concat doom-emacs-dir "core/")
|
2018-09-07 21:43:32 -04:00
|
|
|
"The root directory of core Doom files.")
|
2016-10-02 23:25:08 +02:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-modules-dir (concat doom-emacs-dir "modules/")
|
2018-09-07 21:43:32 -04:00
|
|
|
"The root directory for Doom's modules.")
|
2018-02-16 02:02:58 -05:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-local-dir (concat doom-emacs-dir ".local/")
|
2017-04-16 20:36:15 -04:00
|
|
|
"Root directory for local Emacs files. Use this as permanent storage for files
|
|
|
|
that are safe to share across systems (if this config is symlinked across
|
|
|
|
several computers).")
|
2017-03-16 23:38:22 -04:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-etc-dir (concat doom-local-dir "etc/")
|
2017-12-23 14:30:17 -05:00
|
|
|
"Directory for non-volatile storage.
|
2017-12-22 14:48:07 -05:00
|
|
|
|
2017-12-23 14:30:17 -05:00
|
|
|
Use this for files that don't change much, like servers binaries, external
|
|
|
|
dependencies or long-term shared data.")
|
2017-06-11 23:50:50 +02:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-cache-dir (concat doom-local-dir "cache/")
|
2017-12-22 14:48:07 -05:00
|
|
|
"Directory for volatile storage.
|
2017-01-16 23:15:48 -05:00
|
|
|
|
2017-12-23 14:30:17 -05:00
|
|
|
Use this for files that change often, like cache files.")
|
2017-04-16 20:36:15 -04:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-packages-dir (concat doom-local-dir "packages/")
|
2017-04-16 20:36:15 -04:00
|
|
|
"Where package.el and quelpa plugins (and their caches) are stored.")
|
2016-05-23 06:26:28 -04:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-docs-dir (concat doom-emacs-dir "docs/")
|
2018-06-17 21:39:40 +02:00
|
|
|
"Where the Doom manual is stored.")
|
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-private-dir
|
2018-04-03 19:46:22 -04:00
|
|
|
(eval-when-compile
|
2018-06-05 17:20:20 +02:00
|
|
|
(or (getenv "DOOMDIR")
|
|
|
|
(let ((xdg-path
|
2018-05-24 11:49:01 +02:00
|
|
|
(expand-file-name "doom/"
|
|
|
|
(or (getenv "XDG_CONFIG_HOME")
|
|
|
|
"~/.config"))))
|
2018-04-03 19:46:22 -04:00
|
|
|
(if (file-directory-p xdg-path) xdg-path))
|
|
|
|
"~/.doom.d/"))
|
|
|
|
"Where your private customizations are placed. Must end in a slash. Respects
|
|
|
|
XDG directory conventions if ~/.config/doom exists.")
|
2018-04-03 03:07:26 -04:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-autoload-file (concat doom-local-dir "autoloads.el")
|
2018-06-17 21:35:58 +02:00
|
|
|
"Where `doom-reload-doom-autoloads' will generate its core autoloads file.")
|
2018-06-11 23:18:15 +02:00
|
|
|
|
2018-08-12 02:45:28 +02:00
|
|
|
(defvar doom-package-autoload-file (concat doom-local-dir "autoloads.pkg.el")
|
2018-06-17 21:35:58 +02:00
|
|
|
"Where `doom-reload-package-autoloads' will generate its package.el autoloads
|
2018-06-11 23:18:15 +02:00
|
|
|
file.")
|
|
|
|
|
|
|
|
|
|
|
|
;;
|
2018-06-13 22:16:08 +02:00
|
|
|
;; Doom core variables
|
2018-06-11 23:18:15 +02:00
|
|
|
|
|
|
|
(defvar doom-init-p nil
|
|
|
|
"Non-nil if `doom-initialize' has run.")
|
|
|
|
|
|
|
|
(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 can cause problems.")
|
|
|
|
|
|
|
|
(defvar doom-site-load-path load-path
|
|
|
|
"The starting load-path, before it is altered by `doom-initialize'.")
|
|
|
|
|
2018-06-13 22:16:08 +02:00
|
|
|
(defvar doom--last-emacs-file (concat doom-local-dir "emacs-version.el"))
|
|
|
|
(defvar doom--last-emacs-version nil)
|
|
|
|
(defvar doom--refreshed-p nil)
|
|
|
|
(defvar doom--stage 'init)
|
|
|
|
|
2018-06-11 23:18:15 +02:00
|
|
|
|
2018-06-18 14:47:36 +02:00
|
|
|
;;
|
|
|
|
;; Custom error types
|
|
|
|
|
2018-06-20 02:07:12 +02:00
|
|
|
(define-error 'doom-error "Error in Doom Emacs core")
|
2018-06-18 14:47:36 +02:00
|
|
|
(define-error 'doom-hook-error "Error in a Doom startup hook" 'doom-error)
|
2018-06-20 02:07:12 +02:00
|
|
|
(define-error 'doom-autoload-error "Error in an 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)
|
2018-06-18 14:47:36 +02:00
|
|
|
|
|
|
|
|
2018-08-26 00:16:56 +02:00
|
|
|
;;
|
|
|
|
;; Custom hooks
|
|
|
|
|
|
|
|
(defvar doom-init-hook nil
|
|
|
|
"Hooks run after all init.el files are loaded, including your private and all
|
|
|
|
module init.el files, but before their config.el files are loaded.")
|
|
|
|
|
|
|
|
(defvar doom-post-init-hook nil
|
|
|
|
"A list of hooks run when Doom is fully initialized. Fires near the end of
|
|
|
|
`emacs-startup-hook', as late as possible. Guaranteed to run after everything
|
|
|
|
else (except for `window-setup-hook').")
|
|
|
|
|
|
|
|
(defvar doom-reload-hook nil
|
2018-09-07 21:43:32 -04:00
|
|
|
"A list of hooks to run when `doom/reload' is called.")
|
2018-08-26 00:16:56 +02:00
|
|
|
|
|
|
|
(defvar doom-load-theme-hook nil
|
2018-09-07 21:43:32 -04:00
|
|
|
"Hook run after the theme is loaded with `load-theme' or reloaded with
|
|
|
|
`doom/reload-theme'.")
|
2018-08-26 00:16:56 +02:00
|
|
|
|
|
|
|
(defvar doom-exit-window-hook nil
|
2018-09-07 21:43:32 -04:00
|
|
|
"Hook run before `switch-window' or `switch-frame' are called.
|
|
|
|
|
|
|
|
Also see `doom-enter-window-hook'.")
|
2018-08-26 00:16:56 +02:00
|
|
|
|
|
|
|
(defvar doom-enter-window-hook nil
|
2018-09-07 21:43:32 -04:00
|
|
|
"Hook run after `switch-window' or `switch-frame' are called.
|
|
|
|
|
|
|
|
Also see `doom-exit-window-hook'.")
|
2018-08-26 00:16:56 +02:00
|
|
|
|
|
|
|
(defvar doom-exit-buffer-hook nil
|
|
|
|
"Hook run after `switch-to-buffer', `pop-to-buffer' or `display-buffer' are
|
|
|
|
called. The buffer to be switched to is current when these hooks run.
|
|
|
|
|
|
|
|
Also see `doom-enter-buffer-hook'.")
|
|
|
|
|
|
|
|
(defvar doom-enter-buffer-hook nil
|
|
|
|
"Hook run before `switch-to-buffer', `pop-to-buffer' or `display-buffer' are
|
|
|
|
called. The buffer to be switched to is current when these hooks run.
|
|
|
|
|
|
|
|
Also see `doom-exit-buffer-hook'.")
|
|
|
|
|
|
|
|
(defvar doom-inhibit-switch-buffer-hooks nil
|
2018-09-07 21:43:32 -04:00
|
|
|
"Letvar for inhibiting `doom-enter-buffer-hook' and `doom-exit-buffer-hook'.
|
|
|
|
Do not set this directly.")
|
2018-08-26 00:16:56 +02:00
|
|
|
(defvar doom-inhibit-switch-window-hooks nil
|
2018-09-07 21:43:32 -04:00
|
|
|
"Letvar for inhibiting `doom-enter-window-hook' and `doom-exit-window-hook'.
|
|
|
|
Do not set this directly.")
|
2018-08-26 00:16:56 +02:00
|
|
|
|
|
|
|
(defun doom*switch-window-hooks (orig-fn window &optional norecord)
|
|
|
|
(if (or doom-inhibit-switch-window-hooks
|
|
|
|
(null window)
|
|
|
|
(eq window (selected-window))
|
|
|
|
(window-minibuffer-p)
|
|
|
|
(window-minibuffer-p window))
|
|
|
|
(funcall orig-fn window norecord)
|
|
|
|
(let ((doom-inhibit-switch-window-hooks t))
|
|
|
|
(run-hooks 'doom-exit-window-hook)
|
|
|
|
(prog1 (funcall orig-fn window norecord)
|
|
|
|
(with-selected-window window
|
|
|
|
(run-hooks 'doom-enter-window-hook))))))
|
|
|
|
|
|
|
|
(defun doom*switch-buffer-hooks (orig-fn buffer-or-name &rest args)
|
|
|
|
(if (or doom-inhibit-switch-buffer-hooks
|
|
|
|
(eq (get-buffer buffer-or-name) (current-buffer)))
|
|
|
|
(apply orig-fn buffer-or-name args)
|
|
|
|
(let ((doom-inhibit-switch-buffer-hooks t))
|
|
|
|
(run-hooks 'doom-exit-buffer-hook)
|
|
|
|
(prog1 (apply orig-fn buffer-or-name args)
|
|
|
|
(when (buffer-live-p (get-buffer buffer-or-name))
|
|
|
|
(with-current-buffer buffer-or-name
|
|
|
|
(run-hooks 'doom-enter-buffer-hook)))))))
|
|
|
|
|
|
|
|
(defun doom|init-switch-hooks (&optional disable)
|
|
|
|
"Set up enter/exit hooks for windows and buffers.
|
|
|
|
|
|
|
|
See `doom-enter-buffer-hook', `doom-enter-window-hook', `doom-exit-buffer-hook'
|
|
|
|
and `doom-exit-window-hook'."
|
|
|
|
(dolist (spec '((select-window . doom*switch-window-hooks)
|
|
|
|
(switch-to-buffer . doom*switch-buffer-hooks)
|
|
|
|
(display-buffer . doom*switch-buffer-hooks)
|
|
|
|
(pop-to-buffer . doom*switch-buffer-hooks)))
|
|
|
|
(if disable
|
|
|
|
(advice-remove (car spec) (cdr spec))
|
|
|
|
(advice-add (car spec) :around (cdr spec)))))
|
|
|
|
|
|
|
|
(defun doom*load-theme-hooks (theme &rest _)
|
|
|
|
"Set up `doom-load-theme-hook' to run after `load-theme' is called."
|
|
|
|
(setq doom-theme theme)
|
|
|
|
(run-hooks 'doom-load-theme-hook))
|
|
|
|
(advice-add #'load-theme :after #'doom*load-theme-hooks)
|
|
|
|
|
|
|
|
|
2018-06-11 23:18:15 +02:00
|
|
|
;;
|
|
|
|
;; Emacs core configuration
|
2016-05-26 18:51:39 -04:00
|
|
|
|
2017-01-31 18:59:58 -05:00
|
|
|
;; UTF-8 as the default coding system
|
2017-05-19 02:54:31 +02:00
|
|
|
(when (fboundp 'set-charset-priority)
|
|
|
|
(set-charset-priority 'unicode)) ; pretty
|
2016-09-23 16:13:49 +02:00
|
|
|
(prefer-coding-system 'utf-8) ; pretty
|
2016-06-06 23:53:49 -04:00
|
|
|
(set-terminal-coding-system 'utf-8) ; pretty
|
2017-01-31 18:59:58 -05:00
|
|
|
(set-keyboard-coding-system 'utf-8) ; pretty
|
|
|
|
(set-selection-coding-system 'utf-8) ; perdy
|
|
|
|
(setq locale-coding-system 'utf-8) ; please
|
|
|
|
(setq-default buffer-file-coding-system 'utf-8) ; with sugar on top
|
2017-01-16 23:15:48 -05:00
|
|
|
|
2017-02-19 18:11:28 -05:00
|
|
|
(setq-default
|
|
|
|
ad-redefinition-action 'accept ; silence advised function warnings
|
|
|
|
apropos-do-all t ; make `apropos' more useful
|
2018-06-11 23:18:15 +02:00
|
|
|
auto-mode-case-fold nil
|
|
|
|
autoload-compute-prefixes nil
|
2018-05-18 01:21:09 +02:00
|
|
|
debug-on-error doom-debug-mode
|
2018-02-01 19:50:35 -05:00
|
|
|
ffap-machine-p-known 'reject ; don't ping things that look like domain names
|
2017-03-19 22:50:52 -04:00
|
|
|
idle-update-delay 2 ; update ui less often
|
2018-06-11 23:18:15 +02:00
|
|
|
;; be quiet at startup; don't load or display anything unnecessary
|
2018-05-19 23:49:25 +02:00
|
|
|
inhibit-startup-message t
|
|
|
|
inhibit-startup-echo-area-message user-login-name
|
|
|
|
inhibit-default-init t
|
|
|
|
initial-major-mode 'fundamental-mode
|
|
|
|
initial-scratch-message nil
|
2017-02-19 18:11:28 -05:00
|
|
|
;; keep the point out of the minibuffer
|
|
|
|
minibuffer-prompt-properties '(read-only t point-entered minibuffer-avoid-prompt face minibuffer-prompt)
|
2017-04-16 20:36:15 -04:00
|
|
|
;; History & backup settings (save nothing, that's what git is for)
|
2017-02-19 18:11:28 -05:00
|
|
|
auto-save-default nil
|
|
|
|
create-lockfiles nil
|
2018-09-18 11:51:08 -04:00
|
|
|
history-length 500
|
2018-02-01 19:50:35 -05:00
|
|
|
make-backup-files nil ; don't create backup~ files
|
2018-06-11 23:18:15 +02:00
|
|
|
;; byte compilation
|
|
|
|
byte-compile-verbose doom-debug-mode
|
|
|
|
byte-compile-warnings '(not free-vars unresolved noruntime lexical make-local)
|
|
|
|
;; security
|
|
|
|
gnutls-verify-error (not (getenv "INSECURE")) ; you shouldn't use this
|
|
|
|
tls-checktrust gnutls-verify-error
|
|
|
|
tls-program (list "gnutls-cli --x509cafile %t -p %p %h"
|
|
|
|
;; compatibility fallbacks
|
|
|
|
"gnutls-cli -p %p %h"
|
|
|
|
"openssl s_client -connect %h:%p -no_ssl2 -no_ssl3 -ign_eof")
|
2017-04-16 20:36:15 -04:00
|
|
|
;; files
|
|
|
|
abbrev-file-name (concat doom-local-dir "abbrev.el")
|
|
|
|
auto-save-list-file-name (concat doom-cache-dir "autosave")
|
|
|
|
backup-directory-alist (list (cons "." (concat doom-cache-dir "backup/")))
|
2017-11-02 14:17:15 +01:00
|
|
|
mc/list-file (concat doom-etc-dir "mc-lists.el")
|
2018-05-18 01:21:09 +02:00
|
|
|
pcache-directory (concat doom-cache-dir "pcache/")
|
|
|
|
request-storage-directory (concat doom-cache-dir "request")
|
2017-04-16 20:36:15 -04:00
|
|
|
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/")
|
2017-03-27 13:05:01 -04:00
|
|
|
tramp-backup-directory-alist backup-directory-alist
|
2017-04-16 20:36:15 -04:00
|
|
|
tramp-persistency-file-name (concat doom-cache-dir "tramp-persistency.el")
|
|
|
|
url-cache-directory (concat doom-cache-dir "url/")
|
2018-08-02 17:06:30 +02:00
|
|
|
url-configuration-directory (concat doom-etc-dir "url/")
|
2018-09-10 09:01:03 -04:00
|
|
|
gamegrid-user-score-file-directory (concat doom-etc-dir "games/"))
|
2017-05-15 11:18:26 +02:00
|
|
|
|
2018-04-03 16:24:15 -04:00
|
|
|
(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 ()
|
|
|
|
"Check file name against `doom-auto-minor-mode-alist'."
|
|
|
|
(when buffer-file-name
|
|
|
|
(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)
|
2018-06-06 02:38:39 +02:00
|
|
|
(string-match (regexp-quote remote-id) name))
|
2018-04-03 16:24:15 -04:00
|
|
|
(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)
|
|
|
|
|
2018-06-15 14:58:31 +02:00
|
|
|
(defun doom*symbol-file (orig-fn symbol &optional type)
|
|
|
|
"If a `doom-file' symbol property exists on SYMBOL, use that instead of the
|
|
|
|
original value of `symbol-file'."
|
2018-06-20 01:57:57 +02:00
|
|
|
(or (if (symbolp symbol) (get symbol 'doom-file))
|
2018-06-15 14:58:31 +02:00
|
|
|
(funcall orig-fn symbol type)))
|
|
|
|
(advice-add #'symbol-file :around #'doom*symbol-file)
|
|
|
|
|
2018-09-02 17:06:12 +02:00
|
|
|
;; Don't garbage collect to speed up minibuffer commands
|
|
|
|
(defun doom|defer-garbage-collection ()
|
2018-09-03 01:18:52 +02:00
|
|
|
(setq gc-cons-threshold doom-gc-cons-upper-limit))
|
2018-09-02 17:06:12 +02:00
|
|
|
(defun doom|restore-garbage-collection ()
|
|
|
|
(setq gc-cons-threshold doom-gc-cons-threshold))
|
|
|
|
(add-hook 'minibuffer-setup-hook #'doom|defer-garbage-collection)
|
|
|
|
(add-hook 'minibuffer-exit-hook #'doom|restore-garbage-collection)
|
|
|
|
|
2018-04-03 16:24:15 -04:00
|
|
|
|
2018-09-18 11:42:35 -04:00
|
|
|
;;
|
|
|
|
;; Incremental lazy-loading
|
|
|
|
|
|
|
|
(defvar doom-incremental-packages '(t)
|
|
|
|
"A list of packages to load incrementally after startup. Any large packages
|
|
|
|
here may cause noticable 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' from `emacs-startup-hook' or set
|
|
|
|
`doom-incremental-first-idle-timer' to nil.")
|
|
|
|
|
|
|
|
(defvar doom-incremental-first-idle-timer 2
|
|
|
|
"How long (in idle seconds) until incremental loading starts.
|
|
|
|
|
|
|
|
Set this to nil to disable incremental loading.")
|
|
|
|
|
|
|
|
(defvar doom-incremental-idle-timer 1.5
|
|
|
|
"How long (in idle seconds) in between incrementally loading packages.")
|
|
|
|
|
|
|
|
(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)
|
|
|
|
(when packages
|
|
|
|
(let ((gc-cons-threshold doom-gc-cons-upper-limit)
|
|
|
|
file-name-handler-alist)
|
|
|
|
(let* ((reqs (cl-remove-if #'featurep packages))
|
|
|
|
(req (ignore-errors (pop reqs))))
|
|
|
|
(when req
|
|
|
|
(when doom-debug-mode
|
|
|
|
(message "Incrementally loading %s" req))
|
|
|
|
(require req)
|
|
|
|
(when reqs
|
|
|
|
(run-with-idle-timer doom-incremental-idle-timer
|
|
|
|
nil #'doom-load-packages-incrementally
|
|
|
|
reqs t))))))))
|
|
|
|
|
|
|
|
(defun doom|load-packages-incrementally ()
|
|
|
|
"Begin incrementally loading packages in `doom-incremental-packages'.
|
|
|
|
|
|
|
|
If this is a daemon session, load them all immediately instead."
|
|
|
|
(if (daemonp)
|
|
|
|
(mapc #'require (cdr doom-incremental-packages))
|
|
|
|
(when (integerp 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)
|
|
|
|
|
|
|
|
|
2018-05-14 18:40:35 +02:00
|
|
|
;;
|
2018-06-11 23:18:15 +02:00
|
|
|
;; Bootstrap helpers
|
2018-05-14 18:40:35 +02:00
|
|
|
|
2018-06-18 14:47:36 +02:00
|
|
|
(defun doom-try-run-hook (hook)
|
2018-09-07 21:43:32 -04:00
|
|
|
"Run HOOK (a hook function), but handle errors better, to make debugging
|
|
|
|
issues easier.
|
2018-06-18 14:47:36 +02:00
|
|
|
|
|
|
|
Meant to be used with `run-hook-wrapped'."
|
2018-09-18 11:45:13 -04:00
|
|
|
(when doom-debug-mode
|
|
|
|
(message "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)
|
2018-06-18 14:47:36 +02:00
|
|
|
|
2018-06-11 23:18:15 +02:00
|
|
|
(defun doom-ensure-same-emacs-version-p ()
|
2018-06-13 22:16:08 +02:00
|
|
|
"Check if the running version of Emacs has changed and set
|
|
|
|
`doom-emacs-changed-p' if it has."
|
2018-06-11 23:18:15 +02:00
|
|
|
(if (load doom--last-emacs-file 'noerror 'nomessage 'nosuffix)
|
|
|
|
(setq doom-emacs-changed-p
|
|
|
|
(not (equal emacs-version doom--last-emacs-version)))
|
|
|
|
(with-temp-file doom--last-emacs-file
|
|
|
|
(princ `(setq doom--last-emacs-version ,(prin1-to-string emacs-version))
|
|
|
|
(current-buffer))))
|
|
|
|
(cond ((not doom-emacs-changed-p))
|
|
|
|
((y-or-n-p
|
|
|
|
(format
|
|
|
|
(concat "Your version of Emacs has changed from %s to %s, which may cause incompatibility\n"
|
2018-06-13 22:16:08 +02:00
|
|
|
"issues. If you run into errors, run `bin/doom compile :plugins` or reinstall your\n"
|
|
|
|
"plugins to resolve them.\n\n"
|
2018-06-11 23:18:15 +02:00
|
|
|
"Continue?")
|
|
|
|
doom--last-emacs-version
|
|
|
|
emacs-version))
|
|
|
|
(delete-file doom--last-emacs-file))
|
|
|
|
(noninteractive (error "Aborting"))
|
|
|
|
((kill-emacs))))
|
|
|
|
|
2018-08-08 21:43:50 +02:00
|
|
|
(defun doom-ensure-core-directories-exist ()
|
2018-06-11 23:18:15 +02:00
|
|
|
"Make sure all Doom's essential local directories (in and including
|
|
|
|
`doom-local-dir') exist."
|
|
|
|
(dolist (dir (list doom-local-dir doom-etc-dir doom-cache-dir doom-packages-dir))
|
|
|
|
(unless (file-directory-p dir)
|
|
|
|
(make-directory dir t))))
|
|
|
|
|
|
|
|
(defun doom|display-benchmark (&optional return-p)
|
|
|
|
"Display a benchmark, showing number of packages and modules, and how quickly
|
|
|
|
they were loaded at startup.
|
|
|
|
|
|
|
|
If RETURN-P, return the message as a string instead of displaying it."
|
|
|
|
(funcall (if return-p #'format #'message)
|
|
|
|
"Doom loaded %s packages across %d modules in %.03fs"
|
|
|
|
(length package-activated-list)
|
|
|
|
(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|run-all-startup-hooks ()
|
|
|
|
"Run all startup Emacs hooks. Meant to be executed after starting Emacs with
|
|
|
|
-q or -Q, for example:
|
|
|
|
|
|
|
|
emacs -Q -l init.el -f doom|run-all-startup-hooks"
|
2018-08-13 03:45:58 +02:00
|
|
|
(run-hook-wrapped 'after-init-hook #'doom-try-run-hook)
|
|
|
|
(setq after-init-time (current-time))
|
|
|
|
(dolist (hook (list 'delayed-warnings-hook
|
2018-06-19 00:47:20 +02:00
|
|
|
'emacs-startup-hook 'term-setup-hook
|
|
|
|
'window-setup-hook))
|
|
|
|
(run-hook-wrapped hook #'doom-try-run-hook)))
|
2018-05-14 18:40:35 +02:00
|
|
|
|
2018-05-19 23:58:14 +02:00
|
|
|
|
2018-06-11 23:18:15 +02:00
|
|
|
;;
|
|
|
|
;; Bootstrap functions
|
|
|
|
|
2018-08-03 16:16:01 +02:00
|
|
|
(defun doom-initialize (&optional force-p force-load-core-p)
|
2018-06-11 23:18:15 +02:00
|
|
|
"Bootstrap Doom, if it hasn't already (or if FORCE-P is non-nil).
|
|
|
|
|
2018-08-08 21:43:50 +02:00
|
|
|
Loads Doom core files if in an interactive session or FORCE-LOAD-CORE-P is
|
|
|
|
non-nil.
|
|
|
|
|
2018-06-11 23:18:15 +02:00
|
|
|
The bootstrap process involves making sure 1) the essential directories exist,
|
|
|
|
2) the core packages are installed, 3) `doom-autoload-file' and
|
|
|
|
`doom-package-autoload-file' exist and have been loaded, and 4) Doom's core
|
|
|
|
files are loaded.
|
|
|
|
|
|
|
|
If the cache exists, much of this function isn't run, which substantially
|
|
|
|
reduces startup time.
|
|
|
|
|
|
|
|
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-hook'
|
|
|
|
Module config.el files
|
|
|
|
~/.doom.d/config.el
|
2018-09-07 21:43:32 -04:00
|
|
|
`doom-post-init-hook'
|
2018-06-11 23:18:15 +02:00
|
|
|
`after-init-hook'
|
|
|
|
`emacs-startup-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))
|
2018-07-09 15:33:31 +02:00
|
|
|
(setq doom-init-p t) ; Prevent infinite recursion
|
|
|
|
|
2018-06-11 23:18:15 +02:00
|
|
|
;; `doom-autoload-file' tells Emacs where to load all its autoloaded
|
|
|
|
;; functions from. This includes everything in core/autoload/*.el and all
|
|
|
|
;; the autoload files in your enabled modules.
|
|
|
|
(when (or force-p (not (doom-initialize-autoloads doom-autoload-file)))
|
2018-08-08 21:43:50 +02:00
|
|
|
(doom-ensure-core-directories-exist)
|
2018-06-11 23:18:15 +02:00
|
|
|
(doom-ensure-same-emacs-version-p)
|
2018-07-09 15:33:31 +02:00
|
|
|
|
2018-06-11 23:18:15 +02:00
|
|
|
(require 'core-packages)
|
|
|
|
(doom-ensure-packages-initialized force-p)
|
|
|
|
(doom-ensure-core-packages)
|
2018-07-09 15:33:31 +02:00
|
|
|
|
2018-06-11 23:18:15 +02:00
|
|
|
(unless (or force-p noninteractive)
|
|
|
|
(user-error "Your doom autoloads are missing! Run `bin/doom refresh' to regenerate them")))
|
2018-07-09 15:33:31 +02:00
|
|
|
|
|
|
|
;; Loads `doom-package-autoload-file', which loads a concatenated package
|
|
|
|
;; autoloads file and caches `load-path', `auto-mode-alist',
|
|
|
|
;; `Info-directory-list', `doom-disabled-packages' and
|
2018-06-11 23:18:15 +02:00
|
|
|
;; `package-activated-list'. A big reduction in startup time.
|
|
|
|
(unless (or force-p
|
|
|
|
(doom-initialize-autoloads doom-package-autoload-file)
|
|
|
|
noninteractive)
|
|
|
|
(user-error "Your package autoloads are missing! Run `bin/doom refresh' to regenerate them")))
|
2018-07-09 15:33:31 +02:00
|
|
|
|
2018-06-18 12:04:30 +02:00
|
|
|
(require 'core-os)
|
2018-08-03 16:16:01 +02:00
|
|
|
(when (or force-load-core-p (not noninteractive))
|
2018-08-21 04:27:14 +02:00
|
|
|
(add-hook! 'emacs-startup-hook
|
|
|
|
#'(doom|init-switch-hooks doom|display-benchmark))
|
2018-08-08 21:45:07 +02:00
|
|
|
|
2018-06-11 23:18:15 +02:00
|
|
|
(require 'core-ui)
|
|
|
|
(require 'core-editor)
|
|
|
|
(require 'core-projects)
|
|
|
|
(require 'core-keybinds)))
|
2017-06-08 11:47:56 +02:00
|
|
|
|
2018-06-19 17:19:11 +02:00
|
|
|
(defun doom-initialize-autoloads (file)
|
2018-07-09 15:33:31 +02:00
|
|
|
"Tries to load FILE (an autoloads file). Return t on success, throws an error
|
|
|
|
in interactive sessions, nil otherwise (but logs a warning)."
|
2018-06-19 17:19:11 +02:00
|
|
|
(condition-case e
|
|
|
|
(load (file-name-sans-extension file) 'noerror 'nomessage)
|
|
|
|
((debug error)
|
|
|
|
(if noninteractive
|
|
|
|
(message "Autoload file warning: %s -> %s" (car e) (error-message-string e))
|
|
|
|
(signal 'doom-autoload-error (list (file-name-nondirectory file) e))))))
|
|
|
|
|
2018-05-19 16:42:31 +02:00
|
|
|
|
|
|
|
;;
|
|
|
|
;; Bootstrap Doom
|
2018-04-03 22:36:23 -04:00
|
|
|
|
2018-05-19 16:42:31 +02:00
|
|
|
(add-to-list 'load-path doom-core-dir)
|
|
|
|
|
|
|
|
(require 'core-lib)
|
2018-06-11 23:18:15 +02:00
|
|
|
(require 'core-modules)
|
|
|
|
(when noninteractive
|
2018-06-20 12:03:23 +02:00
|
|
|
(require 'core-cli))
|
2018-09-18 11:51:24 -04:00
|
|
|
(after! package
|
|
|
|
(require 'core-packages))
|
2018-05-19 16:42:31 +02:00
|
|
|
|
2018-05-24 19:00:41 +02:00
|
|
|
(doom-initialize noninteractive)
|
2018-06-11 23:18:15 +02:00
|
|
|
(unless noninteractive
|
2018-06-10 17:24:34 +02:00
|
|
|
(doom-initialize-modules))
|
2017-06-08 11:47:56 +02:00
|
|
|
|
2015-06-04 18:23:21 -04:00
|
|
|
(provide 'core)
|
|
|
|
;;; core.el ends here
|