Skip to content

Commit

Permalink
All 0.1.4 changes (see changelog)
Browse files Browse the repository at this point in the history
  • Loading branch information
trevor-brandt committed Dec 31, 2021
1 parent 289a2a8 commit b0cbe48
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 45 deletions.
15 changes: 12 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@

## [Unreleased]

## [0.1.4] - TODO: DATE
### Added
- Fixed an issue where nested data-scope reader tags will result in the outer tag
pretty-printing macroexpanded forms from the inner tag. The fix ignores inner tags
when pretty-printing content for the outer tag.
E.g., in `#pp (->> [1 2 3] #pp->> (map inc) (apply +))`, the fix will ignore `#pp->>`
in the pretty-printed output of `#pp`.

## [0.1.3] - 2020-12-23 (forked from jsofra/data-scope)
### Added
- Previously unreleased support for thread-first and thread-last `pp` macros (`ds/pp->` and `ds/pp->>`), with new unit tests.
- Combined all namespaces into one all-encompassing, easy-to-utilize namespace for quick debugging: `ds`
- Combined all namespaces into one all-encompassing, easy-to-utilize namespace, `ds` for quick use during debugging.
- Created shorter, un-namespaced versions of the `pp` macros. (Not technically Clojure best practice, but practical for a debug tool.)
- Added namespace, line number, and output of the original inspected form to the `pp` macros.
- Revved all the dependency versions.
Expand All @@ -26,8 +34,9 @@
### Added
- Initial Release!

