Skip to content

Commit 577edd1

Browse files
committed
Add print and caught hooks
1 parent d6d103c commit 577edd1

4 files changed

Lines changed: 50 additions & 35 deletions

File tree

‎README.md‎

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ Use aliases `:clj-line/client` or `:clj-line/server` for more precise targeting.
6161
| `:auto-require` | client | vector of libspecs | Required into each namespace. |
6262
| `:middleware` | server | vector of qualified symbols | nREPL middleware. |
6363
| `:eval-hook` | server | qualified symbol | Wraps eval: `(f eval)` returns the eval fn. |
64+
| `:print-hook` | server | qualified symbol | Wraps result printing: `(f print)` returns a fn with signature `[value writer options]`. |
65+
| `:caught-hook` | server | qualified symbol | Wraps error reporting: `(f caught)` returns a fn with signature `[throwable]`. |
6466
| `:port` | server | int | nREPL port (OS-assigned). |
6567
| `:print-length` | server | int | `*print-length*` (`nil`). |
6668
| `:print-level` | server | int | `*print-level*` (`nil`). |
@@ -81,22 +83,18 @@ Use aliases `:clj-line/client` or `:clj-line/server` for more precise targeting.
8183
- [x] Emacs/Vim editing key commands
8284
- [x] Custom keybindings
8385
- [x] Auto require
84-
- [x] Print var defaults (`*print-level*`, `*print-length*`, `*print-namespace-maps*`, etc)
85-
- [ ] Customized exception printer function
86-
- [ ] Read, Eval, Print, Caught hooks
86+
- [x] Dynamic var config (`*print-level*`, `*print-length*`, `*warn-on-reflection*`, etc)
87+
- [x] Print and Caught hooks (Read is the client's parser, reachable via `:keybindings`)
8788
- [ ] Bracket pairs & structural-editing
8889
- [ ] Docs
90+
- [ ] Inline tab completion of symbols (function or class)
8991
- [ ] Secondary prompt (format and content of continuation line, line numbers, colors)
90-
- [ ] Pretty-print toggle
9192
- [ ] Tap: (on/off, tap out text, filter pred)
92-
- [ ] Auto indent, column alignment (let columns and other things people align)
93-
- [ ] Inline tab completion of symbols (function or class)
9493
- [ ] REPL commands like :prompt (custom?)
9594
- [ ] Status line (on/off)
96-
- [ ] Input value coloring by type
97-
- [ ] Output value coloring by type
98-
- [ ] Indentation rules (basic alignment after each new bracket context)
99-
- [ ] Inline eval of form under cursor output to tap above
95+
- [ ] -Input value coloring by type-
96+
- [ ] -Output value coloring by type-
97+
- [x] Inline eval of form under cursor output to tap above (User space example)
10098

10199
## Tests
102100

‎server/src/clj_line/server.clj‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[clojure.java.io :as io]
44
[nrepl.config :as nrepl-config]
55
[nrepl.server :as server]
6-
[clj-line.server.eval-hook :as hook]))
6+
[clj-line.server.hooks :as hooks]))
77

88
(set! *warn-on-reflection* true)
99

@@ -25,13 +25,12 @@
2525
{}
2626
dynamic-vars))
2727

28-
(defn start [{:keys [eval-hook middleware port] :as config}]
28+
(defn start [{:keys [middleware port] :as config}]
2929
(when-let [vars (not-empty (configured-dynamic-vars config))]
3030
(alter-var-root #'nrepl-config/config assoc :dynamic-vars vars))
31-
(when eval-hook
32-
(hook/install (requiring-resolve eval-hook)))
31+
(hooks/install config)
3332
(let [extra (mapv requiring-resolve middleware)
34-
handler (apply server/default-handler #'hook/middleware extra)
33+
handler (apply server/default-handler #'hooks/middleware extra)
3534
srv (server/start-server :port (or port 0) :handler handler)]
3635
(spit ".nrepl-port" (str (:port srv)))
3736
srv))

‎server/src/clj_line/server/eval_hook.clj‎

Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
(ns clj-line.server.hooks
2+
(:require
3+
[clojure.main :as main]
4+
[nrepl.middleware :refer [set-descriptor!]]
5+
[nrepl.middleware.caught :as caught]
6+
[nrepl.middleware.print :as print]))
7+
8+
(set! *warn-on-reflection* true)
9+
10+
(def default-eval eval)
11+
(def default-print print/*print-fn*)
12+
(def default-caught main/repl-caught)
13+
14+
(def evaluator (atom nil))
15+
(def printer (atom nil))
16+
(def catcher (atom nil))
17+
18+
(defn hooked-eval [form] (@evaluator form))
19+
(defn hooked-print [value writer options] (@printer value writer options))
20+
(defn hooked-caught [throwable] (@catcher throwable))
21+
22+
(defn install [{:keys [eval-hook print-hook caught-hook]}]
23+
(when eval-hook (reset! evaluator ((requiring-resolve eval-hook) default-eval)))
24+
(when print-hook (reset! printer ((requiring-resolve print-hook) default-print)))
25+
(when caught-hook (reset! catcher ((requiring-resolve caught-hook) default-caught))))
26+
27+
(defn middleware [handler]
28+
(fn [{:keys [op] :as msg}]
29+
(handler (if (= op "eval")
30+
(cond-> msg
31+
@evaluator (assoc :eval (str `hooked-eval))
32+
@printer (assoc ::print/print (str `hooked-print))
33+
@catcher (assoc ::caught/caught (str `hooked-caught)))
34+
msg))))
35+
36+
;; Order the middleware before the nrepl eval handler
37+
(set-descriptor! #'middleware
38+
{:requires #{} :expects #{"eval"} :handles {}})

0 commit comments

Comments
 (0)