Skip to content

Commit b8436e4

Browse files
committed
doc functions
1 parent dcfe5c7 commit b8436e4

File tree

5 files changed

+133
-5
lines changed

5 files changed

+133
-5
lines changed

resources/public/clojure-dbg.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
</div>
3333
<br/>
3434
<div class="clojure">
35-
`(let [x# 1] x#)
35+
(require '[klipse.lang.clojure.env :as e])
36+
(e/doc* map)
3637
</div>
3738
<br/>
3839
<div class="clojure">

src/klipse/lang/clojure.cljs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
(:require-macros
33
[gadjett.core :as gadjett :refer [dbg]]
44
[purnam.core :refer [!]]
5+
[klipse.lang.clojure.env :refer [doc]]
56
[cljs.core.async.macros :refer [go go-loop]])
67
(:require
8+
[klipse.lang.clojure.env :refer [current-ns st]]
79
klipse.lang.clojure.bundled-namespaces
810
gadjett.core-fn
911
cljsjs.codemirror.mode.clojure
@@ -26,9 +28,7 @@
2628
(js* "window.cljs.user = {}")
2729

2830

29-
(defonce ^:private current-ns (atom 'cljs.user))
3031

31-
(def create-state-eval (memoize cljs/empty-state))
3232
(def create-state-compile (memoize cljs/empty-state))
3333

3434
(defn display [value {:keys [print-length beautify-strings]}]
@@ -101,14 +101,14 @@
101101
*ns* (create-ns @current-ns)
102102
compiler/emits (partial my-emits max-eval-duration)]
103103
; we have to set `env/*compiler*` because `binding` and core.async don't play well together (https://www.reddit.com/r/Clojure/comments/4wrjw5/withredefs_doesnt_play_well_with_coreasync/) and the code of `eval-str` uses `binding` of `env/*compiler*`.
104-
(cljs/eval-str (create-state-eval)
104+
(cljs/eval-str (st)
105105
s
106106
"my.klipse"
107107
{:eval my-eval
108108
:ns @current-ns
109109
:def-emits-var true
110110
:verbose verbose
111-
:*compiler* (set! env/*compiler* (create-state-eval))
111+
:*compiler* (set! env/*compiler* (st))
112112
:context :expr
113113
:static-fns static-fns
114114
:load (partial io/load-ns external-libs)}

src/klipse/lang/clojure/env.clj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
(ns klipse.lang.clojure.env)
2+
3+
(defmacro doc
4+
"Prints documentation for a var or special form given its name"
5+
[name]
6+
`(klipse.lang.clojure.env/doc* '~name))

src/klipse/lang/clojure/env.cljs

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
(ns klipse.lang.clojure.env
2+
(:require-macros
3+
[cljs.env.macros :as env])
4+
(:require [cljs.analyzer :as ana]
5+
[cljs.repl :refer [print-doc]]
6+
[clojure.string :as string]
7+
[cljs.js :as cljs]))
8+
9+
(def st (memoize cljs/empty-state))
10+
(defonce ^:private current-ns (atom 'cljs.user))
11+
12+
(defn- drop-macros-suffix
13+
[ns-name]
14+
(if (string/ends-with? ns-name "$macros")
15+
(apply str (drop-last 7 ns-name))
16+
ns-name))
17+
18+
(defn- add-macros-suffix
19+
[sym]
20+
(symbol (str (name sym) "$macros")))
21+
22+
(defn- all-ns
23+
"Returns a sequence of all namespaces."
24+
[]
25+
(keys (::ana/namespaces @(st))))
26+
27+
(defn- all-macros-ns []
28+
(->> (all-ns)
29+
(filter #(string/ends-with? (str %) "$macros"))))
30+
31+
(defn- get-namespace
32+
"Gets the AST for a given namespace."
33+
[ns]
34+
{:pre [(symbol? ns)]}
35+
(get-in @(st) [::ana/namespaces ns]))
36+
37+
(defn- resolve-var
38+
"Given an analysis environment resolve a var. Analogous to
39+
clojure.core/resolve"
40+
[env sym]
41+
{:pre [(map? env) (symbol? sym)]}
42+
(try
43+
(ana/resolve-var env sym
44+
(ana/confirm-var-exists-throw))
45+
(catch :default _
46+
(ana/resolve-macro-var env sym))))
47+
48+
(defn- get-macro-var
49+
[env sym macros-ns]
50+
{:pre [(symbol? macros-ns)]}
51+
(when-let [macro-var (env/with-compiler-env (st)
52+
(resolve-var env (symbol macros-ns (name sym))))]
53+
(assoc macro-var :ns macros-ns)))
54+
55+
(defn- get-var
56+
[env sym]
57+
(binding [ana/*cljs-warning-handlers* nil]
58+
(let [var (or (env/with-compiler-env (st) (resolve-var env sym))
59+
(some #(get-macro-var env sym %) (all-macros-ns)))]
60+
(when var
61+
(-> (cond-> var
62+
(not (:ns var))
63+
(assoc :ns (symbol (namespace (:name var))))
64+
(= (namespace (:name var)) (str (:ns var)))
65+
(update :name #(symbol (name %))))
66+
(update :ns (comp symbol drop-macros-suffix str)))))))
67+
68+
(defn- get-aenv []
69+
(assoc (ana/empty-env)
70+
:ns (get-namespace @current-ns)
71+
:context :expr))
72+
73+
(defn- undo-reader-conditional-spacing
74+
"Undoes the effect that wrapping a reader conditional around
75+
a defn has on a docstring."
76+
[s]
77+
;; We look for five spaces (or six, in case that the docstring
78+
;; is not aligned under the first quote) after the first newline
79+
;; (or two, in case the doctring has an unpadded blank line
80+
;; after the first), and then replace all five (or six) spaces
81+
;; after newlines with two.
82+
(when-not (nil? s)
83+
(if (re-find #"[^\n]*\n\n?\s{5,6}\S.*" s)
84+
(string/replace-all s #"\n ?" "\n ")
85+
s)))
86+
87+
(defn- doc* [name]
88+
(if-let [special-name ('{& fn catch try finally try} name)]
89+
(doc* special-name)
90+
(cond
91+
;(special-doc-map name)
92+
;(cljs.repl/print-doc (special-doc-map name))
93+
94+
;(repl-special-doc-map name)
95+
;(cljs.repl/print-doc (repl-special-doc name))
96+
97+
;(get-namespace name)
98+
;(cljs.repl/print-doc (select-keys (get-namespace name) [:name :doc]))
99+
100+
(get-var (get-aenv) name)
101+
(symbol (with-out-str (print-doc (let [aenv (get-aenv)
102+
var (get-var aenv name)
103+
m (-> (select-keys var
104+
[:ns :name :doc :forms :arglists :macro :url])
105+
(update-in [:doc] undo-reader-conditional-spacing)
106+
(merge
107+
{:forms (-> var :meta :forms second)
108+
:arglists (-> var :meta :arglists second)}))]
109+
(cond-> (update-in m [:name] clojure.core/name)
110+
(:protocol-symbol var)
111+
(assoc :protocol true
112+
:methods
113+
(->> (get-in var [:protocol-info :methods])
114+
(map (fn [[fname sigs]]
115+
[fname {:doc (:doc
116+
(get-var aenv
117+
(symbol (str (:ns var)) (str fname))))
118+
:arglists (seq sigs)}]))
119+
(into {})))))))))))
120+

src/klipse/lang/clojure/io.cljs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
(def skip-ns-macros #{'cljs.core
5858
'cljs.pprint
5959
'cljs.env.macros
60+
'klipse.lang.clojure.env
6061
'cljs.analyzer.macros
6162
'cljs.js
6263
'cljs.compiler.macros})

0 commit comments

Comments
 (0)