Skip to content

Commit 285b460

Browse files
committed
fix: module load order
A mistake in 5a5195b caused modules without an explicit :depth to be loaded in the wrong order (because their final depth wasn't cached correctly, and so were all given a depth of 0, thus falling back on their insertion order, which is precisely what 5a5195b was trying to fix). This commit fixes that and changes the module cache vectors to match the structure of doom-module-context, for consistency. Amend: 5a5195b Fix: #6813 Fix: #6859
1 parent 9f512a6 commit 285b460

File tree

1 file changed

+40
-39
lines changed

1 file changed

+40
-39
lines changed

lisp/doom-modules.el

Lines changed: 40 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -111,38 +111,38 @@ your `doom!' block, a warning is emitted before replacing it with :emacs vc and
111111
;;
112112
;;; `doom-module-context'
113113

114-
(defvar doom-module-context [nil nil nil nil]
114+
(defvar doom--empty-module-context [nil nil nil nil nil nil nil])
115+
116+
(eval-and-compile
117+
(setplist 'doom-module-context '(index 0 initdepth 1 configdepth 2
118+
group 3 name 4 flags 5 features 6)))
119+
(defvar doom-module-context doom--empty-module-context
115120
"A vector describing the module associated it with the active context.
116121
117-
Contains the following: [:GROUP MODULE FLAGS FEATURES]
122+
Contains the following: [INDEX INITDEPTH CONFIGDEPTH :GROUP MODULE FLAGS FEATURES]
118123
119124
Do not directly set this variable, only let-bind it.")
120-
(eval-and-compile
121-
(setplist 'doom-module-context '(group 0 name 1 flags 2 features 3)))
122125

123126
;; DEPRECATED: Remove this when byte-compilation is introduced to Doom core.
124127
(defmacro doom-module--context-field (field) (get 'doom-module-context field))
125128

126129
(defun doom-module-context-get (field &optional context)
127130
"Return the FIELD of CONTEXT.
128131
129-
FIELD should be one of `group', `name', `flags', or `features'.
130-
CONTEXT should be a `doom-module-context' vector. If omitted, defaults to
131-
`doom-module-context'."
132+
FIELD should be one of `index', `initdepth', `configdepth', `group', `name',
133+
`flags', or `features'. CONTEXT should be a `doom-module-context' vector. If
134+
omitted, defaults to `doom-module-context'."
132135
(aref (or context doom-module-context) (get 'doom-module-context field)))
133136

134137
(defun doom-module-context (group &optional name)
135138
"Create a `doom-module-context' from a module by GROUP and NAME.
136139
137140
If NAME is omitted, GROUP is treated as a module key cons cell: (GROUP . NAME)."
138141
(declare (side-effect-free t))
139-
(let* ((key (if name (cons group name) group))
140-
(group (or (car-safe key) key))
141-
(name (cdr-safe key))
142-
(data (or (get group name) doom--empty-module)))
143-
(vector group name
144-
(aref data (doom-module--context-field flags))
145-
(aref data (doom-module--context-field features)))))
142+
(let ((key (if name (cons group name) group)))
143+
(or (get (or (car-safe key) key)
144+
(cdr-safe key))
145+
doom--empty-module-context)))
146146

147147
(defun doom-module-context-key (&optional context)
148148
"Return the module of the active `doom-module-context' as a module key."
@@ -227,27 +227,22 @@ following properties:
227227
228228
If PLIST consists of a single nil, the module is purged from memory instead."
229229
(if (car plist)
230-
(progn
230+
(let* ((depth (ensure-list (or (plist-get plist :depth) 0)))
231+
(idepth (or (cdr depth) (car depth)))
232+
(cdepth (car depth))
233+
(idx (hash-table-count doom-modules)))
231234
;; PERF: Doom caches module index, flags, and features in symbol plists
232235
;; for fast lookups in `modulep!' and elsewhere. plists are lighter
233236
;; and faster than hash tables for datasets this size, and this
234-
;; information is looked up *very* often.
237+
;; information is looked up *very* often. The structure of this cache
238+
;; should match `doom-module-context's.
235239
(put category module
236-
(let ((depth (ensure-list (or (plist-get plist :depth) 0))))
237-
(cl-destructuring-bind (i j)
238-
(with-memoization (get 'doom-modules depth) '(0 0))
239-
(dolist (n (list i j))
240-
(when (> n 999)
241-
;; No one will have more than 999 modules at any single
242-
;; depth enabled, right? ...Right?
243-
(signal 'doom-module-error
244-
(list (cons category module) "Over 999 module limit" n))))
245-
(put 'doom-modules depth (list (1+ i) (1+ j)))
246-
(vector (+ (* (or (cdr depth) (car depth)) 1000) j)
247-
(+ (* (car depth) 1000) i)
248-
(plist-get plist :flags)
249-
(plist-get plist :features)))))
250-
;; But the hash table will always been Doom's formal storage for modules.
240+
(vector idx idepth cdepth
241+
category module
242+
(plist-get plist :flags)
243+
(plist-get plist :features)))
244+
;; The hash table will always been Doom's formal storage for
245+
;; modules.
251246
(puthash (cons category module) plist doom-modules))
252247
(remhash (cons category module) doom-modules)
253248
(cl-remf (symbol-plist category) module)))
@@ -275,13 +270,17 @@ configdepth. See `doom-module-set' for details."
275270
:mindepth 1
276271
:depth 1)))
277272
(hash-table-keys doom-modules))
278-
(let ((idx (if initorder? 1 0)))
273+
(let ((idx (if initorder? 1 2)))
279274
(lambda! ((groupa . namea) (groupb . nameb))
280275
(let ((a (get groupa namea))
281276
(b (get groupb nameb)))
282277
(or (null b)
283-
(if a (< (aref a idx)
284-
(aref b idx)))))))))
278+
(and
279+
a (let ((adepth (aref a idx))
280+
(bdepth (aref b idx)))
281+
(if (= adepth bdepth)
282+
(< (aref a 0) (aref b 0))
283+
(< adepth bdepth))))))))))
285284

286285
(defun doom-module-expand-path (category module &optional file)
287286
"Expands a path to FILE relative to CATEGORY and MODULE.
@@ -447,7 +446,6 @@ to least)."
447446
;; DEPRECATED Remove in 3.0
448447
(define-obsolete-function-alias 'featurep! 'modulep! "3.0.0")
449448

450-
(defvar doom--empty-module [nil nil nil nil])
451449
(defmacro modulep! (category &optional module flag)
452450
"Return t if :CATEGORY MODULE (and +FLAGS) are enabled.
453451
@@ -464,17 +462,20 @@ For more about modules and flags, see `doom!'."
464462
;; PERF: This macro bypasses the module API to spare startup their runtime
465463
;; cost, as `modulep!' gets called *a lot* during startup. In the future,
466464
;; Doom will byte-compile its core files. At that time, we can use it again.
467-
(and (cond (flag (memq flag (aref (or (get category module) doom--empty-module) 2)))
465+
(and (cond (flag (memq flag (aref (or (get category module) doom--empty-module-context)
466+
(doom-module--context-field flags))))
468467
(module (get category module))
469-
(doom-module-context (memq category (aref doom-module-context 2)))
468+
((aref doom-module-context 0)
469+
(memq category (aref doom-module-context
470+
(doom-module--context-field flags))))
470471
((let ((file
471472
;; This must be expanded at the call site, not in
472473
;; `modulep!'s definition, to get the file we want.
473474
(macroexpand '(file!))))
474475
(if-let (module (doom-module-from-path file))
475476
(memq category (aref (or (get (car module) (cdr module))
476-
doom--empty-module)
477-
2))
477+
doom--empty-module-context)
478+
(doom-module--context-field flags)))
478479
(error "(modulep! %s %s %s) couldn't figure out what module it was called from (in %s)"
479480
category module flag file)))))
480481
t))

0 commit comments

Comments
 (0)