diff --git a/bin/doom b/bin/doom index 15ca6aaf2..e41248ac7 100755 --- a/bin/doom +++ b/bin/doom @@ -78,12 +78,21 @@ with a different private module." (when (or emacsdir doomdir localdir) (load! "core/core.el" user-emacs-directory)) + ;; Load any the user's private init.el or any cli.el files in modules. This + ;; gives the user (and modules) an opportunity to define their own CLI + ;; commands, or to customize the CLI to better suit them. + (load! doom-module-init-file doom-private-dir t) + (maphash (doom-module-loader doom-cli-file) doom-modules) + (load! doom-cli-file doom-private-dir t) + (run-hooks 'doom-cli-pre-hook) + (let (print-level print-gensym print-length) (condition-case e (if (null command) (doom-cli-execute "help") (let ((start-time (current-time))) (and (doom-cli-execute command args) + (progn (run-hooks 'doom-cli-post-hook) t) (print! (success "Finished! (%.4fs)") (float-time (time-subtract (current-time) diff --git a/core/autoload/debug.el b/core/autoload/debug.el index aaf7f008d..5cfa29d2d 100644 --- a/core/autoload/debug.el +++ b/core/autoload/debug.el @@ -299,17 +299,14 @@ Some items are not supported by the `nsm.el' module." (doom-initialize) (doom-initialize-core-modules)) (setq doom-modules ',doom-modules) + (maphash (lambda (key plist) + (doom-module-put + (car key) (cdr key) + :path (doom-module-locate-path (car key) (cdr key)))) + doom-modules) (--run--) - (maphash (lambda (key plist) - (let ((doom--current-module key) - (doom--current-flags (plist-get plist :flags))) - (load! "init" (doom-module-locate-path (car key) (cdr key)) t))) - doom-modules) - (maphash (lambda (key plist) - (let ((doom--current-module key) - (doom--current-flags (plist-get plist :flags))) - (load! "config" (doom-module-locate-path (car key) (cdr key)) t))) - doom-modules) + (maphash (doom-module-loader doom-module-init-file) doom-modules) + (maphash (doom-module-loader doom-module-config-file) doom-modules) (run-hook-wrapped 'doom-init-modules-hook #'doom-try-run-hook) (doom-run-all-startup-hooks-h))) (`vanilla-doom ; only Doom core diff --git a/core/core-cli.el b/core/core-cli.el index 5f4c9c532..6b2402df0 100644 --- a/core/core-cli.el +++ b/core/core-cli.el @@ -30,6 +30,13 @@ commands like `doom-cli-packages-install', `doom-cli-packages-update' and (defvar doom-auto-discard (getenv "FORCE") "If non-nil, discard all local changes while updating.") +(defvar doom-cli-file "cli" + "The basename of CLI config files for modules. + +These are loaded when a Doom's CLI starts up. There users and modules can define +additional CLI commands, or reconfigure existing ones to better suit their +purpose.") + (defvar doom--cli-commands (make-hash-table :test 'equal)) (defvar doom--cli-groups (make-hash-table :test 'equal)) (defvar doom--cli-group nil) @@ -411,14 +418,5 @@ WARNING: this command exists for convenience and testing. Doom will suffer additional overhead by being started this way. For the best performance, it is best to run Doom out of ~/.emacs.d and ~/.doom.d.")) - -;; -;;; Load user config - -(condition-case-unless-debug e - (load! "init" doom-private-dir t) - (error - (signal 'doom-private-error (list "init.el" e)))) - (provide 'core-cli) ;;; core-cli.el ends here diff --git a/core/core-modules.el b/core/core-modules.el index 43be58de2..7675beaed 100644 --- a/core/core-modules.el +++ b/core/core-modules.el @@ -11,6 +11,19 @@ doom-modules-dir) "A list of module root directories. Order determines priority.") +(defvar doom-module-init-file "init" + "The basename of init files for modules. + +Init files are loaded early, just after Doom core, and before modules' config +files. They are always loaded, even in non-interactive sessions, and before +`doom-before-init-modules-hook'. Related to `doom-module-config-file'.") + +(defvar doom-module-config-file "config" + "The basename of config files for modules. + +Config files are loaded later, and almost always in interactive sessions. These +run before `doom-init-modules-hook'. Relevant to `doom-module-init-file'.") + (defconst doom-obsolete-modules '((:feature (version-control (:emacs vc) (:ui vc-gutter)) (spellcheck (:checkers spell)) @@ -78,31 +91,31 @@ before the user's private module.") (require 'core-projects) (require 'core-editor)) -(defun doom-initialize-modules (&optional force-p) +(defun doom-module-loader (file) + "Return a closure that loads FILE from a module. + +This closure takes two arguments: a cons cell containing (CATEGORY . MODULE) +symbols, and that module's plist." + (declare (pure t) (side-effect-free t)) + (lambda (module plist) + (let ((doom--current-module module) + (doom--current-flags (plist-get plist :flags))) + (load! file (plist-get plist :path) t)))) + +(defun doom-initialize-modules (&optional force-p no-config-p) "Loads the init.el in `doom-private-dir' and sets up hooks for a healthy session of Dooming. Will noop if used more than once, unless FORCE-P is non-nil." (when (or force-p (not doom-init-modules-p)) - (setq doom-init-modules-p t - doom-modules nil) - (with-temp-buffer - (doom-log "Initializing core modules") - (doom-initialize-core-modules) - (when-let (init-p (load! "init" doom-private-dir t)) - (doom-log "Initializing user config") - (when doom-modules - (maphash (lambda (key plist) - (let ((doom--current-module key) - (doom--current-flags (plist-get plist :flags))) - (load! "init" (plist-get plist :path) t))) - doom-modules)) - (run-hook-wrapped 'doom-before-init-modules-hook #'doom-try-run-hook) - (when doom-modules - (maphash (lambda (key plist) - (let ((doom--current-module key) - (doom--current-flags (plist-get plist :flags))) - (load! "config" (plist-get plist :path) t))) - doom-modules)) + (setq doom-init-modules-p t) + (doom-log "Initializing core modules") + (doom-initialize-core-modules) + (when-let (init-p (load! "init" doom-private-dir t)) + (doom-log "Initializing user config") + (maphash (doom-module-loader doom-module-init-file) doom-modules) + (run-hook-wrapped 'doom-before-init-modules-hook #'doom-try-run-hook) + (unless no-config-p + (maphash (doom-module-loader doom-module-config-file) doom-modules) (run-hook-wrapped 'doom-init-modules-hook #'doom-try-run-hook) (load! "config" doom-private-dir t) (load custom-file 'noerror (not doom-debug-mode))))))