diff options
Diffstat (limited to 'lisp/+setup.el')
-rw-r--r-- | lisp/+setup.el | 80 |
1 files changed, 29 insertions, 51 deletions
diff --git a/lisp/+setup.el b/lisp/+setup.el index db59223..919e312 100644 --- a/lisp/+setup.el +++ b/lisp/+setup.el | |||
@@ -29,23 +29,37 @@ | |||
29 | "Warn the user that something bad happened in `setup'." | 29 | "Warn the user that something bad happened in `setup'." |
30 | (display-warning 'setup (format message args))) | 30 | (display-warning 'setup (format message args))) |
31 | 31 | ||
32 | (defun +setup-wrap-to-demote-errors (body name) | ||
33 | "Wrap BODY in a `with-demoted-errors' block. | ||
34 | This behavior is prevented if `setup-attributes' contains the | ||
35 | symbol `without-error-demotion'. | ||
36 | |||
37 | This function differs from `setup-wrap-to-demote-errors' in that | ||
38 | it includes the NAME of the setup form in the warning output." | ||
39 | (if (memq 'without-error-demotion setup-attributes) | ||
40 | body | ||
41 | `(with-demoted-errors ,(format "Error in setup form on line %d (%s): %%S" | ||
42 | (line-number-at-pos) | ||
43 | name) | ||
44 | ,body))) | ||
45 | |||
32 | (setup-define :quit | 46 | (setup-define :quit |
33 | 'setup-quit | 47 | 'setup-quit |
34 | :documentation "Quit the current `setup' form. | 48 | :documentation "Quit the current `setup' form. |
35 | Good for commenting.") | 49 | Good for commenting.") |
36 | 50 | ||
37 | (setup-define :face | 51 | (setup-define :face |
38 | (lambda (face spec) | 52 | (lambda (face spec) |
39 | `(custom-set-faces (list ,face ,spec 'now "Customized by `setup'."))) | 53 | `(custom-set-faces (list ,face ,spec 'now "Customized by `setup'."))) |
40 | :documentation "Customize FACE with SPEC using `custom-set-faces'." | 54 | :documentation "Customize FACE with SPEC using `custom-set-faces'." |
41 | :repeatable t) | 55 | :repeatable t) |
42 | 56 | ||
43 | (setup-define :load-after | 57 | (setup-define :load-after |
44 | (lambda (&rest features) | 58 | (lambda (&rest features) |
45 | (let ((body `(require ',(setup-get 'feature)))) | 59 | (let ((body `(require ',(setup-get 'feature)))) |
46 | (dolist (feature (nreverse features)) | 60 | (dolist (feature (nreverse features)) |
47 | (setq body `(with-eval-after-load ',feature ,body))) | 61 | (setq body `(with-eval-after-load ',feature ,body))) |
48 | body)) | 62 | body)) |
49 | :documentation "Load the current feature after FEATURES.") | 63 | :documentation "Load the current feature after FEATURES.") |
50 | 64 | ||
51 | (setup-define :load-from | 65 | (setup-define :load-from |
@@ -88,50 +102,7 @@ If PATH does not exist, abort the evaluation." | |||
88 | ',recipe) | 102 | ',recipe) |
89 | ,(setup-quit)) | 103 | ,(setup-quit)) |
90 | (:success t))) | 104 | (:success t))) |
91 | (defun setup--straight-handle-arg (arg var) | 105 | ,(setup-quit)))) |
92 | (cond | ||
93 | ((and (boundp var) (symbol-value var)) t) | ||
94 | ((keywordp arg) (set var t)) | ||
95 | ((functionp arg) (set var nil) (funcall arg)) | ||
96 | ((listp arg) (set var nil) (eval arg :lexical)))) | ||
97 | |||
98 | (setup-define :straight | ||
99 | (lambda (recipe &rest predicates) | ||
100 | (let* ((skp (make-symbol "straight-keyword-p")) | ||
101 | (straight-use-p | ||
102 | (cl-every (lambda (f) (setup--straight-handle-arg f skp)) | ||
103 | predicates)) | ||
104 | (form `(unless (and ,straight-use-p | ||
105 | (condition-case e | ||
106 | (straight-use-package ',recipe) | ||
107 | (error | ||
108 | (+setup-warn ":straight error: %S" | ||
109 | ',recipe) | ||
110 | ,(setup-quit)) | ||
111 | (:success t))) | ||
112 | ,(setup-quit)))) | ||
113 | ;; Keyword arguments --- :quit is special and should short-circuit | ||
114 | (if (memq :quit predicates) | ||
115 | (setq form `,(setup-quit)) | ||
116 | ;; Otherwise, handle the rest of them ... | ||
117 | (when-let ((after (cadr (memq :after predicates)))) | ||
118 | (setq form `(with-eval-after-load ,(if (eq after t) | ||
119 | (setup-get 'feature) | ||
120 | after) | ||
121 | ,form)))) | ||
122 | ;; Finally ... | ||
123 | form)) | ||
124 | :documentation "Install RECIPE with `straight-use-package'. | ||
125 | If PREDICATES are given, only install RECIPE if all of them return non-nil. | ||
126 | The following keyword arguments are also recognized: | ||
127 | - :quit --- immediately stop evaluating. Good for commenting. | ||
128 | - :after FEATURE --- only install RECIPE after FEATURE is loaded. | ||
129 | If FEATURE is t, install RECIPE after the current feature." | ||
130 | :repeatable nil | ||
131 | :indent 1 | ||
132 | :shorthand (lambda (sexp) | ||
133 | (let ((recipe (cadr sexp))) | ||
134 | (or (car-safe recipe) recipe)))) ,(setup-quit)))) | ||
135 | ;; Keyword arguments --- :quit is special and should short-circuit | 106 | ;; Keyword arguments --- :quit is special and should short-circuit |
136 | (if (memq :quit predicates) | 107 | (if (memq :quit predicates) |
137 | (setq form `,(setup-quit)) | 108 | (setq form `,(setup-quit)) |
@@ -155,6 +126,13 @@ The following keyword arguments are also recognized: | |||
155 | (let ((recipe (cadr sexp))) | 126 | (let ((recipe (cadr sexp))) |
156 | (or (car-safe recipe) recipe))))) | 127 | (or (car-safe recipe) recipe))))) |
157 | 128 | ||
129 | (setup-define :needs | ||
130 | (lambda (executable) | ||
131 | `(unless (executable-find ,executable) | ||
132 | ,(setup-quit))) | ||
133 | :documentation "If EXECUTABLE is not in the path, stop here." | ||
134 | :repeatable 1) | ||
135 | |||
158 | 136 | ||
159 | ;;; Redefines of `setup' forms | 137 | ;;; Redefines of `setup' forms |
160 | 138 | ||