Skip to content

Commit ad6cbb7

Browse files
[inspect] Add ability to sort maps by key
1 parent 039b069 commit ad6cbb7

File tree

3 files changed

+51
-6
lines changed

3 files changed

+51
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
- [#346](https://github.com/clojure-emacs/orchard/pull/346): Inspector: only show those datafied collection items that have unique datafy represantation.
66
- [#348](https://github.com/clojure-emacs/orchard/pull/348): Inspector: display length of inspected strings.
77
- [#348](https://github.com/clojure-emacs/orchard/pull/348): Inspector: display class flags.
8+
- [#349](https://github.com/clojure-emacs/orchard/pull/349): Inspector: add ability to sort maps by key.
89

910
## 0.35.0 (2025-05-28)
1011

src/orchard/inspect.clj

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
:max-nested-depth nil
4747
:display-analytics-hint nil
4848
:analytics-size-cutoff 100000
49+
:sort-maps false
4950
:pretty-print false})
5051

5152
(defn- reset-render-state [inspector]
@@ -100,11 +101,18 @@
100101
(defn- pagination-info
101102
"Calculate if the object should be paginated given the page size. Return a map
102103
with pagination info, or nil if object fits in a single page."
103-
[{:keys [page-size current-page view-mode value] :as inspector}]
104+
[{:keys [page-size current-page view-mode sort-maps value] :as inspector}]
104105
(let [page-size (if (= view-mode :hex)
105106
(* page-size 16) ;; In hex view mode, each row is 16 bytes.
106107
page-size)
107108
start-idx (* current-page page-size)
109+
;; Sort maps early to ensure proper paging.
110+
sort-map? (and (= (object-type value) :map) sort-maps)
111+
value (if sort-map?
112+
(try (sort-by key value)
113+
;; May throw if keys are not comparable.
114+
(catch Exception _ value))
115+
value)
108116
;; Try grab a chunk that is one element longer than asked in
109117
;; page-size. This is how we know there are elements beyond the
110118
;; current page.
@@ -114,18 +122,19 @@
114122
count+1 (count chunk+1)
115123
paginate? (or (> current-page 0) ;; In non-paginated it's always 0.
116124
(> count+1 page-size))
125+
chunk (cond-> chunk+1
126+
(> count+1 page-size) pop)
117127
clength (or (counted-length inspector value)
118128
(when (<= count+1 page-size)
119129
(+ (* page-size current-page) count+1)))
120130
last-page (if clength
121131
(quot (dec clength) page-size)
122132
;; Possibly infinite
123133
Integer/MAX_VALUE)]
124-
(when paginate?
125-
{:chunk (cond-> chunk+1
126-
(> count+1 page-size) pop)
127-
:start-idx start-idx
128-
:last-page last-page})))
134+
(cond paginate? {:chunk chunk
135+
:start-idx start-idx
136+
:last-page last-page}
137+
sort-map? {:chunk chunk})))
129138

130139
(defn- decide-if-paginated
131140
"Make early decision if the inspected object should be paginated. If so,

test/orchard/inspect_test.clj

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,6 +1736,41 @@
17361736
(is+ [#"--- View mode" [:newline] " ●normal object ●pretty"]
17371737
(section rendered "View mode")))))
17381738

1739+
(deftest sort-maps-test
1740+
(testing "with :sort-map-keys enabled, may keys are sorted"
1741+
(is+ (matchers/prefix
1742+
["--- Contents:" [:newline]
1743+
" " [:value "0" pos?] " = " [:value "0" pos?] [:newline]
1744+
" " [:value "1" pos?] " = " [:value "1" pos?] [:newline]
1745+
" " [:value "2" pos?] " = " [:value "2" pos?] [:newline]
1746+
" " [:value "3" pos?] " = " [:value "3" pos?] [:newline]])
1747+
(-> (zipmap (range 100) (range 100))
1748+
inspect
1749+
(inspect/refresh {:sort-maps true})
1750+
render
1751+
contents-section)))
1752+
1753+
(testing "works if map is smaller than page size"
1754+
(is+ ["--- Contents:" [:newline]
1755+
" " [:value "0" pos?] " = " [:value "0" pos?] [:newline]
1756+
" " [:value "1" pos?] " = " [:value "1" pos?] [:newline]
1757+
" " [:value "2" pos?] " = " [:value "2" pos?] [:newline]
1758+
" " [:value "3" pos?] " = " [:value "3" pos?] [:newline]
1759+
" " [:value "4" pos?] " = " [:value "4" pos?]]
1760+
(-> (zipmap (range 5) (range 5))
1761+
inspect
1762+
(inspect/refresh {:sort-maps true, :page-size 100})
1763+
render
1764+
contents-section)))
1765+
1766+
(testing "doesn't fail if keys are non-comparable"
1767+
(is+ (matchers/prefix ["--- Contents:"])
1768+
(-> {(byte-array 1) 1 (byte-array 2) 2}
1769+
inspect
1770+
(inspect/refresh {:sort-maps true})
1771+
render
1772+
contents-section))))
1773+
17391774
(deftest tap-test
17401775
(testing "tap-current-value"
17411776
(let [proof (atom [])

0 commit comments

Comments
 (0)