From 15904349cfb1fb920a0b275850859dda701186bc Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sat, 19 Oct 2024 15:29:56 -0400 Subject: [PATCH] refactor!: module API BREAKING CHANGE: This backports some architectural choices from v3.0. This changes Doom's module API, renaming some functions and removing others, in order to facilitate some new features, prepare to move Doom's modules into separate repos, and make way for two, much larger breaking commits coming in the next few days. This commit won't break anything for users unless they're tinkering with Doom's internals/using its `doom-module-*` API directly. I am avoiding broader backwards incompatibilities until the 3.0 release. What's new: - Negated flags. (modulep! :editor evil -everywhere) will return non-nil if :editor evil is active without its +everywhere flag. - `modulep!` now takes multiple flags to simplify AND checks. E.g. (and (modulep! +foo) (modulep! +bar) (not (modulep! +baz))) Can now be expressed with: (modulep! +foo +bar -baz) - Adds pcase matchers for `doom-module-context` and `doom-module` structs, making the following destructuring binds possible: (pcase-dolist ((doom-module group name flags features) (hash-table-values doom-modules)) ...) This will be used more in v3.0. - Adds file cookie support to module init.el and config.el files. Here's a summary of breaking changes made in this commit: - `doom-module-context` was changed from a vector to a struct (record). - `doom-modules` is now a table of `doom-module` structs, rather than free-form plists. - The following macros have been renamed: - `doom-context-with` -> `with-doom-context` - `doom-module-context-with` -> `with-doom-module` - The followings functions have been replaced/removed: - `doom-module-context`+`doom-module-context-get` -> `doom-module` - `doom-module-set` -> `doom-module--put` - `doom-module-p` -> `doom-module-active-p` - `doom-module-context-key` (is now a getter with the same name) - `doom-module-put` (removed) - `doom-module--context-field` (removed) - The signatures for these functions have changed: - `doom-module-get CATEGORY &optional MODULE PROP` -> `doom-module-get (GROUP . MODULE) &optional PROP` - `doom-module-locate-path CATEGORY &optional MODULE FILE` -> `doom-module-locate-path (GROUP . MODULE) &optional FILE` - `doom-module-expand-path CATEGORY MODULE &optional FILE` -> `doom-module-expand-path (GROUP . MODULE) &optional FILE` - Adds the following functions - `doom-module-exists-p` - `doom-module-key` - `doom-module->context` - `doom-module<-context` - Removes the following variables - `doom-module--empty-context` This commit results in a little redundancy, which I will address in parts 2/3 and/or v3.0. --- bin/doom | 6 +- lisp/cli/doctor.el | 10 +- lisp/doom-cli-lib.el | 2 +- lisp/doom-lib.el | 21 +- lisp/doom-modules.el | 544 +++++++++++++++----------- lisp/doom-packages.el | 10 +- lisp/doom-profiles.el | 58 +-- lisp/doom.el | 2 +- lisp/lib/autoloads.el | 10 +- lisp/lib/config.el | 6 +- lisp/lib/debug.el | 4 +- lisp/lib/files.el | 21 +- lisp/lib/help.el | 9 +- lisp/lib/packages.el | 12 +- lisp/lib/projects.el | 6 +- modules/completion/helm/doctor.el | 2 +- modules/completion/ido/doctor.el | 2 +- modules/completion/ivy/doctor.el | 2 +- modules/completion/vertico/doctor.el | 2 +- modules/editor/evil/init.el | 5 +- modules/lang/emacs-lisp/autoload.el | 4 +- modules/lang/org/autoload/org-link.el | 21 +- modules/lang/org/config.el | 2 +- modules/tools/debugger/config.el | 2 +- 24 files changed, 443 insertions(+), 320 deletions(-) diff --git a/bin/doom b/bin/doom index 3161b0389..a99ea0afa 100755 --- a/bin/doom +++ b/bin/doom @@ -251,7 +251,7 @@ SEE ALSO: ;; Load $DOOMDIR/init.el, to read the user's `doom!' block and give users an ;; opportunity to customize the CLI environment, if they like. Otherwise, they ;; can do so in .doomrc or .doomproject. -(load! doom-module-init-file doom-user-dir t) +(doom-modules-initialize) ;; There are a lot of CLIs, and some have expensive initialization, so best we ;; load them lazily. @@ -297,9 +297,9 @@ SEE ALSO: (let ((cli-file "cli.el")) (defcli-group! "Module commands" - (doom-context-with 'modules + (with-doom-context 'modules (dolist (key (doom-module-list)) - (when-let (path (doom-module-locate-path (car key) (cdr key) cli-file)) + (when-let (path (doom-module-locate-path key cli-file)) (defcli-group! :prefix (if (cdr key) (format "+%s" (cdr key))) (doom-load (file-name-sans-extension path)))))))) diff --git a/lisp/cli/doctor.el b/lisp/cli/doctor.el index b45716e0c..736e65a06 100644 --- a/lisp/cli/doctor.el +++ b/lisp/cli/doctor.el @@ -317,18 +317,18 @@ in." (print! (start "Checking your enabled modules...")) (advice-add #'require :around #'doom-shut-up-a) (pcase-dolist (`(,group . ,name) (doom-module-list)) - (doom-context-with 'doctor + (with-doom-context 'doctor (let (doom-local-errors doom-local-warnings) (let (doom-doctor--errors doom-doctor--warnings) (condition-case-unless-debug ex - (doom-module-context-with (cons group name) - (let ((doctor-file (doom-module-expand-path group name "doctor.el")) - (packages-file (doom-module-expand-path group name doom-module-packages-file))) + (with-doom-module (cons group name) + (let ((doctor-file (doom-module-expand-path (cons group name) "doctor.el")) + (packages-file (doom-module-expand-path (cons group name) doom-module-packages-file))) (when packages-file (cl-loop with doom-output-indent = 6 - for name in (doom-context-with 'packages + for name in (with-doom-context 'packages (let* (doom-packages doom-disabled-packages) (load packages-file 'noerror 'nomessage) diff --git a/lisp/doom-cli-lib.el b/lisp/doom-cli-lib.el index 335039939..4d447fec6 100644 --- a/lisp/doom-cli-lib.el +++ b/lisp/doom-cli-lib.el @@ -1878,7 +1878,7 @@ errors to `doom-cli-error-file')." (when doom-cli--context (error "Cannot nest `run!' calls")) (doom-run-hooks 'doom-after-init-hook) - (doom-context-with 'cli + (with-doom-context 'cli (let* ((args (flatten-list args)) (context (make-doom-cli-context :prefix prefix :whole args)) (doom-cli--context context) diff --git a/lisp/doom-lib.el b/lisp/doom-lib.el index b5561ebf8..848bfc90f 100644 --- a/lisp/doom-lib.el +++ b/lisp/doom-lib.el @@ -51,7 +51,7 @@ (unless absolute? (append (cons '* (remq t (reverse doom-context))) (if (bound-and-true-p doom-module-context) - (let ((key (doom-module-context-key))) + (let ((key (doom-module-context-key doom-module-context))) (delq nil (list (car key) (cdr key))))))) ":") args))) @@ -617,6 +617,25 @@ See `general-key-dispatch' for what other arguments it accepts in BRANCHES." (defalias 'λ! #'cmd!) (defalias 'λ!! #'cmd!!) +(pcase-defmacro doom-struct (type &rest fields) + `(and (pred (cl-struct-p)) + ;; TODO: Support `&rest', `&key', and `&optional' in FIELDS + ,@(mapcar + (lambda (field) + (let ((offset (cl-struct-slot-offset type field))) + `(app (lambda (it) + ,(if offset + `(aref it ,offset) + `(,(intern (format "%s-%s" ',type ',field)) it))) + ,field))) + fields))) + +(pcase-defmacro doom-module-context (&rest fields) + `(doom-struct doom-module-context ,@fields)) + +(pcase-defmacro doom-module (&rest fields) + `(doom-struct doom-module ,@fields)) + ;;; Mutation (defmacro appendq! (sym &rest lists) diff --git a/lisp/doom-modules.el b/lisp/doom-modules.el index de07325d5..3ba902c9b 100644 --- a/lisp/doom-modules.el +++ b/lisp/doom-modules.el @@ -5,8 +5,8 @@ ;; ;;; Variables -(defvar doom-modules (make-hash-table :test 'equal) - "A hash table of enabled modules. Set by `doom-initialize-modules'.") +(defvar doom-modules nil + "A table of enabled modules and metadata. See `doom-modules-initialize'.") (define-obsolete-variable-alias 'doom-modules-dirs 'doom-module-load-path "3.0.0") (defvar doom-module-load-path @@ -120,114 +120,190 @@ your `doom!' block, a warning is emitted before replacing it with :emacs vc and :type 'hook) +;; +;;; Types + +(cl-defstruct doom-module + "TODO" + (index 0 :read-only t) + ;; source + group + name + depth + flags + features + ;; sources + path + ;; disabled-p + ;; frozen-p + ;; layer-p + ;; recipe + ;; alist + ;; package + ;; if + ) + +(cl-defstruct doom-module-context + "Hot cache object for the containing Doom module." + index key path flags features) + + ;; ;;; `doom-module-context' -(defvar doom-module--empty-context [nil nil nil nil nil nil nil]) +(defvar doom-module-context (make-doom-module-context) + "A `doom-module-context' for the module associated with the current file. -(eval-and-compile - (put 'doom-module-context 'keys '(:index 0 :initdepth 1 :configdepth 2 - :group 3 :name 4 :flags 5 :features 6))) -(defvar doom-module-context doom-module--empty-context - "A vector describing the module associated it with the active context. +Never set this variable directly, use `with-doom-module'.") -Contains the following: [INDEX INITDEPTH CONFIGDEPTH :GROUP MODULE FLAGS FEATURES] - -Do not directly set this variable, only let-bind it.") - -;; DEPRECATED: Remove this when byte-compilation is introduced to Doom core. -(defmacro doom-module--context-field (field) - (plist-get (get 'doom-module-context 'keys) field)) - -(defun doom-module-context-get (field &optional context) - "Return the FIELD of CONTEXT. - -FIELD should be one of `index', `initdepth', `configdepth', `group', `name', -`flags', or `features'. CONTEXT should be a `doom-module-context' vector. If -omitted, defaults to `doom-module-context'." - (aref (or context doom-module-context) - (plist-get (get 'doom-module-context 'keys) - field))) - -(defun doom-module-context (group &optional name) - "Create a `doom-module-context' from a module by GROUP and NAME. - -If NAME is omitted, GROUP is treated as a module key cons cell: (GROUP . NAME)." - (declare (side-effect-free t)) - (let ((key (if name (cons group name) group))) - (or (get (or (car-safe key) key) - (cdr-safe key)) - doom-module--empty-context))) - -(defun doom-module-context-key (&optional context) - "Return the module of the active `doom-module-context' as a module key." - (declare (side-effect-free t)) - (let ((context (or context doom-module-context))) - (cons (aref context (doom-module--context-field :group)) - (aref context (doom-module--context-field :name))))) - -(defmacro doom-module-context-with (module-key &rest body) - "Evaluate BODY with `doom-module-context' informed by MODULE-KEY." +(defmacro with-doom-module (key &rest body) + "Evaluate BODY with `doom-module-context' informed by KEY." (declare (indent 1)) - `(let ((doom-module-context (doom-module-context ,module-key))) + `(let ((doom-module-context + (let ((key ,key)) + (cond ((null key) (make-doom-module-context)) + ((doom-module-context-p key) key) + ((doom-module-p key) (doom-module->context key)) + ((doom-module (car key) (cdr key))) + ((doom-module->context key)) + ((error "Invalid module: %S" key)))))) (doom-log ":context:module: =%s" doom-module-context) ,@body)) +(defun doom-module<-context (context) + "Return a `doom-module' plist from CONTEXT." + (declare (side-effect-free t)) + (doom-module-get (doom-module-context-key context))) + +(defun doom-module->context (key) + "Change a `doom-module' into a `doom-module-context'." + (pcase-let + (((doom-module index path flags group name) + (if (doom-module-p key) + key (doom-module-get (doom-module-key key))))) + (make-doom-module-context + :index index + :key (cons group name) + :path path + :flags flags))) + +(defun doom-module (group name &optional property) + "Return the `doom-module-context' for any active module by GROUP NAME. + +Return its PROPERTY, if specified." + (declare (side-effect-free t)) + (when-let ((context (get group name))) + (if property + (aref + context + (or (plist-get + (eval-when-compile + (cl-loop with i = 1 + for info in (cdr (cl-struct-slot-info 'doom-module-context)) + nconc (list (doom-keyword-intern (symbol-name (car info))) + (prog1 i (cl-incf i))))) + property) + (error "Unknown doom-module-context property: %s" property))) + context))) + ;; ;;; Module API -(defun doom-module-p (category module &optional flag) - "Returns t if CATEGORY MODULE is enabled (ie. present in `doom-modules')." +(defun doom-modules-initialize (&optional force?) + "Initializes module metadata." + (when (or (null doom-modules) force?) + (setq doom-modules (make-hash-table :test 'equal)) + ;; Register Doom's two virtual module categories, representing Doom's core + ;; and the user's config; which are always enabled. + (doom-module--put '(:core . nil) :path doom-core-dir :depth -110) + (doom-module--put '(:user . nil) :path doom-user-dir :depth '(-105 . 105)) + ;; DEPRECATED: I intend to phase out our internal usage of `use-package' and + ;; move it to a :config use-package module. The macro is far too complex + ;; and magical for our needs, but until this move is done, ':config + ;; use-package' will remain a hardcoded module for backwards + ;; compatibility. + (doom-module--put '(:config . use-package) + :path (doom-module-locate-path '(:config . use-package)) + :depth -111) + ;; Load $DOOMDIR/init.el, where the user's `doom!' lives, which will inform + ;; us of all desired modules. + (doom-load (file-name-concat doom-user-dir doom-module-init-file) + 'noerror))) + +(defun doom-module-key (key) + "Normalize KEY into a (GROUP . MODULE) tuple representing a Doom module key." (declare (pure t) (side-effect-free t)) - (when-let (plist (gethash (cons category module) doom-modules)) - (or (null flag) - (and (memq flag (plist-get plist :flags)) - t)))) + (cond ((doom-module-p key) + (cons (doom-module-group key) (doom-module-name key))) + ((doom-module-context-p key) + (doom-module-context-key key)) + ((car-safe key) + (if (nlistp (cdr-safe key)) + key + (cons (car key) (cadr key)))) + ((error "Invalid key: %S" key)))) -(defun doom-module-depth (category module &optional initdepth?) - "Return the depth of CATEGORY MODULE. +(defun doom-module--has-flag-p (flags wanted-flags) + "Return t if the list of WANTED-FLAGS satisfies the list of FLAGS." + (declare (pure t) (side-effect-free error-free)) + (cl-loop with flags = (ensure-list flags) + for flag in (ensure-list wanted-flags) + for flagstr = (symbol-name flag) + if (if (eq ?- (aref flagstr 0)) + (memq (intern (concat "+" (substring flagstr 1))) + flags) + (not (memq flag flags))) + return nil + finally return t)) -If INITDEPTH? is non-nil, use the CAR if a module was given two depths (see -`doom-module-set')." - (if-let (depth (doom-module-get category module :depth)) - (or (if initdepth? - (car-safe depth) - (cdr-safe depth)) - depth) - 0)) +(defun doom-module--fold-flags (flags) + "Returns a collapsed list of FLAGS (a list of +/- prefixed symbols). -(defun doom-module-get (category module &optional property) - "Returns the plist for CATEGORY MODULE. Gets PROPERTY, specifically, if set." - (declare (pure t) (side-effect-free t)) - (when-let (plist (gethash (cons category module) doom-modules)) +FLAGS is read in sequence, cancelling out negated flags and removing +duplicates." + (declare (pure t) (side-effect-free error-free)) + (let (newflags) + (while flags + (let* ((flag (car flags)) + (flagstr (symbol-name flag))) + (when-let ((sym (intern-soft + (concat (if (eq ?- (aref flagstr 0)) "+" "-") + (substring flagstr 1))))) + (setq newflags (delq sym newflags))) + (cl-pushnew flag newflags :test 'eq)) + (setq flags (cdr flags))) + (nreverse newflags))) + +(defun doom-module-get (key &optional property) + "Returns the plist for GROUP MODULE. Gets PROPERTY, specifically, if set." + (declare (side-effect-free t)) + (when-let ((m (gethash key doom-modules))) (if property - (plist-get plist property) - plist))) + (aref + m (or (plist-get + (eval-when-compile + (cl-loop with i = 1 + for info in (cdr (cl-struct-slot-info 'doom-module)) + nconc (list (doom-keyword-intern (symbol-name (car info))) + (prog1 i (cl-incf i))))) + property) + (error "Unknown doom-module property: %s" property))) + m))) -(defun doom-module-put (category module &rest plist) - "Set a PROPERTY for CATEGORY MODULE to VALUE. PLIST should be additional pairs -of PROPERTY and VALUEs. +(cl-defun doom-module--put ((group . name) &rest plist) + "Enable GROUP NAME and associate PLIST with it. -\(fn CATEGORY MODULE PROPERTY VALUE &rest [PROPERTY VALUE [...]])" - (puthash (cons category module) - (if-let (old-plist (doom-module-get category module)) - (if (null plist) - old-plist - (when (cl-oddp (length plist)) - (signal 'wrong-number-of-arguments (list (length plist)))) - (while plist - (plist-put old-plist (pop plist) (pop plist))) - old-plist) - plist) - doom-modules)) - -(defun doom-module-set (category module &rest plist) - "Enables a module by adding it to `doom-modules'. - -CATEGORY is a keyword, module is a symbol, PLIST is a plist that accepts the -following properties: +This enables the target module, where GROUP is a keyword, NAME is a symbol, and +PLIST is a property list accepting none, any, or all of the following +properties: + :group KEYWORD + Indicating the group this module is in. This doesn't have to match GROUP, as + it could indicate a module alias. + :name SYMBOL + Indicating the name of this module. This doesn't have to match NAME, as it + could indicate a module alias. :path STRING Path to the directory where this module lives. :depth INT|(INITDEPTH . CONFIGDEPTH) @@ -235,32 +311,66 @@ following properties: order of the module's init.el, while CONFIGDEPTH determines the same for all other config files (config.el, packages.el, doctor.el, etc). :flags (SYMBOL...) - A list of activated flags for this module. + A list of activated flags for this module. Will be collapsed into + pre-existing flags for the module. :features (SYMBOL...) - A list of active features, determined from module's metadata. NOT - IMPLEMENTED YET. + A list of active features, determined from the module's metadata. Will be + collapsed into any pre-existing features for the module. NOT IMPLEMENTED + YET. -If PLIST consists of a single nil, the module is purged from memory instead." - (if (car plist) - (let* ((depth (ensure-list (or (plist-get plist :depth) 0))) - (idepth (or (cdr depth) (car depth))) - (cdepth (car depth)) - (idx (hash-table-count doom-modules))) - ;; PERF: Doom caches module index, flags, and features in symbol plists - ;; for fast lookups in `modulep!' and elsewhere. plists are lighter - ;; and faster than hash tables for datasets this size, and this - ;; information is looked up *very* often. The structure of this cache - ;; should match `doom-module-context's. - (put category module - (vector idx idepth cdepth - category module - (plist-get plist :flags) - (plist-get plist :features))) - ;; The hash table will always been Doom's formal storage for - ;; modules. - (puthash (cons category module) plist doom-modules)) - (remhash (cons category module) doom-modules) - (cl-remf (symbol-plist category) module))) +\(fn (GROUP . NAME) &key GROUP NAME PATH DEPTH FLAGS FEATURES)" + (let ((module + (make-doom-module + :index (hash-table-count doom-modules) + :group (or (plist-get plist :group) group) + :name (or (plist-get plist :name) name) + :path (plist-get plist :path) + :flags (plist-get plist :flags) + :features () ; TODO + :depth + (if (not (plist-member plist :depth)) + '(0 . 0) + (let ((depth (plist-get plist :depth))) + (cl-check-type depth (or integer cons)) + (cond ((integerp depth) (cons depth depth)) + ((consp depth) (cons (or (car depth) 0) + (or (cdr depth) 0))) + ((error "Invalid DEPTH value: %S" depth)))))))) + (doom-log 2 "module-put: %s" module) + (prog1 (puthash (cons group name) module doom-modules) + ;; PERF: Doom caches module index, flags, and features in symbol plists + ;; for fast lookups in `modulep!' and elsewhere. plists are lighter and + ;; faster than hash tables for datasets this size, and this information + ;; is looked up *very* often. + (put group name (doom-module->context module))))) + +(defun doom-module-active-p (group module &optional flags) + "Return t if GROUP MODULE is active, and with FLAGS (if given)." + (declare (side-effect-free t)) + (when-let ((val (doom-module-get (cons group module) (if flags :flags)))) + (or (null flags) + (doom-module--has-flag-p flags val)))) + +(defun doom-module-exists-p (group module) + "Returns t if GROUP MODULE is present in any active source." + (declare (side-effect-free t)) + (if (doom-module-get group module) t)) + +(cl-defun doom-module--depth< (keya keyb &optional initorder?) + "Return t if module with KEY-A comes before another with KEY-B. + +If INITORDER? is non-nil, grab the car of the module's :depth, rather than it's +cdr. See `doom-module-put' for details about the :depth property." + (declare (pure t) (side-effect-free t)) + (let* ((adepth (doom-module-get keya :depth)) + (bdepth (doom-module-get keyb :depth)) + (adepth (if initorder? (car adepth) (cdr adepth))) + (bdepth (if initorder? (car bdepth) (cdr bdepth)))) + (if (or (null adepth) (null bdepth) + (= adepth bdepth)) + (< (or (doom-module-get keya :index) 0) + (or (doom-module-get keyb :index) 0)) + (< adepth bdepth)))) (defun doom-module-list (&optional paths-or-all initorder?) "Return a list of (:group . name) module keys in order of their :depth. @@ -272,8 +382,7 @@ underneath it. If non-nil, return the same, but search `doom-module-load-path' :depth, followed by disabled modules in lexicographical order (unless a :depth is specified in their .doommodule). -If INITORDER? is non-nil, sort modules by their initdepth, rather than their -configdepth. See `doom-module-set' for details." +If INITORDER? is non-nil, sort modules by the CAR of that module's :depth." (sort (if paths-or-all (delete-dups (append (seq-remove #'cdr (doom-module-list nil initorder?)) @@ -285,72 +394,64 @@ configdepth. See `doom-module-set' for details." :mindepth 1 :depth 1))) (hash-table-keys doom-modules)) - (let ((idx (if initorder? 1 2))) - (lambda! ((groupa . namea) (groupb . nameb)) - (let ((a (get groupa namea)) - (b (get groupb nameb))) - (or (null b) - (and - a (let ((adepth (aref a idx)) - (bdepth (aref b idx))) - (if (= adepth bdepth) - (< (aref a 0) (aref b 0)) - (< adepth bdepth)))))))))) + (doom-rpartial #'doom-module--depth< initorder?))) -(defun doom-module-expand-path (category module &optional file) - "Expands a path to FILE relative to CATEGORY and MODULE. +(defun doom-module-expand-path (key &optional file) + "Expands a path to FILE relative to KEY, a cons cell: (GROUP . NAME) -CATEGORY is a keyword. MODULE is a symbol. FILE is an optional string path. -If the category isn't enabled this returns nil. For finding disabled modules use -`doom-module-locate-path'." - (when-let (path (doom-module-get category module :path)) +GROUP is a keyword. MODULE is a symbol. FILE is an optional string path. +If the group isn't enabled this returns nil. For finding disabled modules use +`doom-module-locate-path' instead." + (when-let ((path (doom-module-get key :path))) (if file (file-name-concat path file) path))) -(defun doom-module-locate-path (category &optional module file) - "Searches `doom-module-load-path' to find the path to a module. +(defun doom-module-locate-path (key &optional file) + "Searches `doom-module-load-path' to find the path to a module by KEY. -CATEGORY is a keyword (e.g. :lang) and MODULE is a symbol (e.g. 'python). FILE -is a string that will be appended to the resulting path. If no path exists, this -returns nil, otherwise an absolute path." +KEY is a cons cell (GROUP . NAME), where GROUP is a keyword (e.g. :lang) and +NAME is a symbol (e.g. \\='python). FILE is a string that will be appended to +the resulting path. If said path doesn't exist, this returns nil, otherwise an +absolute path." (let (file-name-handler-alist) - (if-let (path (doom-module-expand-path category module file)) + (if-let ((path (doom-module-expand-path key file))) (if (or (null file) (file-exists-p path)) path) - (let* ((category (doom-keyword-name category)) - (module (if module (symbol-name module))) - (path (file-name-concat category module file))) - (if file - ;; PERF: locate-file-internal is a little faster for finding files, - ;; but its interface for finding directories is clumsy. - (locate-file-internal path doom-module-load-path '("" ".elc" ".el")) - (cl-loop for default-directory in doom-module-load-path - if (file-exists-p path) - return (expand-file-name path))))))) + (cl-destructuring-bind (group . module) (doom-module-key key) + (let* ((group (doom-keyword-name group)) + (module (if module (symbol-name module))) + (path (file-name-concat group module file))) + (if file + ;; PERF: locate-file-internal is a little faster for finding files, + ;; but its interface for finding directories is clumsy. + (locate-file-internal path doom-module-load-path '("" ".elc" ".el")) + (cl-loop for default-directory in doom-module-load-path + if (file-exists-p path) + return (expand-file-name path)))))))) (defun doom-module-locate-paths (module-list file) "Return all existing paths to FILE under each module in MODULE-LIST. MODULE-LIST is a list of cons cells (GROUP . NAME). See `doom-module-list' for an example." - (cl-loop for (group . name) in (or module-list (doom-module-list)) - if (doom-module-locate-path group name file) + (cl-loop for key in (or module-list (doom-module-list)) + if (doom-module-locate-path key file) collect it)) -(defun doom-module-from-path (path &optional enabled-only) - "Returns a cons cell (CATEGORY . MODULE) derived from PATH (a file path). -If ENABLED-ONLY, return nil if the containing module isn't enabled." +(defun doom-module-from-path (path &optional enabled-only?) + "Returns a cons cell (GROUP . NAME) derived from PATH (a file path). +If ENABLED-ONLY?, return nil if the containing module isn't enabled." (let* ((file-name-handler-alist nil) (path (expand-file-name path))) (save-match-data (cond ((string-match "/modules/\\([^/]+\\)/\\([^/]+\\)\\(?:/.*\\)?$" path) - (when-let* ((category (doom-keyword-intern (match-string 1 path))) - (module (intern (match-string 2 path)))) - (and (or (null enabled-only) - (doom-module-p category module)) - (cons category module)))) + (when-let* ((group (doom-keyword-intern (match-string 1 path))) + (name (intern (match-string 2 path)))) + (and (or (null enabled-only?) + (doom-module-active-p group name)) + (cons group name)))) ((string-match (concat "^" (regexp-quote doom-core-dir)) path) (cons :core nil)) ((string-match (concat "^" (regexp-quote doom-user-dir)) path) @@ -363,9 +464,8 @@ The list is in no particular order and its file paths are absolute. If MODULE-DIRS is non-nil, include all modules (even disabled ones) available in those directories." (declare (pure t) (side-effect-free t)) - (cl-loop with module-load-path = (or module-load-path doom-module-load-path) - for (cat . mod) in (doom-module-list module-load-path) - collect (doom-module-locate-path cat mod))) + (mapcar #'doom-module-locate-path + (doom-module-list (or module-load-path doom-module-load-path)))) (defun doom-module-mplist-map (fn mplist) "Apply FN to each module in MPLIST." @@ -373,14 +473,14 @@ those directories." (inhibit-message doom-inhibit-module-warnings) obsolete results - category m) + group m) (while mplist (setq m (pop mplist)) (cond ((keywordp m) - (setq category m + (setq group m obsolete (assq m doom-obsolete-modules))) - ((null category) - (error "No module category specified for %s" m)) + ((null group) + (error "No module group specified for %s" m)) ((and (listp m) (keywordp (car m))) (pcase (car m) (:cond @@ -402,12 +502,12 @@ those directories." (print! (warn "%s module was removed")) (if (cdr newkeys) (print! (warn "%s module was removed and split into the %s modules") - (list category module) + (list group module) (mapconcat #'prin1-to-string newkeys ", ")) (print! (warn "%s module was moved to %s") - (list category module) + (list group module) (car newkeys))) - (push category mplist) + (push group mplist) (dolist (key newkeys) (push (if flags (nconc (cdr key) flags) @@ -415,7 +515,11 @@ those directories." mplist) (push (car key) mplist)) (throw 'doom-modules t)))) - (push (funcall fn category module :flags (if (listp m) (cdr m))) + (doom-log "module: %s %s %s -> %s" group module (or flags "") + (doom-module-locate-path (cons group module))) + (push (funcall fn (cons group module) + :flags (if (listp m) (cdr m)) + :path (doom-module-locate-path (cons group module))) results)))))) (when noninteractive (setq doom-inhibit-module-warnings t)) @@ -433,84 +537,66 @@ those directories." "Bootstraps DOOM Emacs and its modules. If the first item in MODULES doesn't satisfy `keywordp', MODULES is evaluated, -otherwise, MODULES is a multiple-property list (a plist where each key can have -multiple, linear values). +otherwise, MODULES is a variadic-property list (a plist whose key may be +followed by one or more values). -The bootstrap process involves making sure the essential directories exist, core -packages are installed, `doom-autoloads-file' is loaded, `doom-packages-file' -cache exists (and is loaded) and, finally, loads your private init.el (which -should contain your `doom!' block). - -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)." +This macro does nothing in interactive sessions, but in noninteractive session +iterates through MODULES, enabling and initializing them. The order of modules +in these blocks dictates their load order (unless given an explicit :depth)." `(when noninteractive (doom-module-mplist-map - (lambda (category module &rest plist) - (let ((path (doom-module-locate-path category module))) - (unless path - (print! (warn "Failed to locate a '%s %s' module") category module)) - (apply #'doom-module-set category module - :path path - plist))) + #'doom-module--put ,@(if (keywordp (car modules)) (list (list 'quote modules)) modules)) - doom-modules)) + t)) ;; DEPRECATED Remove in 3.0 (define-obsolete-function-alias 'featurep! 'modulep! "3.0.0") -(defmacro modulep! (category &optional module flag) - "Return t if :CATEGORY MODULE (and +FLAGS) are enabled. +(defmacro modulep! (group &optional module &rest flags) + "Return t if :GROUP MODULE (and +FLAGS) are enabled. -If FLAG is provided, returns t if CATEGORY MODULE has FLAG enabled. +If FLAGS is provided, returns t if GROUP MODULE has all of FLAGS enabled. (modulep! :config default +flag) + (modulep! :config default +flag1 +flag2 +flag3) -CATEGORY and MODULE may be omitted when this macro is used from a Doom module's -source (except your DOOMDIR, which is a special module). Like so: +GROUP and MODULE may be omitted when this macro is used from a Doom module's +source (except your $DOOMDIR, which is a special module). Like so: + (modulep! +flag3 +flag1 +flag2) (modulep! +flag) +FLAGS can be negated. E.g. This will return non-nil if ':tools lsp' is enabled +without `+eglot': + + (modulep! :tools lsp -eglot) + +To interpolate dynamic values, use comma: + + (let ((flag '-eglot)) + (modulep! :tools lsp ,flag)) + For more about modules and flags, see `doom!'." - ;; PERF: This macro bypasses the module API to spare startup their runtime - ;; cost, as `modulep!' gets called *a lot* during startup. In the future, - ;; Doom will byte-compile its core files. At that time, we can use it again. - (and (cond (flag (memq flag (aref (or (get category module) doom-module--empty-context) - (doom-module--context-field :flags)))) - (module (get category module)) - ((aref doom-module-context 0) - (memq category (aref doom-module-context - (doom-module--context-field :flags)))) - ((let ((file - ;; This must be expanded at the call site, not in - ;; `modulep!'s definition, to get the file we want. - (macroexpand '(file!)))) - (if-let (module (doom-module-from-path file)) - (memq category (aref (or (get (car module) (cdr module)) - doom-module--empty-context) - (doom-module--context-field :flags))) - (error "(modulep! %s %s %s) couldn't figure out what module it was called from (in %s)" - category module flag file))))) - t)) - - -;; -;;; Defaults - -;; Register Doom's two virtual module categories, representing Doom's core and -;; the user's config; which are always enabled. -(doom-module-set :core nil :path doom-core-dir :depth -110) -(doom-module-set :user nil :path doom-user-dir :depth '(-105 . 105)) - -;; DEPRECATED: I intend to phase out our internal usage of `use-package' and -;; move it to a :config use-package module. The macro is far too complex and -;; magical for our needs, but until this move is done, ':config use-package' -;; will remain a hardcoded module for backwards compatibility. -(doom-module-set :config 'use-package - :path (doom-module-locate-path :config 'use-package) - :depth -111) + (if (keywordp group) + (if flags + `(doom-module--has-flag-p + (doom-module (backquote ,group) (backquote ,module) :flags) + (backquote ,flags)) + `(and (get (backquote ,group) (backquote ,module)) t)) + (let ((flags (delq nil (cons group (cons module flags))))) + (if (doom-module-context-index doom-module-context) + `(doom-module--has-flag-p + ',(doom-module-context-flags doom-module-context) + (backquote ,flags)) + `(let ((file (file!))) + (if-let ((module (doom-module-from-path file))) + (doom-module--has-flag-p + (doom-module (car module) (cdr module) :flags) + (backquote ,flags)) + (error "(modulep! %s) couldn't resolve current module from %s" + (backquote ,flags) (abbreviate-file-name file)))))))) (provide 'doom-modules) ;;; doom-modules.el ends here diff --git a/lisp/doom-packages.el b/lisp/doom-packages.el index a807cc99e..376ea7216 100644 --- a/lisp/doom-packages.el +++ b/lisp/doom-packages.el @@ -431,13 +431,13 @@ installed." (push (cons name (plist-put plist :modules - (list (doom-module-context-key)))) + (list (doom-module-context-key doom-module-context)))) doom-packages))))))))) (user-error (user-error (error-message-string e))) (error (signal 'doom-package-error - (list (doom-module-context-key) + (list (doom-module-context-key doom-module-context) file e))))) (defun doom-package-list (&optional module-list) @@ -454,11 +454,11 @@ also be a list of module keys." doom-disabled-packages doom-packages) (letf! (defun read-packages (key) - (doom-module-context-with key + (with-doom-module key (when-let (file (doom-module-locate-path - (car key) (cdr key) doom-module-packages-file)) + key doom-module-packages-file)) (doom-packages--read file nil 'noerror)))) - (doom-context-with 'packages + (with-doom-context 'packages (let ((user? (assq :user module-list))) (when user? ;; We load the private packages file twice to populate diff --git a/lisp/doom-profiles.el b/lisp/doom-profiles.el index 08a064006..89df57272 100644 --- a/lisp/doom-profiles.el +++ b/lisp/doom-profiles.el @@ -389,50 +389,54 @@ Defaults to the profile at `doom-profile-default'." (let* ((init-modules-list (doom-module-list nil t)) (config-modules-list (doom-module-list)) (pre-init-modules - (seq-filter (fn! (<= (doom-module-depth (car %) (cdr %) t) -100)) - (remove '(:user) init-modules-list))) + (seq-filter (fn! (<= (car (doom-module-get % :depth)) -100)) + (remove '(:user . nil) init-modules-list))) (init-modules - (seq-filter (fn! (<= 0 (doom-module-depth (car %) (cdr %) t) 100)) + (seq-filter (fn! (<= 0 (car (doom-module-get % :depth)) 100)) init-modules-list)) (config-modules - (seq-filter (fn! (<= 0 (doom-module-depth (car %) (cdr %)) 100)) + (seq-filter (fn! (<= 0 (cdr (doom-module-get % :depth)) 100)) config-modules-list)) (post-config-modules - (seq-filter (fn! (>= (doom-module-depth (car %) (cdr %)) 100)) + (seq-filter (fn! (>= (cdr (doom-module-get % :depth)) 100)) config-modules-list)) (init-file doom-module-init-file) (config-file doom-module-config-file)) - (letf! ((defun module-loader (group name file &optional noerror) - (doom-module-context-with (cons group name) - `(let ((doom-module-context ,doom-module-context)) - (doom-load - ,(pcase (cons group name) - ('(:core . nil) - `(file-name-concat - doom-core-dir ,(file-name-nondirectory (file-name-sans-extension file)))) - ('(:user . nil) - `(file-name-concat - doom-user-dir ,(file-name-nondirectory (file-name-sans-extension file)))) - (_ (abbreviate-file-name (file-name-sans-extension file)))) - t)))) - (defun module-list-loader (modules file &optional noerror) - (cl-loop for (cat . mod) in modules - if (doom-module-locate-path cat mod file) - collect (module-loader cat mod it noerror)))) + (letf! ((defun module-loader (key file) + (let ((noextfile (file-name-sans-extension file))) + `(with-doom-module ',key + ,(pcase key + ('(:core . nil) + `(doom-load + (file-name-concat + doom-core-dir ,(file-name-nondirectory noextfile)) + t)) + ('(:user . nil) + `(doom-load + (file-name-concat + doom-user-dir ,(file-name-nondirectory noextfile)) + t)) + (_ + (when (doom-file-cookie-p file "if" t) + `(doom-load ,(abbreviate-file-name noextfile) t))))))) + (defun module-list-loader (modules file) + (cl-loop for key in modules + if (doom-module-locate-path key file) + collect (module-loader key it)))) ;; FIX: Same as above (see `doom-profile--generate-init-vars'). `((if (or (doom-context-p 'init) (doom-context-p 'reload)) - (doom-context-with 'modules + (with-doom-context 'modules (set 'doom-modules ',doom-modules) (set 'doom-disabled-packages ',doom-disabled-packages) - ;; Cache module state and flags in symbol plists for quick lookup by - ;; `modulep!' later. + ;; Cache module state and flags in symbol plists for quick lookup + ;; by `modulep!' later. ,@(cl-loop for (category . modules) in (seq-group-by #'car config-modules-list) collect `(setplist ',category (quote ,(cl-loop for (_ . module) in modules - nconc `(,module ,(get category module)))))) + nconc `(,module ,(doom-module->context (cons category module))))))) (let ((old-custom-file custom-file)) ,@(module-list-loader pre-init-modules init-file) (doom-run-hooks 'doom-before-modules-init-hook) @@ -441,7 +445,7 @@ Defaults to the profile at `doom-profile-default'." (doom-run-hooks 'doom-before-modules-config-hook) ,@(module-list-loader config-modules config-file) (doom-run-hooks 'doom-after-modules-config-hook) - ,@(module-list-loader post-config-modules config-file t) + ,@(module-list-loader post-config-modules config-file) (when (eq custom-file old-custom-file) (doom-load custom-file 'noerror))))))))) diff --git a/lisp/doom.el b/lisp/doom.el index 059916e7e..c6d6319e5 100644 --- a/lisp/doom.el +++ b/lisp/doom.el @@ -601,7 +601,7 @@ wasn't active when this was called." (doom-log ":context: -%s %s" context doom-context) (setq doom-context (delq context doom-context)))) -(defmacro doom-context-with (contexts &rest body) +(defmacro with-doom-context (contexts &rest body) "Evaluate BODY with CONTEXTS added to `doom-context'." (declare (indent 1)) `(let ((doom-context doom-context)) diff --git a/lisp/lib/autoloads.el b/lisp/lib/autoloads.el index 6a31f3041..13b65de9c 100644 --- a/lisp/lib/autoloads.el +++ b/lisp/lib/autoloads.el @@ -148,9 +148,13 @@ hoist buggy forms into autoloads.") ;; So `autoload-generate-file-autoloads' knows where to write it (target-buffer (current-buffer)) (module (doom-module-from-path file)) - (generated-autoload-load-name (abbreviate-file-name (file-name-sans-extension file))) - (module-enabled-p (and (doom-module-p (car module) (cdr module)) - (doom-file-cookie-p file "if" t)))) + (generated-autoload-load-name + (abbreviate-file-name (file-name-sans-extension file))) + (module-enabled-p + (and (doom-module-active-p (car module) (cdr module)) + (doom-file-cookie-p file "if" t))) + ;; (load-path (cons doom-modules-dir load-path)) + ) (save-excursion (when module-enabled-p (quiet! (autoload-generate-file-autoloads file target-buffer))) diff --git a/lisp/lib/config.el b/lisp/lib/config.el index 486da1f8d..6ed282826 100644 --- a/lisp/lib/config.el +++ b/lisp/lib/config.el @@ -104,7 +104,7 @@ Runs `doom-after-reload-hook' afterwards." (interactive) (mapc #'require (cdr doom-incremental-packages)) (doom--if-compile doom-reload-command - (doom-context-with '(reload modules) + (with-doom-context '(reload modules) (doom-run-hooks 'doom-before-reload-hook) (doom-load (file-name-concat doom-user-dir doom-module-init-file) t) (with-demoted-errors "PRIVATE CONFIG ERROR: %s" @@ -129,7 +129,7 @@ line." (interactive) (require 'doom-profiles) ;; TODO: Make this more robust - (doom-context-with 'reload + (with-doom-context 'reload (dolist (file (mapcar #'car doom-profile-generators)) (when (string-match-p "/[0-9]+-loaddefs[.-]" file) (load (doom-path doom-profile-dir doom-profile-init-dir-name file) @@ -145,7 +145,7 @@ Doing so from within Emacs will taint your shell environment. An envvar file contains a snapshot of your shell environment, which can be imported into Emacs." (interactive) - (doom-context-with 'reload + (with-doom-context 'reload (let ((default-directory doom-emacs-dir)) (with-temp-buffer (doom-load-envvars-file doom-env-file) diff --git a/lisp/lib/debug.el b/lisp/lib/debug.el index 26005573a..1238ecc7e 100644 --- a/lisp/lib/debug.el +++ b/lisp/lib/debug.el @@ -317,8 +317,8 @@ ready to be pasted in a bug report on github." do (setq lastcat cat) and collect lastcat collect - (let* ((flags (doom-module-get lastcat mod :flags)) - (path (doom-module-get lastcat mod :path)) + (let* ((flags (doom-module-get (cons lastcat mod) :flags)) + (path (doom-module-get (cons lastcat mod) :path)) (module (append (cond ((null path) diff --git a/lisp/lib/files.el b/lisp/lib/files.el index f5a153216..7c154a1ba 100644 --- a/lisp/lib/files.el +++ b/lisp/lib/files.el @@ -144,7 +144,7 @@ MATCH is a string regexp. Only entries that match it will be included." result))) ;;;###autoload -(defun doom-file-cookie-p (file &optional cookie null-value) +(defun doom-file-cookie (file &optional cookie null-value) "Returns the evaluated result of FORM in a ;;;###COOKIE FORM at the top of FILE. @@ -158,11 +158,24 @@ return NULL-VALUE." (insert-file-contents file nil 0 256) (if (re-search-forward (format "^;;;###%s " (regexp-quote (or cookie "if"))) nil t) - (doom-module-context-with (doom-module-from-path file) - (let ((load-file-name file)) - (eval (sexp-at-point) t))) + (sexp-at-point) null-value))) +;;;###autoload +(defun doom-file-cookie-p (file &optional cookie null-value) + "Returns the evaluated result of FORM in a ;;;###COOKIE FORM at the top of +FILE. + +If COOKIE doesn't exist, or cookie isn't within the first 256 bytes of FILE, +return NULL-VALUE." + (let ((sexp (doom-file-cookie file cookie null-value))) + (if (equal sexp null-value) + null-value + (with-temp-buffer + (with-doom-module (doom-module-from-path file) + (let ((load-file-name file)) + (eval (doom-file-cookie file cookie null-value) t))))))) + ;;;###autoload (defmacro file-exists-p! (files &optional directory) "Returns non-nil if the FILES in DIRECTORY all exist. diff --git a/lisp/lib/help.el b/lisp/lib/help.el index 7764cacc7..d8d72ba02 100644 --- a/lisp/lib/help.el +++ b/lisp/lib/help.el @@ -344,10 +344,10 @@ without needing to check if they are available." (defun doom--help-modules-list () (cl-loop for (cat . mod) in (doom-module-list 'all) - for readme-path = (or (doom-module-locate-path cat mod "README.org") - (doom-module-locate-path cat mod)) + for readme-path = (or (doom-module-locate-path (cons cat mod) "README.org") + (doom-module-locate-path (cons cat mod))) for format = (if mod (format "%s %s" cat mod) (format "%s" cat)) - if (doom-module-p cat mod) + if (doom-module-active-p cat mod) collect (list format readme-path) else if (and cat mod) collect (list (propertize format 'face 'font-lock-comment-face) @@ -630,8 +630,7 @@ If prefix arg is present, refresh the cache." (:core doom-core-dir) (:user doom-user-dir) (category - (doom-module-locate-path category - (cdr m))))) + (doom-module-locate-path (cons category (cdr m)))))) (readme-path (expand-file-name "README.org" module-path))) (insert indent) (doom--help-insert-button diff --git a/lisp/lib/packages.el b/lisp/lib/packages.el index c9b9dd9ad..607154820 100644 --- a/lisp/lib/packages.el +++ b/lisp/lib/packages.el @@ -49,8 +49,8 @@ (or buffer-file-name (bound-and-true-p org-src-source-file-name))) (package - (doom-context-with 'packages - (doom-module-context-with (doom-module-from-path buffer-file-name) + (with-doom-context 'packages + (with-doom-module (doom-module-from-path buffer-file-name) (eval (sexp-at-point) t))))) (list :beg beg :end end @@ -164,14 +164,14 @@ each package." (list (intern (car module)) (ignore-errors (intern (cadr module))) current-prefix-arg))) - (mapc (lambda! ((cat . mod)) - (if-let (packages-file (doom-module-locate-path cat mod doom-module-packages-file)) + (mapc (lambda! (key) + (if-let (packages-file (doom-module-locate-path key doom-module-packages-file)) (with-current-buffer (or (get-file-buffer packages-file) (find-file-noselect packages-file)) (doom/bump-packages-in-buffer select) (save-buffer)) - (message "Module %s has no packages.el file" (cons cat mod)))) + (message "Module %s has no packages.el file" key))) (if module (list (cons category module)) (cl-remove-if-not (lambda (m) (eq (car m) category)) @@ -188,7 +188,7 @@ each package." (unless modules (user-error "This package isn't installed by any Doom module")) (dolist (module modules) - (when (doom-module-locate-path (car module) (cdr module) doom-module-packages-file) + (when (doom-module-locate-path module doom-module-packages-file) (doom/bump-module (car module) (cdr module)))))) diff --git a/lisp/lib/projects.el b/lisp/lib/projects.el index 7596f067d..7d023e72e 100644 --- a/lisp/lib/projects.el +++ b/lisp/lib/projects.el @@ -151,7 +151,7 @@ If DIR is not a project, it will be indexed (but not cached)." ;; Intentionally avoid `helm-projectile-find-file', because it runs ;; asynchronously, and thus doesn't see the lexical ;; `default-directory' - (if (doom-module-p :completion 'ivy) + (if (doom-module-active-p :completion 'ivy) #'counsel-projectile-find-file #'projectile-find-file))) ((and (bound-and-true-p ivy-mode) @@ -175,9 +175,9 @@ If DIR is not a project, it will be indexed (but not cached)." "Traverse a file structure starting linearly from DIR." (let ((default-directory (file-truename (expand-file-name dir)))) (call-interactively - (cond ((doom-module-p :completion 'ivy) + (cond ((doom-module-active-p :completion 'ivy) #'counsel-find-file) - ((doom-module-p :completion 'helm) + ((doom-module-active-p :completion 'helm) #'helm-find-files) (#'find-file))))) diff --git a/modules/completion/helm/doctor.el b/modules/completion/helm/doctor.el index ea80e0b8e..dd028c7b8 100644 --- a/modules/completion/helm/doctor.el +++ b/modules/completion/helm/doctor.el @@ -2,6 +2,6 @@ ;;; completion/helm/doctor.el (dolist (module '(ivy ido vertico)) - (when (doom-module-p :completion module) + (when (doom-module-active-p :completion module) (error! "This module is incompatible with :completion %s; disable one or the other" module))) diff --git a/modules/completion/ido/doctor.el b/modules/completion/ido/doctor.el index 9aeb09eb7..b5482033e 100644 --- a/modules/completion/ido/doctor.el +++ b/modules/completion/ido/doctor.el @@ -2,6 +2,6 @@ ;;; completion/ido/doctor.el (dolist (module '(helm ivy vertico)) - (when (doom-module-p :completion module) + (when (doom-module-active-p :completion module) (error! "This module is incompatible with :completion %s; disable one or the other" module))) diff --git a/modules/completion/ivy/doctor.el b/modules/completion/ivy/doctor.el index 771fdeb93..70f48eaf5 100644 --- a/modules/completion/ivy/doctor.el +++ b/modules/completion/ivy/doctor.el @@ -2,6 +2,6 @@ ;;; completion/ivy/doctor.el (dolist (module '(helm ido vertico)) - (when (doom-module-p :completion module) + (when (doom-module-active-p :completion module) (error! "This module is incompatible with :completion %s; disable one or the other" module))) diff --git a/modules/completion/vertico/doctor.el b/modules/completion/vertico/doctor.el index 009c0cbc2..943e12244 100644 --- a/modules/completion/vertico/doctor.el +++ b/modules/completion/vertico/doctor.el @@ -2,7 +2,7 @@ ;;; completion/vertico/doctor.el (dolist (module '(ivy helm ido)) - (when (doom-module-p :completion module) + (when (doom-module-active-p :completion module) (error! "This module is incompatible with :completion %s; disable one or the other" module))) diff --git a/modules/editor/evil/init.el b/modules/editor/evil/init.el index 18dfaa092..8b4776356 100644 --- a/modules/editor/evil/init.el +++ b/modules/editor/evil/init.el @@ -1,4 +1,5 @@ ;;; editor/evil/init.el -*- lexical-binding: t; -*- +;;;###if (modulep! +everywhere) (defvar evil-collection-key-blacklist) @@ -22,9 +23,7 @@ ;; disable modules, and to reduce the effort required to maintain our copy of ;; `evil-collection-list' (now I can just copy it from time to time). -(when (and (not noninteractive) - (not (doom-context-p 'reload)) - (modulep! +everywhere)) +(unless (or noninteractive (doom-context-p 'reload)) (setq evil-collection-company-use-tng (modulep! :completion company +tng)) diff --git a/modules/lang/emacs-lisp/autoload.el b/modules/lang/emacs-lisp/autoload.el index 3b9af8585..8e759f5a2 100644 --- a/modules/lang/emacs-lisp/autoload.el +++ b/modules/lang/emacs-lisp/autoload.el @@ -13,11 +13,11 @@ to a pop up buffer." (debug-on-error t)) (unwind-protect (condition-case-unless-debug e - (doom-module-context-with + (with-doom-module (doom-module-from-path (or (buffer-file-name (buffer-base-buffer)) default-directory)) - (doom-context-with 'eval + (with-doom-context 'eval (eval-region beg end buffer load-read-function)) (with-current-buffer buffer (let ((pp-max-width nil)) diff --git a/modules/lang/org/autoload/org-link.el b/modules/lang/org/autoload/org-link.el index 3ab615248..34ebb2d07 100644 --- a/modules/lang/org/autoload/org-link.el +++ b/modules/lang/org/autoload/org-link.el @@ -157,12 +157,11 @@ exist, and `org-link' otherwise." (cl-destructuring-bind (&key category module flag) (+org-link--read-module-spec module-path) (when category - (let ((doom-modules-dirs (list doom-modules-dir))) - (if-let* ((path (doom-module-locate-path category module)) - (path (or (car (doom-glob path "README.org")) - path))) - (find-file path) - (user-error "Can't find Doom module '%s'" module-path)))) + (if-let* ((path (doom-module-locate-path (cons category module))) + (path (or (car (doom-glob path "README.org")) + path))) + (find-file path) + (user-error "Can't find Doom module '%s'" module-path))) (when flag (goto-char (point-min)) (when (and (re-search-forward "^\\*+ \\(?:TODO \\)?Module flags") @@ -179,13 +178,13 @@ exist, and `org-link' otherwise." (cl-destructuring-bind (&key category module flag) (+org-link--read-module-spec module-path) (let ((overall-face - (if (and category (doom-module-locate-path category module)) + (if (and category (doom-module-locate-path (cons category module))) '((:underline nil) org-link org-block bold) '(shadow org-block bold))) (icon-face (cond - ((doom-module-p category module flag) 'success) - ((and category (doom-module-locate-path category module)) 'warning) + ((doom-module-active-p category module flag) 'success) + ((and category (doom-module-locate-path (cons category module))) 'warning) (t 'error)))) (add-text-properties start end @@ -294,9 +293,9 @@ exist, and `org-link' otherwise." (cl-destructuring-bind (&key category module flag) (+org-link--read-module-spec (org-element-property :path link)) (cond - ((doom-module-p category module) + ((doom-module-active-p category module) (propertize "enabled" 'face 'success)) - ((and category (doom-module-locate-path category module)) + ((and category (doom-module-locate-path (cons category module))) (propertize "disabled" 'face 'error)) (t (propertize "unknown" 'face '(bold error))))))) ("doom-executable" diff --git a/modules/lang/org/config.el b/modules/lang/org/config.el index a373809b6..3c3d558fd 100644 --- a/modules/lang/org/config.el +++ b/modules/lang/org/config.el @@ -1301,7 +1301,7 @@ between the two." )) ;;; Custom org modules - (dolist (flag (doom-module-context-get :flags)) + (dolist (flag (doom-module :lang 'org :flags)) (load! (concat "contrib/" (substring (symbol-name flag) 1)) nil t)) ;; Add our general hooks after the submodules, so that any hooks the diff --git a/modules/tools/debugger/config.el b/modules/tools/debugger/config.el index 5861e261f..4ef38ad27 100644 --- a/modules/tools/debugger/config.el +++ b/modules/tools/debugger/config.el @@ -119,7 +119,7 @@ :config (pcase-dolist (`((,category . ,modules) :after ,after :require ,libs) +debugger--dap-alist) - (when (doom-module-p category (car modules) (cadr modules)) + (when (doom-module-active-p category (car modules) (cadr modules)) (dolist (lib (ensure-list after)) (with-eval-after-load lib (mapc #'require (ensure-list libs))))))