Skip to content

Commit 5e81c0f

Browse files
[inspect] Add inspect-show-analytics op
1 parent 9d73a16 commit 5e81c0f

File tree

8 files changed

+164
-216
lines changed

8 files changed

+164
-216
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
## master (unreleased)
44

5+
* Bump `orchard` to [0.32.0](https://github.com/clojure-emacs/orchard/blob/master/CHANGELOG.md#0320-2025-04-05).
56
* [#925](https://github.com/clojure-emacs/cider-nrepl/pull/9250): Stop vendoring Puget dependency.
67
* [#917](https://github.com/clojure-emacs/cider-nrepl/pull/917): Sort printed maps in test output.
8+
* [#927](https://github.com/clojure-emacs/cider-nrepl/pull/927): Add `inspect-display-analytics` op.
79

810
## 0.53.2 (2025-03-26)
911

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,24 @@ Returns::
478478

479479

480480

481+
=== `inspect-display-analytics`
482+
483+
Calculate and render analytics section for the currently inspected object.
484+
485+
Required parameters::
486+
* `:session` The current session
487+
488+
489+
Optional parameters::
490+
{blank}
491+
492+
Returns::
493+
* `:path` Printed representation of current inspector path.
494+
* `:status` "done"
495+
* `:value` The inspector result. Contains a specially-formatted string that can be ``read`` and then rendered client-side.
496+
497+
498+
481499
=== `inspect-last-exception`
482500

483501
Returns an Inspector response for the last exception that has been processed through ``analyze-last-stacktrace`` for the current nrepl session.

project.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
:url "http://www.eclipse.org/legal/epl-v10.html"}
2323
:scm {:name "git" :url "https://github.com/clojure-emacs/cider-nrepl"}
2424
:dependencies [[nrepl/nrepl "1.3.1" :exclusions [org.clojure/clojure]]
25-
[cider/orchard "0.31.1" :exclusions [org.clojure/clojure]]
25+
[cider/orchard "0.32.1" :exclusions [org.clojure/clojure]]
2626
^:inline-dep [thunknyc/profile "0.5.2"]
2727
^:inline-dep [fipp ~fipp-version] ; can be removed in unresolved-tree mode
2828
^:inline-dep [compliment "0.7.0"]

src/cider/nrepl.clj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,10 @@ if applicable, and re-render the updated value."
345345
{:doc "Toggles the viewing mode of the inspector. This influences the way how inspector is rendering the current value. `:normal` is the default. When view mode is `:object`, any value will be rendered as a Java object (fields shown as is). View mode is automatically reset back to normal when navigating to child values."
346346
:requires {"session" "The current session"}
347347
:returns inspector-returns}
348+
"inspect-display-analytics"
349+
{:doc "Calculate and render analytics section for the currently inspected object."
350+
:requires {"session" "The current session"}
351+
:returns inspector-returns}
348352
"inspect-next-page"
349353
{:doc "Jumps to the next page in paginated collection view."
350354
:requires {"session" "The current session"}

src/cider/nrepl/middleware/inspect.clj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232

3333
(defn- msg->inspector-config [msg]
3434
(select-keys msg [:page-size :max-atom-length :max-coll-size
35-
:max-value-length :max-nested-depth]))
35+
:max-value-length :max-nested-depth :display-analytics-hint]))
3636

3737
(defn inspect-reply*
3838
[msg value]
@@ -84,6 +84,9 @@
8484
(defn toggle-view-mode-reply [msg]
8585
(inspector-response msg (swap-inspector! msg toggle-view-mode)))
8686

87+
(defn- display-analytics-reply [msg]
88+
(inspector-response msg (swap-inspector! msg inspect/display-analytics)))
89+
8790
(defn ^:deprecated set-page-size-reply [msg] (refresh-reply msg))
8891
(defn ^:deprecated set-max-atom-length-reply [msg] (refresh-reply msg))
8992
(defn ^:deprecated set-max-coll-size-reply [msg] (refresh-reply msg))
@@ -114,6 +117,7 @@
114117
"inspect-prev-page" prev-page-reply
115118
"inspect-refresh" refresh-reply
116119
"inspect-toggle-view-mode" toggle-view-mode-reply
120+
"inspect-display-analytics" display-analytics-reply
117121
"inspect-set-page-size" refresh-reply
118122
"inspect-set-max-atom-length" refresh-reply
119123
"inspect-set-max-coll-size" refresh-reply

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

Lines changed: 84 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -28,138 +28,83 @@
2828
(use-fixtures :each session/session-fixture inspect-tap-current-value-test-fixture)
2929

3030
(def nil-result
31-
'["nil" (:newline)])
31+
["nil" [:newline]])
3232

3333
(def any-var true)
3434

3535
(def var-result
36-
'("Class: "
37-
(:value "clojure.lang.Var" 0)
38-
(:newline)
39-
"Value: "
40-
(:value "true" 1)
41-
(:newline)
42-
(:newline)
43-
"--- Meta Information:"
44-
(:newline)
45-
" "
46-
(:value ":line" 2) " = " (:value #"\d+" 3) (:newline)
47-
" "
48-
(:value ":column" 4) " = " (:value #"\d+" 5) (:newline)
49-
" "
50-
(:value ":file" 6) " = " (:value #"\".*cider/nrepl/middleware/inspect_test.clj\"" 7) (:newline)
51-
" "
52-
(:value ":name" 8) " = " (:value "any-var" 9) (:newline)
53-
" "
54-
(:value ":ns" 10) " = " (:value "cider.nrepl.middleware.inspect-test" 11) (:newline)
55-
(:newline)
56-
"--- Datafy:" (:newline)
57-
" " "0" ". " (:value "true" 12) (:newline)))
36+
["Class: " [:value "clojure.lang.Var" 0] [:newline]
37+
"Value: " [:value "true" 1] [:newline]
38+
[:newline]
39+
"--- Meta Information:" [:newline]
40+
" " [:value ":line" 2] " = " [:value #"\d+" 3] [:newline]
41+
" " [:value ":column" 4] " = " [:value #"\d+" 5] [:newline]
42+
" " [:value ":file" 6] " = " [:value #"\".*cider/nrepl/middleware/inspect_test.clj\"" 7] [:newline]
43+
" " [:value ":name" 8] " = " [:value "any-var" 9] [:newline]
44+
" " [:value ":ns" 10] " = " [:value "cider.nrepl.middleware.inspect-test" 11] [:newline]
45+
[:newline]
46+
"--- Datafy:" [:newline]
47+
" 0. " [:value "true" 12] [:newline]])
5848

5949
(def code "(sorted-map :a {:b 1} :c \"a\" :d 'e :f [2 3])")
6050

6151
(def infinite-map-code "(let [m (java.util.HashMap.)] (.put m (symbol \"very long key to avoid stack overflow before limit reaches\") m) m)")
6252

6353
(def inspect-result
64-
'("Class: "
65-
(:value "clojure.lang.PersistentTreeMap" 0)
66-
(:newline)
67-
"Count: "
68-
"4"
69-
(:newline)
70-
(:newline)
71-
"--- Contents:"
72-
(:newline)
73-
" " (:value ":a" 1) " = " (:value "{:b 1}" 2)
74-
(:newline)
75-
" " (:value ":c" 3) " = " (:value "\"a\"" 4)
76-
(:newline)
77-
" " (:value ":d" 5) " = " (:value "e" 6)
78-
(:newline)
79-
" " (:value ":f" 7) " = " (:value "[2 3]" 8)
80-
(:newline)))
54+
["Class: " [:value "clojure.lang.PersistentTreeMap" 0] [:newline]
55+
"Count: 4" [:newline]
56+
[:newline]
57+
"--- Contents:" [:newline]
58+
" " [:value ":a" 1] " = " [:value "{:b 1}" 2] [:newline]
59+
" " [:value ":c" 3] " = " [:value "\"a\"" 4] [:newline]
60+
" " [:value ":d" 5] " = " [:value "e" 6] [:newline]
61+
" " [:value ":f" 7] " = " [:value "[2 3]" 8] [:newline]])
8162

8263
(def push-result
83-
'("Class: "
84-
(:value "clojure.lang.PersistentArrayMap" 0)
85-
(:newline)
86-
"Count: "
87-
"1"
88-
(:newline)
89-
(:newline)
90-
"--- Contents:"
91-
(:newline)
92-
" " (:value ":b" 1) " = " (:value "1" 2)
93-
(:newline)
94-
(:newline)
95-
"--- Path:"
96-
(:newline)
97-
" " ":a"))
64+
["Class: " [:value "clojure.lang.PersistentArrayMap" 0] [:newline]
65+
"Count: 1" [:newline]
66+
[:newline]
67+
"--- Contents:" [:newline]
68+
" " [:value ":b" 1] " = " [:value "1" 2] [:newline]
69+
[:newline]
70+
"--- Path:" [:newline]
71+
" :a"])
9872

9973
(def sibling-result
100-
'("Class: "
101-
(:value "java.lang.String" 0)
102-
(:newline)
103-
"Value: "
104-
"\"c\""
105-
(:newline)
106-
(:newline)
107-
"--- Print:"
108-
(:newline)
109-
" "
110-
"c"
111-
(:newline)
112-
(:newline)
113-
"--- Path:"
114-
(:newline)
115-
" "
116-
"(nth 2)"))
74+
["Class: " [:value "java.lang.String" 0] [:newline]
75+
"Value: \"c\"" [:newline]
76+
[:newline]
77+
"--- Print:" [:newline]
78+
" c" [:newline]
79+
[:newline]
80+
"--- Path:" [:newline]
81+
" (nth 2)"])
11782

11883
(def next-page-result
119-
'("Class: "
120-
(:value "clojure.lang.LazySeq" 0)
121-
(:newline)
122-
(:newline)
123-
"--- Contents:"
124-
(:newline)
125-
" " "..."
126-
(:newline)
127-
" " "32" ". " (:value "32" 1)
128-
(:newline)
129-
" " "33" ". " (:value "33" 2)
130-
(:newline)
131-
" " "34" ". " (:value "34" 3)
132-
(:newline)
133-
(:newline)
134-
"--- Page Info:"
135-
(:newline)
136-
" " "Page size: 32, showing page: 2 of 2"
137-
(:newline)))
84+
["Class: " [:value "clojure.lang.LazySeq" 0] [:newline]
85+
[:newline]
86+
"--- Contents:" [:newline]
87+
" ..." [:newline]
88+
" 32. " [:value "32" 1] [:newline]
89+
" 33. " [:value "33" 2] [:newline]
90+
" 34. " [:value "34" 3] [:newline]
91+
[:newline]
92+
"--- Page Info:" [:newline]
93+
" Page size: 32, showing page: 2 of 2" [:newline]])
13894