[Unreleased]: https://github.com/jsofra/data-scope/compare/0.1.3...HEAD
[0.1.3]: https://github.com/tervorz/data-scope/compare/0.1.2..0.1.3
[Unreleased]: https://github.com/jsofra/data-scope/compare/0.1.4...HEAD
[0.1.4]: https://github.com/tervorz/data-scope/compare/0.1.3...0.1.4
[0.1.3]: https://github.com/tervorz/data-scope/compare/0.1.2...0.1.3
[0.1.2]: https://github.com/tervorz/data-scope/compare/0.1.1...0.1.2
[0.1.1]: https://github.com/tervorz/data-scope/compare/0.1.0...0.1.1
[0.1.0]: https://github.com/tervorz/data-scope/compare/0.1.0-SNAPSHOT...0.1.0
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ which was inspired by [Spyscope](https://github.com/dgrnbrg/spyscope).

#### Leiningen

Add `[tervorz/data-scope "0.1.3"]` to your project.clj's `:dependencies`.
Add `[tervorz/data-scope "0.1.4"]` to your project.clj's `:dependencies`.

If you want data-scope to be automatically loaded and available in every project's
`user` namespace, add the following to the `:user` profile in `~/.lein/profiles.clj`:

:dependencies [[tervorz/data-scope "0.1.3"]]
:dependencies [[tervorz/data-scope "0.1.4"]]
:injections [(require 'ds)]

#### Boot
Expand All @@ -32,7 +32,7 @@ After requiring the namespace, you must also run `(boot.core/load-data-readers!)
to get the reader tags working. Using a `~/.boot/profile.boot` file:

``` clojure
(set-env! :dependencies #(conj % '[tervorz/data-scope "0.1.3"]))
(set-env! :dependencies #(conj % '[tervorz/data-scope "0.1.4"]))
(boot.core/load-data-readers!)
(require 'ds)
```
Expand All @@ -54,7 +54,7 @@ To use in any namespace, you'll need to `require` it:
(apply +)))
```

Currently there are readers tags for visualizing data as both charts, graphs, tables and trees.
Currently there are reader tags for visualizing data as either charts, graphs, tables and trees.
There is also support for pretty printing data. See all the usage examples below for the details.

### Inspectors
Expand Down
14 changes: 7 additions & 7 deletions project.clj
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
(defproject tervorz/data-scope "0.1.3"
(defproject tervorz/data-scope "0.1.4"
:description "Tools for interactively examining data."
:url "https://github.com/tervorz/data-scope"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.10.1"]
:dependencies [[org.clojure/clojure "1.10.3"]
;; explicit include to remedy CVE-2020-15250 in incanter-core
[junit "4.13.1"]
[junit "4.13.2"]
[incanter/incanter-core "1.9.3" :exclusions [junit]]
[incanter/incanter-charts "1.9.3"]
[hashp "0.2.0"]
[hashp "0.2.1"]
[rhizome "0.2.9"]
[mvxcvi/puget "1.3.1"]
[org.clojure/core.cache "1.0.207"]]
[mvxcvi/puget "1.3.2"]
[org.clojure/core.cache "1.0.225"]]
:plugins [[lein-cloverage "1.1.1"]
[lein-nvd "1.3.1"]]
:profiles {:repl {:dependencies [[org.clojure/tools.namespace "1.1.0"]]}})
:profiles {:repl {:dependencies [[org.clojure/tools.namespace "1.2.0"]]}})
63 changes: 39 additions & 24 deletions src/data_scope/pprint.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,51 @@

(defn print-table [[f :as data]]
(->> (cond
(map? f) [data]
(sequential? f) [(range (count (first data)))
(map #(into {} (map-indexed vector %)) data)])
(apply clojure.pprint/print-table)))
(map? f) [data]
(sequential? f) [(range (count (first data)))
(map #(into {} (map-indexed vector %)) data)])
(apply clojure.pprint/print-table)))

(defn print-and-return
[form evaluated]
(println)
(location-line-and-form form evaluated)
(puget.printer/cprint evaluated)
(println)
evaluated)

(defn pprint-wrapper
"A wrapper that helps the pretty-printer identify whether or not there's a
nested ds macro expansion in pretty-printed output."
([form]
(print-and-return form (eval form)))
([form thread-type]
(fn [threaded-arg]
(let [form-as-list (if (not (list? form))
(list form)
form)
[f & args] (when (list? form-as-list) form-as-list)
quoted-arg `(quote ~threaded-arg)
evaluated (case thread-type
:first (->> quoted-arg
(conj (seq args))
(cons f)
eval)
:last (-> form-as-list
vec
(conj quoted-arg)
seq
eval))]
(print-and-return form evaluated)))))

(defn scope-pprint [form]
`(let [form# ~form]
(println)
(~location-line-and-form '~form form#)
('~puget.printer/cprint form#)
(println)
form#))
`(pprint-wrapper '~form))

(defn scope-pprint-thread-last [form]
`((fn [x#]
(let [form# (->> x# ~form)]
(println)
(~location-line-and-form '~form form#)
('~puget.printer/cprint form#)
(println)
form#))))
`((pprint-wrapper '~form :last)))

(defn scope-pprint-thread-first [form]
`((fn [x#]
(let [form# (-> x# ~form)]
(println)
(~location-line-and-form '~form form#)
('~puget.printer/cprint form#)
(println)
form#))))
`((pprint-wrapper '~form :first)))

(defn scope-print-table [form]
`(let [form# ~form]
Expand Down
56 changes: 49 additions & 7 deletions src/ds.clj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
[clojure.inspector]
[clojure.pprint :as pprint]
[clojure.string :as str]
[clojure.walk]
[clojure.walk :as w]
[hashp.core :as hashp]
[incanter.charts]
[incanter.core]
Expand All @@ -21,23 +21,65 @@
(->> (hashp/current-stacktrace)
(filter :clojure)
(remove (comp (partial = "ds") :ns))
(remove (every-pred
(comp (partial = "clojure.core") :ns)
(comp not-empty :fn)
(comp #(str/starts-with? % "eval") :fn)))
first)]
(if (and ns fn line)
(format "[%s/%s:%s]" ns fn line)
"[location unknown]")))

(defn filter-form
"If `form` already contains macroexpanded pretty-print output, filter out the
macro expanded content to just return the original form for prettier printing.
Example of code where a data-scope reader macro is nested in another and might
require filtering:
#pp (->> [1 2 3]
#pp->> (map inc)
(apply +))
The above example has a #pp->> macro that results in macroexpanded output to
#pp, so we try to filter that noise out from the #pp output."
[form]
(cond
;; if your form isn't a collection, we don't need to worry about
;; filtering out noise
(not (coll? form))
form

;; threaded printed items will have a form that looks like:
;; `((ds/pprint-wrapper (quote original-form)))`
(and (= 1 (count form))
(coll? (first form))
(= 'ds/pprint-wrapper (ffirst form)))
(second (second (first form)))

;; regular pretty-printed items look like:
;; `(ds/pprint-wrapper (quote original-form))`
(= 'ds/pprint-wrapper (first form))
(second (second form))

;; if the form is a collection but isn't wrapped with pprint, then the
;; form doesn't have any nested pretty-print macros
:else
form))

(defn location-line-and-form
"Prints the namespace, fn, and line where the literal was placed, and also
prints the original form that is being inspected if it's different than the
result of evaluating that form."
[form evaluated]
(if (not= evaluated form)
(let [orig-form# (with-out-str (pprint/pprint form))]
(if (= evaluated form)
`~(println (current-trace) "=>")
(let [orig-form# (->> form
(w/prewalk filter-form)
pprint/pprint
with-out-str)]
`~(println (current-trace)
(clojure.string/trim-newline (or orig-form# "")) ;; nil-safe
"=>"))
`~(println (current-trace)
"=>")))
(str/trim-newline (or orig-form# "")) ;; nil-safe
"=>"))))

(load "data_scope/charts")
(load "data_scope/graphs")
Expand Down

0 comments on commit b0cbe48

Please sign in to comment.