fenix-skills/skills/describe/agent-skill-describe.el

77 lines
3.3 KiB
EmacsLisp

(require 'cl-lib)
(cl-defun agent-skill-describe (&key query)
"Look up QUERY across multiple Emacs documentation mechanisms.
Searches for QUERY as a function, variable, and via apropos,
returning all findings in a single string."
(let ((sym (intern-soft query))
(sections nil))
;; Function documentation
(when (and sym (fboundp sym))
(push (format "## Function: %s\n\n%s\n\nSignature: %s\n\n%s"
query
(cond ((subrp (symbol-function sym)) "Built-in function")
((macrop sym) "Macro")
((commandp sym) "Interactive command")
(t "Function"))
(or (help-function-arglist sym t) "()")
(or (documentation sym t) "No documentation available."))
sections))
;; Variable documentation
(when (and sym (boundp sym))
(let ((val (symbol-value sym)))
(push (format "## Variable: %s\n\nCurrent value: %s\n\n%s"
query
(let ((printed (format "%S" val)))
(if (> (length printed) 200)
(concat (substring printed 0 200) "...")
printed))
(or (documentation-property sym 'variable-documentation t)
"No documentation available."))
sections)))
;; Face documentation
(when (and sym (facep sym))
(push (format "## Face: %s\n\n%s"
query
(or (documentation-property sym 'face-documentation t)
"No documentation available."))
sections))
;; Key binding (if it looks like a key sequence)
(when (string-match-p "\\`[CMSs]-\\|\\`<" query)
(let* ((keyseq (ignore-errors (kbd query)))
(binding (and keyseq (key-binding keyseq))))
(when binding
(push (format "## Key binding: %s\n\n%s runs `%s'\n\n%s"
query query binding
(or (documentation binding t)
"No documentation available."))
sections))))
;; Apropos matches (up to 20)
(let ((matches nil))
(mapatoms
(lambda (s)
(when (and (string-match-p (regexp-quote query) (symbol-name s))
(not (eq s sym))
(or (fboundp s) (boundp s)))
(push (format " %s%s"
(symbol-name s)
(cond ((and (fboundp s) (boundp s))
" [function, variable]")
((fboundp s) " [function]")
(t " [variable]")))
matches))))
(when matches
(let ((sorted (sort matches #'string<)))
(push (format "## Related symbols\n\n%s%s"
(mapconcat #'identity (seq-take sorted 20) "\n")
(if (> (length sorted) 20)
(format "\n ... and %d more" (- (length sorted) 20))
""))
sections))))
(if sections
(mapconcat #'identity (nreverse sections) "\n\n")
(format "No documentation found for \"%s\"." query))))
(provide 'agent-skill-describe)