13995
(def first-page-result
140-
'("Class: "
141-
(:value "clojure.lang.LazySeq" 0)
142-
(:newline)
143-
(:newline)
144-
"--- Contents:"
145-
(:newline)
146-
" " "0" ". " (:value "0" 1)
147-
(:newline)
148-
" " "1" ". " (:value "1" 2)
149-
(:newline)
150-
" " "2" ". " (:value "2" 3)
151-
(:newline)
152-
" " "3" ". " (:value "3" 4)
153-
(:newline)
154-
" " "4" ". " (:value "4" 5)
155-
(:newline)
156-
" " "..."
157-
(:newline)
158-
(:newline)
159-
"--- Page Info:"
160-
(:newline)
161-
" " "Page size: 5, showing page: 1 of ?"
162-
(:newline)))
96+
["Class: " [:value "clojure.lang.LazySeq" 0] [:newline]
97+
[:newline]
98+
"--- Contents:" [:newline]
99+
" 0. " [:value "0" 1] [:newline]
100+
" 1. " [:value "1" 2] [:newline]
101+
" 2. " [:value "2" 3] [:newline]
102+
" 3. " [:value "3" 4] [:newline]
103+
" 4. " [:value "4" 5] [:newline]
104+
" ..." [:newline]
105+
[:newline]
106+
"--- Page Info:" [:newline]
107+
" Page size: 5, showing page: 1 of ?" [:newline]])
163108

