refactor(profiles): bootstrap script
- Swap out the funcall+alist lookup for a pcase (which is expanded to a cond, which is is faster and easier to read). - Wrap bootstrap file to $EMACSDIR/profiles/init.el, but byte-compile it to $EMACSDIR/profiles/init.X.el where X is emacs-major-version. - Make doom-profiles-save's second argument optional (defaults to doom-profiles-bootstrap-file). - Make doom-profiles-save throw a error if byte-compilation fails for some reason. - Rename the tempvars to include 'doom' in their name, so debuggers know where they originate.
This commit is contained in:
parent
09d24cd68a
commit
6dffa09c71
3 changed files with 89 additions and 87 deletions
|
@ -81,9 +81,9 @@
|
||||||
;; $XDG_CONFIG_HOME/doom-profiles.el, and ~/.doom-profiles.el. All it
|
;; $XDG_CONFIG_HOME/doom-profiles.el, and ~/.doom-profiles.el. All it
|
||||||
;; needs is for `$DOOMPROFILE' to be set.
|
;; needs is for `$DOOMPROFILE' to be set.
|
||||||
(setenv "DOOMPROFILE" profile)
|
(setenv "DOOMPROFILE" profile)
|
||||||
(or (load (expand-file-name (format "profiles/init.%d" emacs-major-version)
|
(or (load (expand-file-name (format "profiles/init.%d.elc" emacs-major-version)
|
||||||
user-emacs-directory)
|
user-emacs-directory)
|
||||||
'noerror (not init-file-debug) nil 'must-suffix)
|
'noerror (not init-file-debug) 'nosuffix)
|
||||||
(user-error "Profiles not initialized yet; run 'doom sync' first"))))
|
(user-error "Profiles not initialized yet; run 'doom sync' first"))))
|
||||||
|
|
||||||
;; PERF: When `load'ing or `require'ing files, each permutation of
|
;; PERF: When `load'ing or `require'ing files, each permutation of
|
||||||
|
|
|
@ -70,8 +70,8 @@
|
||||||
(dolist (p removed) (print! (item "Removed %S") (car p)))
|
(dolist (p removed) (print! (item "Removed %S") (car p)))
|
||||||
(dolist (p changed) (print! (item "Changed %S") (car p)))
|
(dolist (p changed) (print! (item "Changed %S") (car p)))
|
||||||
(doom-file-write doom-cli-known-profiles-file (list new-profiles) :mode #o600)
|
(doom-file-write doom-cli-known-profiles-file (list new-profiles) :mode #o600)
|
||||||
(doom-profiles-save new-profiles doom-profiles-bootstrap-file)
|
(doom-profiles-save new-profiles)
|
||||||
(print! (success "Regenerated profile init file: %s")
|
(print! (success "Regenerated profile bootstrapper: %s")
|
||||||
(path doom-profiles-bootstrap-file)))))))))
|
(path doom-profiles-bootstrap-file)))))))))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,8 +31,8 @@ files, and will write a summary profiles.el to the first entry in this
|
||||||
variable.")
|
variable.")
|
||||||
|
|
||||||
(defvar doom-profiles-bootstrap-file
|
(defvar doom-profiles-bootstrap-file
|
||||||
(file-name-concat doom-emacs-dir (format "profiles/init.%d.el" emacs-major-version))
|
(file-name-concat doom-emacs-dir (format "profiles/init.el" emacs-major-version))
|
||||||
"Where Doom writes its profile bootstrap script.")
|
"Where Doom writes its interactive profile bootstrap script.")
|
||||||
|
|
||||||
(defvar doom-profile-init-file-name (format "init.%d.el" emacs-major-version)
|
(defvar doom-profile-init-file-name (format "init.%d.el" emacs-major-version)
|
||||||
"TODO")
|
"TODO")
|
||||||
|
@ -150,91 +150,93 @@ is non-nil, refresh the cache."
|
||||||
;; TODO (defun doom-profile-initialize (profile-name &optional ref)
|
;; TODO (defun doom-profile-initialize (profile-name &optional ref)
|
||||||
;; )
|
;; )
|
||||||
|
|
||||||
(defun doom-profiles-save (profiles file)
|
(defun doom-profiles-save (profiles &optional file)
|
||||||
"Generate a profile bootstrapper for Doom to load at startup."
|
"Generate a profile bootstrapper for Doom to load at startup."
|
||||||
|
(unless file
|
||||||
|
(setq file doom-profiles-bootstrap-file))
|
||||||
(doom-file-write
|
(doom-file-write
|
||||||
file `(";; -*- lexical-binding: t; tab-width: 8; -*-\n"
|
file (let ((profilesym (make-symbol "profile"))
|
||||||
";; Updated: " ,(format-time-string "%Y-%m-%d %H:%M:%S") "\n"
|
(deferredsym (make-symbol "deferred-vars")))
|
||||||
";; Generated by 'doom profiles sync' or 'doom sync'.\n"
|
`(";; -*- lexical-binding: t; tab-width: 8; -*-\n"
|
||||||
";; DO NOT EDIT THIS BY HAND!\n"
|
";; Updated: " ,(format-time-string "%Y-%m-%d %H:%M:%S") "\n"
|
||||||
,(format "%S" doom-version)
|
";; Generated by 'doom profiles sync' or 'doom sync'.\n"
|
||||||
(funcall
|
";; DO NOT EDIT THIS BY HAND!\n"
|
||||||
(alist-get
|
,(format "%S" doom-version)
|
||||||
(intern (getenv-internal "DOOMPROFILE"))
|
(pcase (intern (getenv-internal "DOOMPROFILE"))
|
||||||
(list
|
,@(cl-loop
|
||||||
,@(cl-loop
|
for (profile-name . bindings) in profiles
|
||||||
with deferred?
|
for deferred?
|
||||||
= (seq-find (fn! (memq (car-safe %) '(:prepend :prepend? :append :append?)))
|
= (seq-find (fn! (and (memq (car-safe (cdr %)) '(:prepend :prepend? :append :append?))
|
||||||
(mapcar #'cdr profiles))
|
(not (stringp (car-safe %)))))
|
||||||
with deferred-varsym = (make-symbol "deferred-vars")
|
bindings)
|
||||||
for (name . bindings) in profiles
|
collect
|
||||||
collect
|
`(',profile-name
|
||||||
`(cons ',name
|
(let ,(if deferred? '(--deferred-vars--))
|
||||||
(lambda ()
|
,@(cl-loop
|
||||||
(let ,(if deferred? '(--deferred-vars--))
|
for (var . val) in bindings
|
||||||
,@(cl-loop
|
collect
|
||||||
for (var . val) in bindings
|
(pcase (car-safe val)
|
||||||
collect
|
(:path
|
||||||
(pcase (car-safe val)
|
`(,(if (stringp var) 'setenv 'setq)
|
||||||
(:path
|
,var ,(cl-loop with form = `(expand-file-name ,(cadr val) user-emacs-directory)
|
||||||
`(,(if (stringp var) 'setenv 'set)
|
for dir in (cddr val)
|
||||||
',var ,(cl-loop with form = `(expand-file-name ,(cadr val) user-emacs-directory)
|
do (setq form `(expand-file-name ,dir ,form))
|
||||||
for dir in (cddr val)
|
finally return form)))
|
||||||
do (setq form `(expand-file-name ,dir ,form))
|
(:eval
|
||||||
finally return form)))
|
(if (eq var '_)
|
||||||
(:eval
|
(macroexp-progn (cdr val))
|
||||||
(if (eq var '_)
|
`(,(if (stringp var) 'setenv 'setq)
|
||||||
(macroexp-progn (cdr val))
|
,var ,(macroexp-progn (cdr val)))))
|
||||||
`(,(if (stringp var) 'setenv 'set)
|
(:plist
|
||||||
',var ,(macroexp-progn (cdr val)))))
|
`(,(if (stringp var) 'setenv 'setq)
|
||||||
(:plist
|
,var ',(if (stringp var)
|
||||||
`(,(if (stringp var) 'setenv 'set)
|
(prin1-to-string (cadr val))
|
||||||
',var ',(if (stringp var)
|
(cadr val))))
|
||||||
(prin1-to-string (cadr val))
|
((or :prepend :prepend?)
|
||||||
(cadr val))))
|
(if (stringp var)
|
||||||
((or :prepend :prepend?)
|
`(setenv ,var (concat ,val (getenv ,var)))
|
||||||
(if (stringp var)
|
(setq deferred? t)
|
||||||
`(setenv ',var (concat ,val (getenv ,var)))
|
`(push (cons ',var
|
||||||
(setq deferred? t)
|
(lambda ()
|
||||||
`(push (cons ',var
|
(dolist (item (list ,@(cdr val)))
|
||||||
(lambda ()
|
,(if (eq (car val) :append?)
|
||||||
(dolist (item (list ,@(cdr val)))
|
`(add-to-list ',var item)
|
||||||
,(if (eq (car val) :append?)
|
`(push item ,var)))))
|
||||||
`(add-to-list ',var item)
|
--deferred-vars--)))
|
||||||
`(push item ',var)))))
|
((or :append :append?)
|
||||||
--deferred-vars--)))
|
(if (stringp var)
|
||||||
((or :append :append?)
|
`(setenv ,var (concat (getenv ,var) ,val))
|
||||||
(if (stringp var)
|
(setq deferred? t)
|
||||||
`(setenv ,var (concat (getenv ,var) ,val))
|
`(push (cons ',var
|
||||||
(setq deferred? t)
|
(lambda ()
|
||||||
`(push (cons ',var
|
(dolist (item (list ,@(cdr val)))
|
||||||
(lambda ()
|
,(if (eq (car val) :append?)
|
||||||
(dolist (item (list ,@(cdr val)))
|
`(add-to-list ',var item 'append)
|
||||||
,(if (eq (car val) :append?)
|
`(set ',var (append ,var (list item)))))))
|
||||||
`(add-to-list ',var item 'append)
|
--deferred-vars--)))
|
||||||
`(setq ',var (append ',var (list item)))))))
|
(_ `(,(if (stringp var) 'setenv 'setq) ,var ',val))))
|
||||||
--deferred-vars--)))
|
,@(when deferred?
|
||||||
(_ `(,(if (stringp var) 'setenv 'set) ',var ',val))))
|
`((defun --doom-profile-set-deferred-vars-- (_)
|
||||||
,@(when deferred?
|
(dolist (var --deferred-vars--)
|
||||||
`((defun --defer-vars-- (_)
|
(when (boundp (car var))
|
||||||
(dolist (var --deferred-vars--)
|
(funcall (cdr var))
|
||||||
(when (boundp (car var))
|
(setq --deferred-vars-- (delete var --deferred-vars--))))
|
||||||
(funcall (cdr var))
|
(unless --deferred-vars--
|
||||||
(setq --deferred-vars-- (delete var --deferred-vars--))))
|
(remove-hook 'after-load-functions #'--doom-profile-set-deferred-vars--)
|
||||||
(unless --deferred-vars--
|
(unintern '--doom-profile-set-deferred-vars-- obarray)))
|
||||||
(remove-hook 'after-load-functions #'--defer-vars--)
|
(add-hook 'after-load-functions #'--doom-profile-set-deferred-vars--)
|
||||||
(unintern '--defer-vars-- obarray)))
|
(--doom-profile-set-deferred-vars-- nil)))))))))
|
||||||
(add-hook 'after-load-functions #'--defer-vars--)
|
|
||||||
(--defer-vars--))))))))
|
|
||||||
(lambda ()
|
|
||||||
(if (or noninteractive
|
|
||||||
(,(symbol-function #'doom-profiles-bootloadable-p)))
|
|
||||||
(user-error "Failed to find profile: %s" (getenv "DOOMPROFILE"))
|
|
||||||
(user-error "To be a bootloader, Doom must be installed in ~/.config/emacs or ~/.emacs.d"))))))
|
|
||||||
:mode #o600
|
:mode #o600
|
||||||
:printfn #'pp)
|
:printfn #'pp)
|
||||||
(let ((byte-compile-warnings (if init-file-debug byte-compile-warnings)))
|
(print-group!
|
||||||
(print-group! (byte-compile-file file))))
|
(or (let ((byte-compile-warnings (if init-file-debug byte-compile-warnings))
|
||||||
|
(byte-compile-dest-file-function
|
||||||
|
(lambda (_) (format "%s.%d.elc" (file-name-sans-extension file) emacs-major-version))))
|
||||||
|
(byte-compile-file file))
|
||||||
|
;; Do it again? So the errors/warnings are visible?
|
||||||
|
;; (let ((byte-compile-warnings t))
|
||||||
|
;; (byte-compile-file file))
|
||||||
|
(signal 'doom-profile-error (list file "Failed to byte-compile bootstrap file")))))
|
||||||
|
|
||||||
(defun doom-profile-p (profile-name)
|
(defun doom-profile-p (profile-name)
|
||||||
"Return t if PROFILE-NAME is a valid and existing profile."
|
"Return t if PROFILE-NAME is a valid and existing profile."
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue