From 62371e3b8b66cb9b704d576ca883493fd21ed420 Mon Sep 17 00:00:00 2001 From: Oleksandr Yakushev Date: Fri, 3 Jul 2026 11:37:05 +0300 Subject: [PATCH] [inspector] Render ARef contents fully like normal values --- CHANGELOG.md | 1 + src/orchard/inspect.clj | 42 +++++++++++++++++--------------- test/orchard/inspect_test.clj | 45 +++++++++++++++++++++++------------ 3 files changed, 54 insertions(+), 34 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f71bd588..d4b9ee28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## master (unreleased) - [#406](https://github.com/clojure-emacs/orchard/pull/406): Inspector: remove Datafy section. +- [#408](https://github.com/clojure-emacs/orchard/pull/408): Inspector: render ARef contents fully. ## 0.43.0 (2026-06-24) diff --git a/src/orchard/inspect.clj b/src/orchard/inspect.clj index 05365099..7d8b1f9f 100644 --- a/src/orchard/inspect.clj +++ b/src/orchard/inspect.clj @@ -90,7 +90,10 @@ (throw (ex-info (str "Precondition failed: " (pr-str '~x)) {})))) (defn- pageable? [obj] - (contains? #{:list :map :set :array} (object-type obj))) + (let [ot (object-type obj) + pageable-colls #{:list :map :set :array}] + (or (contains? pageable-colls ot) + (and (= ot :aref) (contains? pageable-colls (object-type @obj)))))) (defn- counted-length [{:keys [page-size]} obj] (cond (instance? clojure.lang.Counted obj) (count obj) @@ -109,6 +112,9 @@ (* page-size 16) ;; In hex view mode, each row is 16 bytes. page-size) start-idx (* current-page page-size) + ;; Deref early to paginate ARef contents + value (cond-> value + (instance? clojure.lang.ARef value) deref) ;; Sort maps early to ensure proper paging. sort-map? (and (= (object-type value) :map) sort-maps) value (if sort-map? @@ -605,7 +611,7 @@ (defn- render-collection-paged "Render a single page of either an indexed or associative collection." - [{:keys [value chunk start-idx] :as inspector}] + [{:keys [chunk start-idx] :as inspector} value] (let [type (object-type value)] (-> inspector (render-leading-page-ellipsis) @@ -676,6 +682,13 @@ ins lines) (render-trailing-page-ellipsis ins)))) +(defn- render-identity-hash-code [inspector obj] + (let [code (System/identityHashCode obj)] + (-> inspector + (render-indent (format "Identity hash code: %s (0x%s)" + (str code) (Integer/toHexString code))) + (render-ln)))) + ;; Inspector multimethod (defn- dispatch-inspect [{:keys [view-mode] :as _ins} obj] (if (= view-mode :object) @@ -710,7 +723,7 @@ (render-analytics) (render-section-header "Contents") (indent) - (render-collection-paged) + (render-collection-paged obj) (unindent) (render-page-info))) @@ -727,7 +740,7 @@ (indent ins) (if (= (:view-mode inspector) :hex) (render-hexdump ins) - (render-collection-paged ins)) + (render-collection-paged ins obj)) (unindent ins) (render-page-info ins))) @@ -748,7 +761,7 @@ (defmethod inspect :string [inspector ^java.lang.String obj] (-> (render-class-name inspector obj) - (render "Value: " (print-string inspector obj)) + (render-indent "Value: " (print-string inspector obj)) (render-ln) (render-indent-ln "Length: " (str (.length obj))) (render-section-header "Print") @@ -821,17 +834,11 @@ (into (sorted-map))) false) (unindent)) - inspector)) - (render-ident-hashcode [inspector] - (let [code (System/identityHashCode obj)] - (-> inspector - (render "Identity hash code: " (str code) " " - (format "(0x%s)" (Integer/toHexString code))) - (render-ln))))] + inspector))] (cond-> inspector true (render-labeled-value "Class" (class obj)) true (render-labeled-value "Value" obj {:display-value printed}) - true (render-ident-hashcode) + true (render-identity-hash-code obj) (seq non-static-accessible) (render-fields "Instance fields" non-static-accessible) (seq static-accessible) (render-fields "Static fields" static-accessible) (seq non-static-nonaccessible) (render-fields "Private instance fields" non-static-nonaccessible) @@ -1002,15 +1009,12 @@ (defmethod inspect :aref [inspector ^clojure.lang.ARef obj] (let [val (deref obj)] (-> (render-class-name inspector obj) + (render-identity-hash-code obj) + (render-labeled-value "Deref" val) (render-meta-information obj) (render-section-header "Deref") (indent) - (render-class-name val) - (render-counted-length val) - (render-section-header "Contents") - (indent) - (render-value-maybe-expand val) - (unindent) + (inspect val) (unindent)))) (defmethod inspect DiffColl [{:keys [only-diff] :as inspector} ^DiffColl obj] diff --git a/test/orchard/inspect_test.clj b/test/orchard/inspect_test.clj index ccb38977..9f9517cc 100644 --- a/test/orchard/inspect_test.clj +++ b/test/orchard/inspect_test.clj @@ -868,48 +868,63 @@ (deftest inspect-atom-test (testing "inspecting an atom" (is+ {nil - ["Class: " [:value "clojure.lang.Atom" 0]] + ["Class: " [:value "clojure.lang.Atom" 0] [:newline] + #"^Identity hash code:" [:newline] + "Deref: " [:value "{:a 1}" pos?]] "Deref" - [" Class: " [:value "clojure.lang.PersistentArrayMap" 1] [:newline] + [" Class: " [:value "clojure.lang.PersistentArrayMap" pos?] [:newline] " Count: 1" [:newline] [:newline] " --- Contents:" [:newline] - " " [:value ":a" 2] " = " [:value "1" 3]]} + " " [:value ":a" pos?] " = " [:value "1" pos?]]} (-> (inspect (atom {:a 1})) render group-sections))) (testing "small collection is rendered fully" - (is+ [" Class: " [:value "clojure.lang.LongRange" 1] [:newline] + (is+ [" Class: " [:value "clojure.lang.LongRange" pos?] [:newline] " Count: 3" [:newline] [:newline] " --- Contents:" [:newline] - " 0. " [:value "0" 2] [:newline] - " 1. " [:value "1" 3] [:newline] - " 2. " [:value "2" 4]] + " 0. " [:value "0" pos?] [:newline] + " 1. " [:value "1" pos?] [:newline] + " 2. " [:value "2" pos?]] (-> (atom (range 3)) inspect render (section "Deref")))) - (testing "larger collection is rendered as a single value" - (is+ [" Class: " [:value "clojure.lang.LongRange" 1] [:newline] + (testing "larger collection is paged" + (is+ [" Class: " [:value "clojure.lang.LongRange" pos?] [:newline] " Count: 100" [:newline] [:newline] " --- Contents:" [:newline] - " " [:value "(0 1 2 3 4 ...)" 2]] - (-> (atom (range 100)) inspect render (section "Deref")))) + " 0. " [:value "0" pos?] [:newline] + " 1. " [:value "1" pos?] [:newline] + " 2. " [:value "2" pos?] [:newline] + " ..." [:newline] + [:newline] + " --- Page Info:" [:newline] + " Page size: 3, showing page: 1 of 34"] + (-> (atom (range 100)) (inspect {:page-size 3}) render (section "Deref")))) (testing "meta is shown on atoms" - (is+ [" " [:value ":foo" 1] " = " [:value "\"bar\"" 2]] + (is+ [" " [:value ":foo" pos?] " = " [:value "\"bar\"" pos?]] (-> (atom [1 2 3] :meta {:foo "bar"}) inspect render (section "Meta Information"))))) (deftest inspect-atom-infinite-seq-test (testing "inspecting an atom holding an infinite seq" (is+ {nil - ["Class: " [:value "clojure.lang.Atom" 0]] + ["Class: " [:value "clojure.lang.Atom" 0] [:newline] + #"^Identity hash code:" [:newline] + "Deref: " [:value "(1 1 1 1 1 ...)" pos?]] "Deref" - [" Class: " [:value "clojure.lang.Repeat" 1] [:newline] + [" Class: " [:value "clojure.lang.Repeat" pos?] [:newline] [:newline] " --- Contents:" [:newline] - " " [:value "(1 1 1 1 1 ...)" 2]]} + " 0. " [:value "1" pos?] [:newline] + " 1. " [:value "1" pos?] [:newline] + " 2. " [:value "1" pos?] [:newline] + " ..." [:newline] [:newline] + " --- Page Info:" [:newline] + " Page size: 3, showing page: 1 of ?"]} (-> (inspect (atom (repeat 1))) (set-page-size 3) render