164109
(defn value [{:keys [value]}]
165110
(edn/read-string (first value)))
@@ -664,13 +609,10 @@
664609
"\"[[[[[[...]]]]]]\""))))))
665610

666611
(def normal-mode-prefix
667-
["--- Contents:"
668-
[:newline]
669-
" " "0" ". " [:value "1" number?]
670-
[:newline]
671-
" " "1" ". " [:value "2" number?]
672-
[:newline]
673-
" " "2" ". " [:value "3" number?]])
612+
["--- Contents:" [:newline]
613+
" 0. " [:value "1" number?] [:newline]
614+
" 1. " [:value "2" number?] [:newline]
615+
" 2. " [:value "3" number?]])
674616

675617
(def object-mode-prefix
676618
["--- Instance fields:"
@@ -708,10 +650,29 @@
708650
(is+ (matchers/prefix object-mode-prefix)
709651
(value-skip-header (session/message {:op "inspect-toggle-view-mode"})))
710652
(is+ (matchers/prefix ["--- Contents:" [:newline]
711-
" " "0" ". " [:value "2" number?] [:newline]
712-
" " "1" ". " [:value "3" number?] [:newline]])
653+
" 0. " [:value "2" number?] [:newline]
654+
" 1. " [:value "3" number?] [:newline]])
713655
(value-skip-header (session/message {:op "inspect-push" :idx 13})))))
714656

657+
(deftest display-analytics-integration-test
658+
(testing "analytics can be displayed with inspect-display-analytics"
659+
(session/message {:op "inspect-clear"})
660+
(value-skip-header (session/message {:op "eval"
661+
:inspect "true"
662+
:code "(range 100)"}))
663+
(is+ (matchers/prefix ["--- Analytics:" [:newline]
664+
" " [:value ":count" pos?] " = " [:value "100" pos?] [:newline]
665+
" " [:value ":types" pos?] " = " [:value "{java.lang.Long 100}" pos?] [:newline]])
666+
(value-skip-header (session/message {:op "inspect-display-analytics"}))))
667+
668+
(testing "analytics hint is displayed when requested"
669+
(session/message {:op "inspect-clear"})
670+
(is+ (matchers/prefix ["--- Analytics:" [:newline] #"Press 'y' or M-x"])
671+
(value-skip-header (session/message {:op "eval"
672+
:inspect "true"
673+
:code "(range 100)"
674+
:display-analytics-hint "true"})))))
675+
715676
(deftest print-length-independence-test
716677
(testing "*print-length* doesn't break rendering of long collections"
717678
(is (re-find #"showing page: \d+ of \d+"

test/clj/cider/test_helpers.clj

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,7 @@
55

66
(defmacro is+
77
"Like `is` but wraps expected value in matcher-combinators's `match?`."
8-
[expected actual & [message]]
9-
`(is (~'match? ~expected ~actual) ~@(when message [message])))
8+
([expected actual]
9+
`(is+ ~expected ~actual nil))
10+
([expected actual message]
11+
`(is (~'match? ~expected ~actual) ~message)))

0 commit comments

Comments
 (0)