From 5782c55e52899513f4244ec9a6ba191b3679a5ee Mon Sep 17 00:00:00 2001 From: Case Duckworth Date: Tue, 19 Apr 2022 22:27:03 -0500 Subject: Enhance :straight setup form :straight now takes care of :straight-when, :also-straight, and possibly others, later. --- lisp/+setup.el | 133 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 85 insertions(+), 48 deletions(-) (limited to 'lisp') diff --git a/lisp/+setup.el b/lisp/+setup.el index 7c658b6..975bcde 100644 --- a/lisp/+setup.el +++ b/lisp/+setup.el @@ -23,6 +23,7 @@ (require 'el-patch) (require 'setup) (require 'straight) +(require 'cl-lib) (defun +setup-warn (message &rest args) "Warn the user that something bad happened in `setup'." @@ -66,57 +67,93 @@ If PATH does not exist, abort the evaluation." ;;; Straight.el (with-eval-after-load 'straight - (setup-define :also-straight - (lambda (recipe) `(setup (:straight ,recipe))) - :documentation - "Install RECIPE with `straight-use-package', after loading FEATURE." - :repeatable t - :after-loaded t) - - (defun +setup-straight-shorthand (sexp) - "Shorthand for `:straight' and other local macros." - (let ((recipe (cadr sexp))) - (or (car-safe recipe) recipe))) + (defun setup--straight-handle-arg (arg var) + (cond + ((and (boundp var) (symbol-value var)) t) + ((keywordp arg) (set var t)) + ((functionp arg) (set var nil) (funcall arg)) + ((listp arg) (set var nil) (eval arg :lexical)))) (setup-define :straight - (lambda (recipe) - `(unless (ignore-errors (straight-use-package ',recipe) t) - (+setup-warn ":straight error: %S" ',recipe) - ,(setup-quit))) - :documentation - "Install RECIPE with `straight-use-package'. -This macro can be used as HEAD, and will replace itself with the -first RECIPE's package." - :repeatable t - :shorthand #'+setup-straight-shorthand) - - (setup-define :straight-after - (lambda (recipe feature) - `(with-eval-after-load ,feature - (setup (:straight ,recipe)))) - :indent 1 - :documentation - "Install RECIPE with `straight-use-package', after FEATURE. -This macro can be used as HEAD, and will replace itself with the -first RECIPE's package." - :shorthand #'+setup-straight-shorthand) - - (setup-define :straight-when - (lambda (recipe condition) - `(if ,condition - (unless (ignore-errors (straight-use-package ',recipe) t) - (+setup-warn ":straight error: %S" ',recipe) - ,(setup-quit)) - (message "Setup: :straight-when returned nil %S" ',recipe) - ,(setup-quit))) - :documentation - "Install RECIPE with `straight-use-package' when CONDITION is met. -If CONDITION is false, or if `straight-use-package' fails, stop -evaluating the body. This macro can be used as HEAD, and will -replace itself with the RECIPE's package." - :repeatable 2 + (lambda (recipe &rest predicates) + (let* ((skp (make-symbol "straight-keyword-p")) + (straight-use-p + (cl-every (lambda (f) (setup--straight-handle-arg f skp)) + predicates)) + (form `(unless (and ,straight-use-p + (condition-case e + (straight-use-package ',recipe) + (error + (+setup-warn ":straight error: %S" + ',recipe) + ,(setup-quit)) + (:success t))) +(defun setup--straight-handle-arg (arg var) + (cond + ((and (boundp var) (symbol-value var)) t) + ((keywordp arg) (set var t)) + ((functionp arg) (set var nil) (funcall arg)) + ((listp arg) (set var nil) (eval arg :lexical)))) + +(setup-define :straight + (lambda (recipe &rest predicates) + (let* ((skp (make-symbol "straight-keyword-p")) + (straight-use-p + (cl-every (lambda (f) (setup--straight-handle-arg f skp)) + predicates)) + (form `(unless (and ,straight-use-p + (condition-case e + (straight-use-package ',recipe) + (error + (+setup-warn ":straight error: %S" + ',recipe) + ,(setup-quit)) + (:success t))) + ,(setup-quit)))) + ;; Keyword arguments --- :quit is special and should short-circuit + (if (memq :quit predicates) + (setq form `,(setup-quit)) + ;; Otherwise, handle the rest of them ... + (when-let ((after (cadr (memq :after predicates)))) + (setq form `(with-eval-after-load ,(if (eq after t) + (setup-get 'feature) + after) + ,form)))) + ;; Finally ... + form)) + :documentation "Install RECIPE with `straight-use-package'. +If PREDICATES are given, only install RECIPE if all of them return non-nil. +The following keyword arguments are also recognized: +- :quit --- immediately stop evaluating. Good for commenting. +- :after FEATURE --- only install RECIPE after FEATURE is loaded. + If FEATURE is t, install RECIPE after the current feature." + :repeatable nil + :indent 1 + :shorthand (lambda (sexp) + (let ((recipe (cadr sexp))) + (or (car-safe recipe) recipe)))) ,(setup-quit)))) + ;; Keyword arguments --- :quit is special and should short-circuit + (if (memq :quit predicates) + (setq form `,(setup-quit)) + ;; Otherwise, handle the rest of them ... + (when-let ((after (cadr (memq :after predicates)))) + (setq form `(with-eval-after-load ,(if (eq after t) + (setup-get 'feature) + after) + ,form)))) + ;; Finally ... + form)) + :documentation "Install RECIPE with `straight-use-package'. +If PREDICATES are given, only install RECIPE if all of them return non-nil. +The following keyword arguments are also recognized: +- :quit --- immediately stop evaluating. Good for commenting. +- :after FEATURE --- only install RECIPE after FEATURE is loaded. + If FEATURE is t, install RECIPE after the current feature." + :repeatable nil :indent 1 - :shorthand #'+setup-straight-shorthand)) + :shorthand (lambda (sexp) + (let ((recipe (cadr sexp))) + (or (car-safe recipe) recipe))))) ;;; Redefines of `setup' forms -- cgit 1.4.1-21-gabe81