Skip to content

Commit 69959fb

Browse files
committed
Numerous repl-helpers improvements
- add function spec to doc-symbol - add doc-namespace, describe-spec - add find-symbols support for filtering against ns - fix source-symbol not actually printing function source
1 parent 89feeb0 commit 69959fb

File tree

1 file changed

+50
-6
lines changed

1 file changed

+50
-6
lines changed

resources/clojure-mcp/repl_helpers.clj

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
(ns clj-mcp.repl-tools
44
"Namespace containing helper functions for REPL-driven development"
5-
(:require [clojure.string :as str]
6-
[clojure.pprint :as pprint]))
5+
(:require [clojure.pprint :as pprint]
6+
[clojure.spec.alpha :as s]
7+
[clojure.string :as str]))
78

89
;; Namespace exploration
910
(defn list-ns
@@ -52,26 +53,64 @@
5253
(println (str " Arguments: " arglists)))
5354
(when-let [added (:added m)]
5455
(println (str " Added in: " added)))
56+
(when-let [fn-spec (s/get-spec (symbol v))]
57+
(println " Function Spec: " (with-out-str (pprint/pprint (s/describe fn-spec)))))
5558
(when-let [deprecated (:deprecated m)]
5659
(println (str " DEPRECATED: " deprecated)))
5760
(println (str "-------------------------")))
5861
(println (str "Error: Symbol not found: " sym)))
5962
nil)
6063

64+
(defn doc-namespace
65+
"Show documentation for a namespace. Accepts symbol or string."
66+
[sym]
67+
(if-let [ns (find-ns (if (symbol? sym) sym (symbol sym)))]
68+
(let [m (meta ns)]
69+
(println (str "-------------------------"))
70+
(println (str (name sym) " - " (or (:doc m) "No documentation")))
71+
(println (str "-------------------------")))
72+
(println (str "Error: Namespace not found: " sym)))
73+
nil)
74+
6175
(defn source-symbol
6276
"Show source code for a var. Accepts symbol or string."
6377
[sym]
6478
(if-let [v (resolve (if (symbol? sym) sym (symbol sym)))]
6579
(if-let [source-fn (resolve 'clojure.repl/source-fn)]
66-
(source-fn (symbol (str (-> v meta :ns)) (str (-> v meta :name))))
80+
(println (source-fn (symbol v)))
6781
(println "Error: clojure.repl/source-fn not available"))
6882
(println (str "Error: Symbol not found: " sym)))
6983
nil)
7084

85+
(defn describe-spec
86+
"Show detailed information about a keyword/symbol/var `spec`."
87+
[spec]
88+
(if-let [spec-form (s/get-spec spec)]
89+
(do
90+
(println (str "-------------------------"))
91+
(println (str "Spec: " spec))
92+
(pprint/pprint (s/describe spec-form))
93+
(println (str "-------------------------")))
94+
(println (str "Error: Spec not found: " spec)))
95+
nil)
96+
7197
(defn find-symbols
72-
"Find symbols matching the given pattern across all namespaces."
98+
"Find symbols matching the given pattern across all namespaces.
99+
Pattern can be a string (for substring matching) or a regex pattern.
100+
Matches against both namespace and symbol name in the format 'namespace/symbol'."
73101
[pattern]
74-
(let [matches (sort (map str (clojure.repl/apropos pattern)))]
102+
(let [match-fn (cond
103+
(instance? java.util.regex.Pattern pattern)
104+
#(re-find pattern %)
105+
:else
106+
#(str/includes? % (str pattern)))
107+
108+
matches (sort (for [ns (all-ns)
109+
:let [ns-name (str (ns-name ns))]
110+
[sym-name] (ns-publics ns)
111+
:let [qualified-name (str ns-name "/" (name sym-name))]
112+
:when (match-fn qualified-name)]
113+
qualified-name))]
75114
(println (str "Symbols matching '" pattern "':"))
76115
(doseq [sym matches]
77116
(println (str " " sym)))
@@ -127,7 +166,9 @@
127166
(println " clj-mcp.repl-tools/list-ns - List all available namespaces")
128167
(println " clj-mcp.repl-tools/list-vars - List all vars in namespace")
129168
(println " clj-mcp.repl-tools/doc-symbol - Show documentation for symbol")
169+
(println " clj-mcp.repl-tools/doc-namespace - Show documentation for a namespace")
130170
(println " clj-mcp.repl-tools/source-symbol - Show source code for symbol")
171+
(println " clj-mcp.repl-tools/describe-spec - Show detailed information about spec")
131172
(println " clj-mcp.repl-tools/find-symbols - Find symbols matching pattern")
132173
(println " clj-mcp.repl-tools/complete - Find completions for prefix")
133174
(println " clj-mcp.repl-tools/help - Show this help message")
@@ -136,8 +177,11 @@
136177
(println " (clj-mcp.repl-tools/list-ns) ; List all namespaces")
137178
(println " (clj-mcp.repl-tools/list-vars 'clojure.string) ; List functions in clojure.string")
138179
(println " (clj-mcp.repl-tools/doc-symbol 'map) ; Show documentation for map")
180+
(println " (clj-mcp.repl-tools/doc-namespace 'clojure.repl) ; Show documentation for map")
139181
(println " (clj-mcp.repl-tools/source-symbol 'map) ; Show source code for map")
140-
(println " (clj-mcp.repl-tools/find-symbols \"seq\") ; Find symbols containing \"seq\"")
182+
(println " (clj-mcp.repl-tools/describe-spec :my/spec) ; Show detailed information about a clojure spec")
183+
(println " (clj-mcp.repl-tools/find-symbols \"seq\") ; Find symbols containing \"seq\" (namespace/symbol)")
184+
(println " (clj-mcp.repl-tools/find-symbols #\".*math.*\") ; Find symbols matching regex pattern")
141185
(println " (clj-mcp.repl-tools/complete \"clojure.string/j\") ; Find completions for prefix")
142186
(println)
143187
(println "For convenience, you can require the namespace with an alias:")

0 commit comments

Comments
 (0)