@@ -79,6 +79,64 @@ the conventions of use-package."
7979
8080; ;;; Extract package names from an init file
8181
82+ (defcustom use-package-tags-init-files
83+ (list (or user-init-file
84+ (expand-file-name " init.el" user-emacs-directory)))
85+ " List of files to look for package declarations."
86+ :type '(repeat file))
87+
88+ (defun use-package-tags--source-buffer-list (source )
89+ " Return a list of buffers for SOURCE.
90+
91+ If the argument is nil, it returns a list containing the current
92+ buffer.
93+
94+ Alternatively, the argument can be one of the following:
95+
96+ * t for `use-package-tags-init-files' .
97+ * File name.
98+ * Buffer.
99+ * List of files.
100+ * List of buffers."
101+ (cl-labels
102+ ((to-buffer
103+ (item)
104+ (cl-etypecase item
105+ (buffer item)
106+ ; ; (symbol (to-buffer (eval symbol)))
107+ (file-exists (or (find-buffer-visiting item)
108+ (find-file-noselect item)))
109+ (string (error " File does not exist: %s " item)))))
110+ (cl-typecase source
111+ (null (list (current-buffer )))
112+ (symbol (if (eq t source )
113+ (mapcar #'to-buffer use-package-tags-init-files)
114+ ; ; TODO: Return the variable value when a symbol is given
115+ ; ; (list (to-buffer source))
116+ (error " Symbol is not accepted: %s " source )))
117+ (list (mapcar #'to-buffer source ))
118+ (otherwise (list (to-buffer source ))))))
119+
120+ (defsubst use-package-tags--normalize-query (query )
121+ " Normalize QUERY into a list or t."
122+ (cl-etypecase query
123+ (listp query)
124+ (symbolp (or (eq t query)
125+ (list query)))))
126+
127+ (defmacro use-package-tags--with-package-forms (buffers &rest progn )
128+ " In BUFFERS, evaluate PROGN at every `use-package' form."
129+ (declare (indent 1 ))
130+ `(dolist (buf , buffers )
131+ (with-current-buffer buf
132+ (save-excursion
133+ (goto-char (point-min ))
134+ (while (re-search-forward (rx " (use-package" space) nil t )
135+ (beginning-of-defun-raw )
136+ ,@progn
137+ (end-of-defun ))))))
138+
139+ ;;;### autoload
82140(cl-defun use-package-tags-select (query &key from installable
83141 (as 'symbols ))
84142 " Get a list of packages declared in `use-package' forms.
@@ -91,8 +149,8 @@ at least one tag in the query or have no tags. Alternatively, you
91149can select all packages declared in the source by specifying t as
92150the query.
93151
94- By default, the source is the current buffer .
95- You can specify a file as the source by setting FROM to its file path .
152+ FROM specifies the source.
153+ See `use-package-tags-- source-buffer-list' .
96154
97155When INSTALLABLE is set to non-nil, it returns a list of packages
98156available on the Emacs-Mirror. You will need epkg.el for this feature.
@@ -107,52 +165,40 @@ It accepts the following values (the default: symbols):
107165 * lines: a single string joined by newlines."
108166 (declare (indent 1 ))
109167 (let (alist
110- (bufs (cl-etypecase from
111- (null (list (current-buffer )))
112- (file-exists-p (list (or (find-buffer-visiting from)
113- (find-file-noselect from))))))
114- (query (cl-etypecase query
115- (listp query)
116- (symbolp (or (eq t query)
117- (list query))))))
168+ (query (use-package-tags--normalize-query query)))
118169 (cl-labels
119170 ((get-keyword (prop rest) (-some->> (member prop rest)
120171 (nth 1 ))))
121- (dolist (buf bufs)
122- (with-current-buffer buf
123- (save-excursion
124- (goto-char (point-min ))
125- (while (re-search-forward (rx " (use-package" space) nil t )
126- (beginning-of-defun-raw )
127- (let* ((exp (read (current-buffer )))
128- (name (nth 1 exp))
129- (disabled (get-keyword :disabled exp))
130- ; ; TODO: Handle dependencies
131- ; ; (after (get-keyword :after))
132- ; ; (requires (get-keyword :requires))
133- ; ; TODO: Add support for :when and :unless
134- (if-expr (get-keyword :if exp))
135- (tags (get-keyword :tags exp)))
136- (when (and (not disabled)
137- (not (and if-expr
138- (not (eval if-expr))))
139- ; ; TODO: :requires keyword
140- ; ; (or (not requires)
141- ; ; (-all-p (lambda (feature)
142- ; ; (assoc feature alist))
143- ; ; (cl-etypecase requires
144- ; ; (list requires)
145- ; ; (symbol (list requires)))))
146- (or (eq t query)
147- (not tags)
148- (cl-intersection tags query)))
149- (push (list name)
150- ; ; TODO: Handle dependencies
151- ; ; (list name
152- ; ; :after after
153- ; ; :requires requires)
154- alist)))
155- (end-of-defun ))))))
172+ (use-package-tags--with-package-forms
173+ (use-package-tags--source-buffer-list from)
174+ (let* ((exp (read (current-buffer )))
175+ (name (nth 1 exp))
176+ (disabled (get-keyword :disabled exp))
177+ ; ; TODO: Handle dependencies
178+ ; ; (after (get-keyword :after))
179+ ; ; (requires (get-keyword :requires))
180+ ; ; TODO: Add support for :when and :unless
181+ (if-expr (get-keyword :if exp))
182+ (tags (get-keyword :tags exp)))
183+ (when (and (not disabled)
184+ (not (and if-expr
185+ (not (eval if-expr))))
186+ ; ; TODO: :requires keyword
187+ ; ; (or (not requires)
188+ ; ; (-all-p (lambda (feature)
189+ ; ; (assoc feature alist))
190+ ; ; (cl-etypecase requires
191+ ; ; (list requires)
192+ ; ; (symbol (list requires)))))
193+ (or (eq t query)
194+ (not tags)
195+ (cl-intersection tags query)))
196+ (push (list name)
197+ ; ; TODO: Handle dependencies
198+ ; ; (list name
199+ ; ; :after after
200+ ; ; :requires requires)
201+ alist)))))
156202 (cl-labels
157203 ((enabled-p
158204 ; ; The dependency handle is work in progress.
@@ -220,5 +266,29 @@ It accepts the following values (the default: symbols):
220266 (delq nil )
221267 (-uniq))))
222268
269+ ;;;### autoload
270+ (cl-defun use-package-tags-collect-tags (source &key sort )
271+ " Collect package tags from a source.
272+
273+ For SOURCE, see `use-package-tags--source-buffer-list' .
274+
275+ If SORT is non-nil, the result will be lexicographically sorted."
276+ (cl-labels
277+ ((get-keyword (prop rest) (-some->> (member prop rest)
278+ (nth 1 )))
279+ (order (items) (if sort
280+ (cl-sort items #'string< :key #'symbol-name )
281+ items)))
282+ (let (result)
283+ (use-package-tags--with-package-forms
284+ (use-package-tags--source-buffer-list source )
285+ (let* ((exp (read (current-buffer )))
286+ (tags (get-keyword :tags exp)))
287+ (when tags
288+ (push tags result))))
289+ (->> (-flatten-n 1 result)
290+ (cl-remove-duplicates )
291+ (order)))))
292+
223293(provide 'use-package-tags )
224294; ;; use-package-tags.el ends here
0 commit comments