diff options
| author | Philip Kaludercic <philipk@posteo.net> | 2026-02-09 19:22:07 +0100 |
|---|---|---|
| committer | Philip Kaludercic <philipk@posteo.net> | 2026-02-09 21:12:21 +0100 |
| commit | 4a3640c3f82142f115c6a7a7e64a4869700d1f64 (patch) | |
| tree | 6b720264ff6a9a416dbd38ba9c309f2e6700c8b9 /admin | |
| parent | 1aabe135e644a5f8703cd6d6eac0402b728c9cd3 (diff) | |
Detect more package suggestions
* admin/scrape-elpa.el (scrape-elpa--safe-eval): Add new
function.
(scrape-elpa): Evaluate part of the matched expression to catch
more entries.
* etc/package-autosuggest.eld: Update database.
Diffstat (limited to 'admin')
| -rw-r--r-- | admin/scrape-elpa.el | 60 |
1 files changed, 56 insertions, 4 deletions
diff --git a/admin/scrape-elpa.el b/admin/scrape-elpa.el index f513dc36550..f3e9d7f8d0f 100644 --- a/admin/scrape-elpa.el +++ b/admin/scrape-elpa.el @@ -1,6 +1,6 @@ ;;; scrape-elpa.el --- Collect ELPA package suggestions -*- lexical-binding: t; -*- -;; Copyright (C) 2024 Free Software Foundation, Inc. +;; Copyright (C) 2024, 2026 Free Software Foundation, Inc. ;; Author: Philip Kaludercic <philipk@posteo.net> ;; Keywords: tools @@ -25,6 +25,39 @@ ;;; Code: +(require 'rx) + +(defun scrape-elpa--safe-eval (exp &optional vars) + "Manually evaluate EXP without potentially dangerous side-effects. +The optional argument VARS may be an alist mapping symbols to values, +used when evaluating variables. The evaluation function is not meant to +be comprehensive, but just to handle the kinds of expressions that +`scrape-elpa' expects to encounter." + (pcase-exhaustive exp + ;; special handling for macros + (`(rx . ,body) (rx-to-string `(: . ,body) t)) + ;; quoting and quasi-quoting + (`',x x) + (`(purecopy ,x) x) + ((and (guard (eq '\` (car-safe exp))) (let `(,car . ,cdr) (cadr exp))) + (cons + (if (eq (car-safe car) '\,) (scrape-elpa--safe-eval (cadr car) vars) car) + (if (eq (car-safe cdr) '\,) (scrape-elpa--safe-eval (cadr cdr) vars) cdr))) + ;; supported functions + (`(cons ,car ,cdr) + (cons (scrape-elpa--safe-eval car vars) + (scrape-elpa--safe-eval cdr vars))) + (`(concat . ,args) + (apply #'concat (mapcar #'scrape-elpa--safe-eval args))) + ;; self-evaluating forms + ((pred macroexp-const-p) exp) + ;; variable evaluation + ((pred symbolp) + (let ((ent (assq exp vars))) + (if ent (cdr ent) (signal 'void-variable exp)))))) + +(scrape-elpa--safe-eval '(cons "\\.go\\'" 'go-mode)) + (defun scrape-elpa (&rest directories) "Scrape autoload files in DIRECTORIES for package suggestions. This file will automatically update \"package-autosuggest.eld\", but not @@ -57,6 +90,7 @@ Please review the results before updating the autosuggest database!" "Scraping files..." (and-let* (((string-match "/\\([^/]+?\\)-autoloads\\.el\\'" file)) (pkg (intern (match-string 1 file))) + (vars (list '(#:nihil))) (inhibit-message t)) (with-temp-buffer (insert-file-contents file) @@ -64,16 +98,34 @@ Please review the results before updating the autosuggest database!" (while t (dolist (exp (macroexp-unprogn (read (current-buffer)))) (pcase exp + (`(defconst ,(and (pred symbolp) var) ,val . ,_) + (catch 'ignore + (push + (cons var (condition-case err + (scrape-elpa--safe-eval val vars) + (t (message "Failed to evaluate %S: %S in %S" exp err vars) + (throw 'ignore nil)))) + vars))) (`(add-to-list ',(and (or 'interpreter-mode-alist 'magic-mode-alist 'auto-mode-alist) variable) - '(,(and (pred stringp) regexp) . - ,(and (pred symbolp) mode))) + ,(let `(,(and (pred stringp) regexp) . + ,(and (pred symbolp) mode)) + (condition-case err + (scrape-elpa--safe-eval _ vars) + (t (message "Failed to evaluate %S: %S in %S" exp err vars) + nil)))) (terpri) (prin1 (append (list pkg variable regexp) - (and (not (eq pkg mode)) (list mode)))))))) + (and (not (eq pkg mode)) (list mode))))) + (`(add-to-list + ',(or 'interpreter-mode-alist + 'magic-mode-alist + 'auto-mode-alist) + _) + (_ (message "Skipped over %S" exp)))))) (end-of-file nil)))))) (insert "\n)\n"))) |
