Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## master (unreleased)

- [#386](https://github.com/clojure-emacs/orchard/pull/386): Inspector: rename default view mode for unknown objects to `:object`.
- [#397](https://github.com/clojure-emacs/orchard/pull/397): Inspector: add support for diffing sets.

## 0.41.0 (2026-04-13)

Expand Down
2 changes: 1 addition & 1 deletion build/main.clj
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,4 @@
(b/install opts))

;; To recompile Java class at runtime:
;; ((requiring-resolve 'virgil/compile-java) ["src"])
;; ((requiring-resolve 'virgil/compile-java) ["src" "test"])
21 changes: 17 additions & 4 deletions src/orchard/inspect.clj
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
(:require
[clojure.core.protocols :refer [datafy nav]]
[clojure.reflect :as reflect]
[clojure.set :as set]
[clojure.string :as str]
[orchard.inspect.analytics :as analytics]
[orchard.java.compatibility :as compat]
Expand Down Expand Up @@ -1258,6 +1259,13 @@
(assoc :view-mode (first (supported-view-modes inspector)))
inspect-render))))

(declare diff)

(defn- diff-sequences [s1 s2]
(let [n (max (count s1) (count s2))]
(mapv #(diff (nth s1 % print/nothing) (nth s2 % print/nothing))
(range n))))

(defn diff
"Perform a recursive diff on two values and return a structure suitable to be
viewed with the inspector."
Expand All @@ -1266,10 +1274,7 @@
(not= (class d1) (class d2)) (print/->Diff d1 d2)

(and (sequential? d1) (sequential? d2))
(let [n (max (count d1) (count d2))]
(->> (mapv #(diff (nth d1 % print/nothing) (nth d2 % print/nothing))
(range n))
print/->DiffColl))
(print/->DiffColl (diff-sequences d1 d2))

(and (map? d1) (map? d2))
(print/->DiffColl
Expand All @@ -1279,4 +1284,12 @@
[k (diff (get d1 k print/nothing) (get d2 k print/nothing))]))
(into {})))

(and (set? d1) (set? d2))
(let [common (set/intersection d1 d2)
subset1 (vec (set/difference d1 d2))
subset2 (vec (set/difference d2 d1))]
(print/->DiffColl
(-> (into #{} common) ;; If common is a sorted-set, turn into regular.
(into (diff-sequences subset1 subset2)))))

:else (print/->Diff d1 d2)))
1 change: 1 addition & 0 deletions src/orchard/print.clj
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@
coll))
(sequential? coll) (mapv #(if (diff-result? %) % nothing)
coll)
(set? coll) (set (filter diff-result? coll))
:else coll))

(defmethod print DiffColl [^DiffColl x, ^Writer w]
Expand Down
9 changes: 9 additions & 0 deletions test/orchard/inspect_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -1794,6 +1794,15 @@
render
(section "Diff contents")))

(testing "diff sets"
;; Complicated regexp is used to match because the order of elements in a
;; set is not predictable.
(is+ [" " [:value ":a" pos?] " = " [:value #"#≠#\{((2|3|#±\[1 ~~ 4\]) ?){3}\}" pos?]]
(-> (inspect/diff {:a #{1 2 3}} {:a #{2 3 4}})
inspect
render
(section "Diff contents"))))

(testing "in :only-diff mode, render only differing subvalues"
(is+ {"Diff contents"
[" 0. " [:value "#≠{:tea/type #±[\"Jinxuan Oolong\" ~~ \"Jinxuan Wulong\"], :aliases #≠[ #±[\"Jinxuan\" ~~ \"金宣\"] #±[ ~~ \"Jinxuan\"]], :temperature #±[80 ~~ 75]}" pos?] [:newline]
Expand Down