diff options
Diffstat (limited to 'lisp/yoke.el')
-rw-r--r-- | lisp/yoke.el | 66 |
1 files changed, 50 insertions, 16 deletions
diff --git a/lisp/yoke.el b/lisp/yoke.el index 2673e5e..4f40869 100644 --- a/lisp/yoke.el +++ b/lisp/yoke.el | |||
@@ -32,7 +32,7 @@ directory created." | |||
32 | (message "Downloading %S... done" repo)) | 32 | (message "Downloading %S... done" repo)) |
33 | dir)) | 33 | dir)) |
34 | 34 | ||
35 | (defun yoke-lasso (pkg repo) | 35 | (defun yoke-lasso (pkg repo &optional load-path) |
36 | "Add PKG to `load-path' so it can be used. | 36 | "Add PKG to `load-path' so it can be used. |
37 | If PKG is not installed, install it from REPO. Packages will be | 37 | If PKG is not installed, install it from REPO. Packages will be |
38 | installed to `yoke-dir'." | 38 | installed to `yoke-dir'." |
@@ -40,7 +40,8 @@ installed to `yoke-dir'." | |||
40 | (yoke-git repo dir) | 40 | (yoke-git repo dir) |
41 | (cond | 41 | (cond |
42 | ((file-exists-p dir) | 42 | ((file-exists-p dir) |
43 | (add-to-list 'load-path dir) | 43 | (when (or load-path dir) |
44 | (add-to-list 'load-path (expand-file-name (or load-path dir)))) | ||
44 | ;; This bit is stolen from `straight'. | 45 | ;; This bit is stolen from `straight'. |
45 | (eval-and-compile (require 'autoload)) | 46 | (eval-and-compile (require 'autoload)) |
46 | (let ((generated-autoload-file | 47 | (let ((generated-autoload-file |
@@ -91,6 +92,31 @@ Similar-ish to `plist-get', but works on non-proper plists." | |||
91 | (setq list (cdr list))) | 92 | (setq list (cdr list))) |
92 | (reverse r))) | 93 | (reverse r))) |
93 | 94 | ||
95 | (defun eval-after-init (fn) | ||
96 | "Evaluate FN after inititation, or now if Emacs is initialized. | ||
97 | FN is called with no arguments." | ||
98 | (if after-init-time | ||
99 | (funcall fn) | ||
100 | (add-hook 'after-init-hook fn))) | ||
101 | |||
102 | (defmacro eval-after (features &rest body) | ||
103 | "Evaluate BODY, but only after loading FEATURES. | ||
104 | FEATURES can be an atom or a list; as an atom it works like | ||
105 | `with-eval-after-load'. The special feature `init' will evaluate | ||
106 | BODY after Emacs is finished initializing." | ||
107 | (declare (indent 1) | ||
108 | (debug (form def-body))) | ||
109 | (if (eq features 'init) | ||
110 | `(eval-after-init (lambda () ,@body)) | ||
111 | (unless (listp features) | ||
112 | (setq features (list features))) | ||
113 | (if (null features) | ||
114 | (macroexp-progn body) | ||
115 | (let* ((this (car features)) | ||
116 | (rest (cdr features))) | ||
117 | `(with-eval-after-load ',this | ||
118 | (eval-after ,rest ,@body)))))) | ||
119 | |||
94 | (defun yoke-pkg-name (pkg) | 120 | (defun yoke-pkg-name (pkg) |
95 | (intern (format "yoke:%s" pkg))) | 121 | (intern (format "yoke:%s" pkg))) |
96 | 122 | ||
@@ -98,28 +124,36 @@ Similar-ish to `plist-get', but works on non-proper plists." | |||
98 | &optional repo | 124 | &optional repo |
99 | &body body | 125 | &body body |
100 | &key | 126 | &key |
101 | requires ; :requires ((PKG REPO)...) | 127 | after ; :after (FEATURE...) |
102 | dest ; :dest DESTINATION | 128 | depends ; :depends ((PKG REPO)...) |
129 | load ; :load DIRECTORY | ||
103 | (when t whenp) ; :when PREDICATE | 130 | (when t whenp) ; :when PREDICATE |
104 | (unless nil unlessp) ; :unless PREDICATE | 131 | (unless nil unlessp) ; :unless PREDICATE |
105 | &allow-other-keys) | 132 | &allow-other-keys) |
106 | "Yoke a PKG into your Emacs session." | 133 | "Yoke a PKG into your Emacs session." |
107 | (declare (indent defun)) | 134 | (declare (indent defun)) |
108 | (let ((name (yoke-pkg-name pkg))) | 135 | (let ((name (yoke-pkg-name pkg)) |
136 | (body (delete2 body | ||
137 | :depends :when :unless :after :load))) | ||
109 | `(cl-block ,name | 138 | `(cl-block ,name |
110 | (condition-case e | 139 | (condition-case e |
111 | (let ((*yoke-name* ',name) | 140 | (let ((*yoke-name* ',name) |
112 | (*yoke-repo* ,repo) | 141 | (*yoke-repo* ,repo) |
113 | (*yoke-dest* ,(when repo `(yoke-repo-dir ',pkg ,repo)))) | 142 | (*yoke-dest* ,(when repo `(yoke-repo-dir ',pkg ,repo)))) |
114 | ,@(list (cond | 143 | ,@(cond |
115 | ((and whenp unlessp) | 144 | ((and whenp unlessp) |
116 | `(when (or (not ,when) ,unless) | 145 | `((when (or (not ,when) ,unless) |
117 | (cl-return-from ,name nil))) | 146 | (cl-return-from ,name nil)))) |
118 | (whenp `(unless ,when (cl-return-from ,name nil))) | 147 | (whenp `((unless ,when (cl-return-from ,name nil)))) |
119 | (unlessp `(when ,unless (cl-return-from ,name nil))))) | 148 | (unlessp `((when ,unless (cl-return-from ,name nil))))) |
120 | ,@(cl-loop for (pkg repo) in requires | 149 | ,@(cl-loop for (pkg* repo* load-path*) in depends |
121 | collect `(or (yoke-lasso ',pkg ,repo) | 150 | collect `(or (yoke-lasso ',pkg* ,repo* ,load-path*) |
122 | (cl-return-from ,name nil))) | 151 | (cl-return-from ,name nil))) |
123 | ,@(when repo `((yoke-lasso ',pkg ,repo))) | 152 | ,@(cond |
124 | ,@(delete2 body :requires :when :unless)) | 153 | (repo `((yoke-lasso ',pkg ,repo ,load))) |
125 | (t (message "%s: %S" ',name e)))))) | 154 | (load `((add-to-list 'load-path ,load)))) |
155 | ,@(if after | ||
156 | `((eval-after ,after ,@body)) | ||
157 | body)) | ||
158 | (:success ',pkg) | ||
159 | (t (message "%s: %s" ',name e)))))) | ||