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)
(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)

View file

@ -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

View file

@ -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

View file

@ -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))))))