Skip to content

Commit ea52bac

Browse files
authored
Add inspect-print-current-value op (#933)
This PR adds the `inspect-print-current-value` op. It prints the current value of the inspector with the user provided `::print/print-fn` or a default one. It is used by CIDER in the `cider-inspector-print-current-value` command, bound to "P" in the inspector, to print it's current value.
1 parent ba65ade commit ea52bac

File tree

5 files changed

+103
-2
lines changed

5 files changed

+103
-2
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## master (unreleased)
44

5+
* [#933](https://github.com/clojure-emacs/cider-nrepl/pull/933): Add the `cider-inspector-print-current-value` command to print the current value of the inspector.
56
* Bump `orchard` to [0.34.1](https://github.com/clojure-emacs/orchard/blob/master/CHANGELOG.md#0341-2025-04-23).
67
* [#935](https://github.com/clojure-emacs/cider-nrepl/pull/935): Unify injected print-method implementations with orchard.print.
78

doc/modules/ROOT/pages/nrepl-api/ops.adoc

+24
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,30 @@ Returns::
576576

577577

578578

579+
=== `inspect-print-current-value`
580+
581+
Print the current value of the inspector.
582+
583+
Required parameters::
584+
* `:session` The current session
585+
586+
587+
Optional parameters::
588+
* `:nrepl.middleware.print/buffer-size` The size of the buffer to use when streaming results. Defaults to 1024.
589+
* `:nrepl.middleware.print/keys` A seq of the keys in the response whose values should be printed.
590+
* `:nrepl.middleware.print/options` A map of options to pass to the printing function. Defaults to ``nil``.
591+
* `:nrepl.middleware.print/print` A fully-qualified symbol naming a var whose function to use for printing. Must point to a function with signature [value writer options].
592+
* `:nrepl.middleware.print/quota` A hard limit on the number of bytes printed for each value.
593+
* `:nrepl.middleware.print/stream?` If logical true, the result of printing each value will be streamed to the client over one or more messages.
594+
595+
596+
Returns::
597+
* `:path` Printed representation of current inspector path.
598+
* `:status` "done"
599+
* `:value` The inspector result. Contains a specially-formatted string that can be ``read`` and then rendered client-side.
600+
601+
602+
579603
=== `inspect-push`
580604

581605
Inspects the inside value specified by index.

src/cider/nrepl.clj

+6-1
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,12 @@ Note: Documentation may be incomplete; not all return keys are described."
313313
inspector's state in the `:value` slot."
314314
:requires #{"clone" #'wrap-caught #'wrap-print}
315315
:expects #{"eval"}
316-
:handles {"inspect-pop"
316+
:handles {"inspect-print-current-value"
317+
{:doc "Print the current value of the inspector."
318+
:requires {"session" "The current session"}
319+
:optional wrap-print-optional-arguments
320+
:returns inspector-returns}
321+
"inspect-pop"
317322
{:doc "Moves one level up in the inspector stack."
318323
:requires {"session" "The current session"}
319324
:returns inspector-returns}

src/cider/nrepl/middleware/inspect.clj

+21-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
(ns cider.nrepl.middleware.inspect
22
(:require
3+
[cider.nrepl.middleware.util :refer [respond-to]]
34
[cider.nrepl.middleware.util.cljs :as cljs]
45
[cider.nrepl.middleware.util.error-handling
56
:refer [eval-interceptor-transport with-safe-transport]]
7+
[cider.nrepl.pprint :as pprint]
8+
[nrepl.middleware.print :as print]
69
[nrepl.misc :refer [response-for]]
710
[nrepl.transport :as transport]
811
[orchard.inspect :as inspect]))
@@ -107,16 +110,33 @@
107110
(defn def-current-value [msg]
108111
(inspector-response msg (swap-inspector! msg inspect/def-current-value (symbol (:ns msg)) (:var-name msg))))
109112

113+
(defn print-current-value-reply [{:keys [::print/print-fn session] :as msg}]
114+
(let [inspector (-> session meta ::inspector)]
115+
(with-open [writer (print/replying-PrintWriter :value msg msg)]
116+
(binding [*print-length* (or *print-length* 100)
117+
*print-level* (or *print-level* 20)]
118+
((or print-fn pprint/pprint) (:value inspector) writer)
119+
(.flush writer)))
120+
(respond-to msg :status :done)))
121+
110122
(defn tap-current-value [msg]
111123
(inspector-response msg (swap-inspector! msg inspect/tap-current-value)))
112124

113125
(defn tap-indexed [msg]
114126
(inspector-response msg (swap-inspector! msg inspect/tap-indexed (:idx msg))))
115127

116128
(defn handle-inspect [handler {:keys [op inspect] :as msg}]
117-
(if (and (= op "eval") inspect)
129+
(cond
130+
(and (= op "eval") inspect)
118131
(handle-eval-inspect handler msg)
119132

133+
;; This is outside of `with-safe-transport` because it streams the pretty
134+
;; printed result to the client in multiple messages. It does NOT return any
135+
;; value, which is expected by `with-safe-transport`.
136+
(= op "inspect-print-current-value")
137+
(print-current-value-reply msg)
138+
139+
:else
120140
(with-safe-transport handler msg
121141
"inspect-pop" pop-reply
122142
"inspect-push" push-reply

test/clj/cider/nrepl/middleware/inspect_test.clj

+51
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,57 @@
745745
:inspect "true"
746746
:code "(range 100)"}))))))))
747747

748+
(deftest inspect-print-current-value-test
749+
(testing "inspect-print-current-value returns the currently inspected value as a printed string"
750+
(is (= [(str/join "\n" ["{:a -1,"
751+
" :bb \"111\","
752+
" :ccc (1),"
753+
" :d"
754+
" ({:a 0, :bb \"000\", :ccc ()}"
755+
" {:a -1, :bb \"111\", :ccc (1)}"
756+
" {:a -2, :bb \"222\", :ccc (2 1)}"
757+
" {:a -3, :bb \"333\", :ccc (3 2 1)}"
758+
" {:a -4, :bb \"444\", :ccc (4 3 2 1)})}"])]
759+
(:value (do
760+
(session/message {:op "eval"
761+
:code "(def test-val
762+
(for [i (range 2)]
763+
{:a (- i)
764+
:bb (str i i i)
765+
:ccc (range i 0 -1)
766+
:d (for [i (range 5)]
767+
{:a (- i)
768+
:bb (str i i i)
769+
:ccc (range i 0 -1)})}))"})
770+
(session/message {:op "eval"
771+
:inspect "true"
772+
:code "test-val"})
773+
(session/message {:op "inspect-push"
774+
:idx 2})
775+
(session/message {:op "inspect-print-current-value"
776+
:nrepl.middleware.print/print "cider.nrepl.pprint/pprint"})))))))
777+
778+
(deftest inspect-print-current-value-no-value-test
779+
(testing "inspect-print-current-value returns nil if nothing has been inspected yet"
780+
(is (= ["nil"] (:value (session/message
781+
{:op "inspect-print-current-value"
782+
:nrepl.middleware.print/print "cider.nrepl.pprint/pprint"}))))))
783+
784+
(deftest inspect-print-current-value-default-print-fn-test
785+
(testing "inspect-print-current-value uses a default print fn when none is provided"
786+
(is (= ["nil"] (:value (session/message {:op "inspect-print-current-value"}))))))
787+
788+
(deftest inspect-print-current-value-infinite-seq-test
789+
(testing "inspect-print-current-value works with infinite-seqs"
790+
(is (str/starts-with? (first (:value (do (session/message {:op "eval"
791+
:code "(def test-val (repeat :x))"})
792+
(session/message {:op "eval"
793+
:inspect "true"
794+
:code "test-val"})
795+
(session/message {:op "inspect-print-current-value"
796+
:nrepl.middleware.print/print "cider.nrepl.pprint/pprint"}))))
797+
"(:x"))))
798+
748799
(deftest inspect-def-current-value-test
749800
(testing "inspect-def-current-value defines a var with the current inspector value"
750801
(is (= "{3 4}"

0 commit comments

Comments
 (0)