Refactor core & core-lib
And make their tests pass
This commit is contained in:
parent
059ede53b6
commit
62b089ba36
2 changed files with 62 additions and 57 deletions
|
@ -1,8 +1,7 @@
|
|||
;;; core-lib.el -*- lexical-binding: t; -*-
|
||||
|
||||
(let ((load-path doom--initial-load-path))
|
||||
(require 'subr-x)
|
||||
(require 'cl-lib))
|
||||
(require 'cl-lib)
|
||||
(require 'subr-x)
|
||||
|
||||
;; Polyfills
|
||||
(unless EMACS26+
|
||||
|
@ -175,7 +174,7 @@ at the values with which this function was called."
|
|||
"Push VALUES sequentially into PLACE, if they aren't already present.
|
||||
This is a variadic `cl-pushnew'."
|
||||
(let ((var (make-symbol "result")))
|
||||
`(dolist (,var (list ,@values))
|
||||
`(dolist (,var (list ,@values) (with-no-warnings ,place))
|
||||
(cl-pushnew ,var ,place :test #'equal))))
|
||||
|
||||
(defmacro prependq! (sym &rest lists)
|
||||
|
@ -338,7 +337,10 @@ If NOERROR is non-nil, don't throw an error if the file doesn't exist."
|
|||
(setq path (or (dir!)
|
||||
(error "Could not detect path to look for '%s' in"
|
||||
filename))))
|
||||
(let ((file (if path `(expand-file-name ,filename ,path) filename)))
|
||||
(let ((file (if path
|
||||
`(let (file-name-handler-alist)
|
||||
(expand-file-name ,filename ,path))
|
||||
filename)))
|
||||
`(condition-case e
|
||||
(load ,file ,noerror ,(not doom-debug-mode))
|
||||
((debug doom-error) (signal (car e) (cdr e)))
|
||||
|
@ -372,29 +374,29 @@ serve as a predicated alternative to `after!'."
|
|||
(put ',fn 'permanent-local-hook t)
|
||||
(add-hook 'after-load-functions #',fn)))))
|
||||
|
||||
(defmacro defer-feature! (feature &optional mode)
|
||||
"Pretend FEATURE hasn't been loaded yet, until FEATURE-hook is triggered.
|
||||
(defmacro defer-feature! (feature &optional fn)
|
||||
"Pretend FEATURE hasn't been loaded yet, until FEATURE-hook or FN runs.
|
||||
|
||||
Some packages (like `elisp-mode' and `lisp-mode') are loaded immediately at
|
||||
startup, which will prematurely trigger `after!' (and `with-eval-after-load')
|
||||
blocks. To get around this we make Emacs believe FEATURE hasn't been loaded yet,
|
||||
then wait until FEATURE-hook (or MODE-hook, if MODE is provided) is triggered to
|
||||
then wait until FEATURE-hook (or MODE-hook, if FN is provided) is triggered to
|
||||
reverse this and trigger `after!' blocks at a more reasonable time."
|
||||
(let ((advice-fn (intern (format "doom--defer-feature-%s-a" feature)))
|
||||
(mode (or mode feature)))
|
||||
(fn (or fn feature)))
|
||||
`(progn
|
||||
(setq features (delq ',feature features))
|
||||
(advice-add #',mode :before #',advice-fn)
|
||||
(advice-add #',fn :before #',advice-fn)
|
||||
(defun ,advice-fn (&rest _)
|
||||
;; Some plugins (like yasnippet) will invoke a mode early to parse
|
||||
;; Some plugins (like yasnippet) will invoke a fn early to parse
|
||||
;; code, which would prematurely trigger this. In those cases, well
|
||||
;; behaved plugins will use `delay-mode-hooks', which we can check for:
|
||||
(when (and ,(intern (format "%s-hook" mode))
|
||||
(when (and ,(intern (format "%s-hook" fn))
|
||||
(not delay-mode-hooks))
|
||||
;; ...Otherwise, announce to the world this package has been loaded,
|
||||
;; so `after!' handlers can react.
|
||||
(provide ',feature)
|
||||
(advice-remove #',mode #',advice-fn))))))
|
||||
(advice-remove #',fn #',advice-fn))))))
|
||||
|
||||
(defmacro quiet! (&rest forms)
|
||||
"Run FORMS without generating any output.
|
||||
|
|
91
core/core.el
91
core/core.el
|
@ -1,5 +1,16 @@
|
|||
;;; core.el --- the heart of the beast -*- lexical-binding: t; -*-
|
||||
|
||||
(defconst doom-version "2.0.9"
|
||||
"Current version of Doom Emacs.")
|
||||
|
||||
(defconst EMACS26+ (> emacs-major-version 25))
|
||||
(defconst EMACS27+ (> emacs-major-version 26))
|
||||
(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)))
|
||||
|
||||
;;
|
||||
(defvar doom-init-p nil
|
||||
"Non-nil if Doom has been initialized.")
|
||||
|
||||
|
@ -19,18 +30,6 @@ DEBUG envvar will enable this at startup.")
|
|||
"The default value to use for `gc-cons-threshold'. If you experience freezing,
|
||||
decrease this. If you experience stuttering, increase this.")
|
||||
|
||||
;;; Constants
|
||||
(defconst doom-version "2.0.9"
|
||||
"Current version of Doom Emacs.")
|
||||
|
||||
(defconst EMACS26+ (> emacs-major-version 25))
|
||||
(defconst EMACS27+ (> emacs-major-version 26))
|
||||
|
||||
(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)))
|
||||
|
||||
;;; Directories/files
|
||||
(defvar doom-emacs-dir
|
||||
(eval-when-compile (file-truename user-emacs-directory))
|
||||
|
@ -63,9 +62,7 @@ dependencies or long-term shared data. Must end with a slash.")
|
|||
Use this for files that change often, like cache files. Must end with a slash.")
|
||||
|
||||
(defvar doom-elpa-dir (concat doom-local-dir "elpa/")
|
||||
"Where package.el and quelpa plugins (and their caches) are stored.
|
||||
|
||||
Must end with a slash.")
|
||||
"Where package.el plugins (and their caches) are stored. Must end with a slash.")
|
||||
|
||||
(defvar doom-docs-dir (concat doom-emacs-dir "docs/")
|
||||
"Where Doom's documentation files are stored. Must end with a slash.")
|
||||
|
@ -225,8 +222,8 @@ users).")
|
|||
(setq fast-but-imprecise-scrolling t)
|
||||
|
||||
;; Resizing the Emacs frame can be a terribly expensive part of changing the
|
||||
;; font. By inhibiting this, we easily halve startup times with fonts that are
|
||||
;; larger than the system default.
|
||||
;; font. By inhibiting this, we halve startup times, particularly when we use
|
||||
;; fonts that are larger than the system default (which would resize the frame).
|
||||
(setq frame-inhibit-implied-resize t)
|
||||
|
||||
;; Don't ping things that look like domain names.
|
||||
|
@ -323,7 +320,8 @@ 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.")
|
||||
`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
|
||||
"How long (in idle seconds) until incremental loading starts.
|
||||
|
@ -404,7 +402,8 @@ If RETURN-P, return the message as a string instead of displaying it."
|
|||
(- (length load-path) (length doom--initial-load-path))
|
||||
(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))))))
|
||||
(setq doom-init-time
|
||||
(float-time (time-subtract (current-time) before-init-time))))))
|
||||
|
||||
(defun doom-load-autoloads-file (file)
|
||||
"Tries to load FILE (an autoloads file). Return t on success, throws an error
|
||||
|
@ -422,25 +421,28 @@ in interactive sessions, nil otherwise (but logs a warning)."
|
|||
(if (not (file-readable-p file))
|
||||
(unless noerror
|
||||
(signal 'file-error (list "Couldn't read envvar file" file)))
|
||||
(with-temp-buffer
|
||||
(insert-file-contents file)
|
||||
(search-forward "\n\n" nil t)
|
||||
(while (re-search-forward "\n\\([^= \n]+\\)=" nil t)
|
||||
(save-excursion
|
||||
(let ((var (match-string 1))
|
||||
(value (buffer-substring-no-properties
|
||||
(point)
|
||||
(1- (or (when (re-search-forward "^\\([^= ]+\\)=" nil t)
|
||||
(line-beginning-position))
|
||||
(point-max))))))
|
||||
(setenv var value)))))
|
||||
(setq-default
|
||||
exec-path (append (split-string (getenv "PATH")
|
||||
(if IS-WINDOWS ";" ":"))
|
||||
(list exec-directory))
|
||||
shell-file-name (or (getenv "SHELL")
|
||||
shell-file-name))
|
||||
t))
|
||||
(let (vars)
|
||||
(with-temp-buffer
|
||||
(insert-file-contents file)
|
||||
(search-forward "\n\n")
|
||||
(while (re-search-forward "\n\\([^= \n]+\\)=" nil t)
|
||||
(save-excursion
|
||||
(let ((var (match-string 1))
|
||||
(value (buffer-substring-no-properties
|
||||
(point)
|
||||
(1- (or (when (re-search-forward "^\\([^= ]+\\)=" nil t)
|
||||
(line-beginning-position))
|
||||
(point-max))))))
|
||||
(push (cons var value) vars)
|
||||
(setenv var value)))))
|
||||
(when vars
|
||||
(setq-default
|
||||
exec-path (append (split-string (getenv "PATH")
|
||||
(if IS-WINDOWS ";" ":"))
|
||||
(list exec-directory))
|
||||
shell-file-name (or (getenv "SHELL")
|
||||
shell-file-name))
|
||||
(nreverse vars)))))
|
||||
|
||||
(defun doom-initialize (&optional force-p)
|
||||
"Bootstrap Doom, if it hasn't already (or if FORCE-P is non-nil).
|
||||
|
@ -510,9 +512,9 @@ to least)."
|
|||
(require 'core-packages)
|
||||
(doom-initialize-packages)))
|
||||
|
||||
;; Eagerly load these libraries because this module may be loaded in a session
|
||||
;; that hasn't been fully initialized (where autoloads files haven't been
|
||||
;; generated or `load-path' populated).
|
||||
;; 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 'noerror 'nomessage)
|
||||
(file-expand-wildcards (concat doom-core-dir "autoload/*.el")))
|
||||
|
||||
|
@ -533,10 +535,11 @@ to least)."
|
|||
force-p
|
||||
(not doom-interactive-mode))
|
||||
(unless core-autoloads-p
|
||||
(message "Your Doom core autoloads file is missing"))
|
||||
(warn "Your Doom core autoloads file is missing"))
|
||||
(unless pkg-autoloads-p
|
||||
(message "Your package autoloads file is missing"))
|
||||
(user-error "Run `bin/doom refresh' to generate them")))))
|
||||
(warn "Your package autoloads file is missing"))
|
||||
(signal 'doom-autoload-error "Run `bin/doom refresh' to generate them")))
|
||||
t))
|
||||
|
||||
(defun doom-initialize-core ()
|
||||
"Load Doom's core files for an interactive session."
|
||||
|
|
Loading…
Reference in a new issue