Add magic cli.el in modules & refactor module init

Doom now looks for cli.el files in your private directory or modules,
giving them an opportunity to customize the CLI (add commands or
reconfigure existing ones) to suit their purposes.
This commit is contained in:
Henrik Lissner 2020-05-25 03:09:46 -04:00
parent 3a38fc633c
commit cc5f498586
No known key found for this signature in database
GPG key ID: 5F6C0EA160557395
4 changed files with 57 additions and 40 deletions

View file

@ -78,12 +78,21 @@ with a different private module."
(when (or emacsdir doomdir localdir) (when (or emacsdir doomdir localdir)
(load! "core/core.el" user-emacs-directory)) (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) (let (print-level print-gensym print-length)
(condition-case e (condition-case e
(if (null command) (if (null command)
(doom-cli-execute "help") (doom-cli-execute "help")
(let ((start-time (current-time))) (let ((start-time (current-time)))
(and (doom-cli-execute command args) (and (doom-cli-execute command args)
(progn (run-hooks 'doom-cli-post-hook) t)
(print! (success "Finished! (%.4fs)") (print! (success "Finished! (%.4fs)")
(float-time (float-time
(time-subtract (current-time) (time-subtract (current-time)

View file

@ -299,17 +299,14 @@ Some items are not supported by the `nsm.el' module."
(doom-initialize) (doom-initialize)
(doom-initialize-core-modules)) (doom-initialize-core-modules))
(setq doom-modules ',doom-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--) (--run--)
(maphash (lambda (key plist) (maphash (doom-module-loader doom-module-init-file) doom-modules)
(let ((doom--current-module key) (maphash (doom-module-loader doom-module-config-file) doom-modules)
(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)
(run-hook-wrapped 'doom-init-modules-hook #'doom-try-run-hook) (run-hook-wrapped 'doom-init-modules-hook #'doom-try-run-hook)
(doom-run-all-startup-hooks-h))) (doom-run-all-startup-hooks-h)))
(`vanilla-doom ; only Doom core (`vanilla-doom ; only Doom core

View file

@ -30,6 +30,13 @@ commands like `doom-cli-packages-install', `doom-cli-packages-update' and
(defvar doom-auto-discard (getenv "FORCE") (defvar doom-auto-discard (getenv "FORCE")
"If non-nil, discard all local changes while updating.") "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-commands (make-hash-table :test 'equal))
(defvar doom--cli-groups (make-hash-table :test 'equal)) (defvar doom--cli-groups (make-hash-table :test 'equal))
(defvar doom--cli-group nil) (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 additional overhead by being started this way. For the best performance, it is
best to run Doom out of ~/.emacs.d and ~/.doom.d.")) 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) (provide 'core-cli)
;;; core-cli.el ends here ;;; core-cli.el ends here

View file

@ -11,6 +11,19 @@
doom-modules-dir) doom-modules-dir)
"A list of module root directories. Order determines priority.") "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 (defconst doom-obsolete-modules
'((:feature (version-control (:emacs vc) (:ui vc-gutter)) '((:feature (version-control (:emacs vc) (:ui vc-gutter))
(spellcheck (:checkers spell)) (spellcheck (:checkers spell))
@ -78,31 +91,31 @@ before the user's private module.")
(require 'core-projects) (require 'core-projects)
(require 'core-editor)) (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 "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 session of Dooming. Will noop if used more than once, unless FORCE-P is
non-nil." non-nil."
(when (or force-p (not doom-init-modules-p)) (when (or force-p (not doom-init-modules-p))
(setq doom-init-modules-p t (setq doom-init-modules-p t)
doom-modules nil) (doom-log "Initializing core modules")
(with-temp-buffer (doom-initialize-core-modules)
(doom-log "Initializing core modules") (when-let (init-p (load! "init" doom-private-dir t))
(doom-initialize-core-modules) (doom-log "Initializing user config")
(when-let (init-p (load! "init" doom-private-dir t)) (maphash (doom-module-loader doom-module-init-file) doom-modules)
(doom-log "Initializing user config") (run-hook-wrapped 'doom-before-init-modules-hook #'doom-try-run-hook)
(when doom-modules (unless no-config-p
(maphash (lambda (key plist) (maphash (doom-module-loader doom-module-config-file) doom-modules)
(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))
(run-hook-wrapped 'doom-init-modules-hook #'doom-try-run-hook) (run-hook-wrapped 'doom-init-modules-hook #'doom-try-run-hook)
(load! "config" doom-private-dir t) (load! "config" doom-private-dir t)
(load custom-file 'noerror (not doom-debug-mode)))))) (load custom-file 'noerror (not doom-debug-mode))))))