diff --git a/.travis.yml b/.travis.yml index f0aed7b..6bb686c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ language: clojure notifications: email: false +script: lein trampoline test diff --git a/CHANGELOG.md b/CHANGELOG.md index eee6ce9..0f757af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ +## 0.4.0 + * Fixed the diff-dispatching interface to correctly diff types - in particular, resolves a bug when diffing hash-maps and array-maps. + * Changed the behavior of `source` at the REPL to be colorized. + * Adds support for custom whidbey/puget options, including specifying the width. + * Updated dependencies. + ## 0.3.4 - * Updated dependencies. Should set the stage for ClojureScript support. + * Updated dependencies. ## 0.3.3 * Add a bugfix for a colorscheme configuration issue that was introduced in 0.3.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e4e9384..a4220de 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,3 +5,12 @@ Got something to make Ultra even more awesome? Radical. Let's talk about how to ## Filing Issues Ultra is composed of multiple dependencies, features, and code paths. When filing an issue, particularly related to bugs or performance problems, it's really helpful to narrow down which component of Ultra is responsible for the problem in question. Please [selectively disable](https://github.com/venantius/ultra#configuration) Ultra's features until you figure out which of the main four features is responsible for the behavior you're reporting. + +In addition, it's helpful to include the following information: + - Your JDK version + - Your Leiningen version + - Which version of Ultra you're using + +## Tests + +I will be the first person to admit that this library is quite short on test coverage. That has become something of a problem over time, with PRs being submitted with breaking changes in other, unexpected areas. My policy going forward is going to be to require tests as part of a pull request; I simply can't keep accepting pull requests that I have to go back and re-write later because the original author didn't test the new behavior thoroughly enough. diff --git a/README.md b/README.md index d425566..1734352 100644 --- a/README.md +++ b/README.md @@ -12,21 +12,23 @@ I've written a blog post describing Ultra in greater depth [here](http://blog.ve ## Installation -To install and configure Ultra, add something like the following to your `~/.lein/profiles.clj` +To install Ultra, just add the following to your `~/.lein/profiles.clj` ```clojure -{:user {:plugins [[venantius/ultra "0.3.4"]] - :ultra {:color-scheme :solarized_dark}}} +{:user {:plugins [[venantius/ultra "0.4.0"]]}} ``` ### Requirements -Leiningen version 2.5.2+ +As of Ultra `0.4.0`, Clojure 1.7.x is required due to reader conditional usage in Ultar's dependencies. +Ultra `0.3.4` is the last version supporting Clojure 1.6.x + +Leiningen version 2.5.2+ JDK 7+ #### ClojureScript Support -At the moment, Ultra doesn't have ClojureScript support at the REPL. See https://github.com/brandonbloom/fipp/issues/7. +At the moment, Ultra doesn't have ClojureScript support at the REPL. The relevant upstream issue to track work on this is https://github.com/greglook/puget/issues/27; from there, Whidbey will need to be updated, and then Ultra will be able to consume the changes. ## Features For a detailed list of features, check out the [wiki](https://github.com/venantius/ultra/wiki). Here's the highlight reel: @@ -45,14 +47,13 @@ For a detailed list of features, check out the [wiki](https://github.com/venanti ## Configuration -All of the above features are enabled by default, but can be turned off by setting a `false` flag in your profile. If you wanted Ultra to essentially no-op, your profile would look like this: +All of the above features are enabled by default, but can be turned off by setting a `false` flag in your profile. If you wanted Ultra to essentially no-op, your configuration map would look like this: ```clojure -{:user {:plugins [[venantius/ultra "0.3.4"]] - :ultra {:repl false - :stacktraces false - :tests false - :java false}}} +{:ultra {:repl false + :stacktraces false + :tests false + :java false}}}} ``` ### Color schemes @@ -64,22 +65,57 @@ At the moment Ultra supports the following color schemes: If you want to set the colors yourself instead of using a theme you can configure them directly, e.g.: ```clojure -{:user {:plugins [[venantius/ultra "0.3.4"]] - :ultra {:color-scheme {:delimiter [:red] - :tag [:red] - :nil [:cyan] - :boolean [:cyan] - :number [:cyan] - :string [:cyan] - :character [:cyan] - :keyword [:green] - :symbol nil - :function-symbol [:blue] - :class-delimiter [:blue] - :class-name nil - :exception nil}}}} +{:ultra {:color-scheme {:delimiter [:red] + :tag [:red] + :nil [:cyan] + :boolean [:cyan] + :number [:cyan] + :string [:cyan] + :character [:cyan] + :keyword [:green] + :symbol nil + :function-symbol [:blue] + :class-delimiter [:blue] + :class-name nil + :exception nil}}} ``` +### Additional REPL Configuration + +Ultra uses [Whidbey](https://github.com/greglook/whidbey) as its pretty-printing engine, and supports all of Whidbey's configuration flags. + +```clojure +{:ultra {:repl {:width 180 + :map-delimiter "" + :extend-notation true + :print-meta true + ...}}} +``` + +###### `:width` + +Number of characters to try to wrap pretty-printed forms at. + +###### `:print-meta` + +If true, metadata will be printed before values. + +###### `:sort-keys` + +Print maps and sets with ordered keys. Defaults to true, which will sort all collections. If a number, counted collections will be sorted up to the set size. Otherwise, collections are not sorted before printing. + +###### `:map-delimiter` + +The text placed between key-value pairs in a map. + +###### `:map-coll-separator` + +The text placed between a map key and a collection value. The keyword :line will cause line breaks if the whole map does not fit on a single line. + +###### `:seq-limit` + +If set to a positive number, then lists will only render at most the first n elements. This can help prevent unintentional realization of infinite lazy sequences. + ## Contributing Please open an issue here before submitting pull requests; I prefer to have documentation and consensus that either of our time will be well spent by working on it. When opening an issue -- particularly for bugs -- please refer to [CONTRIBUTING.md](https://github.com/venantius/ultra/blob/master/CONTRIBUTING.md) diff --git a/project.clj b/project.clj index a58c1f4..8c0dae8 100644 --- a/project.clj +++ b/project.clj @@ -1,16 +1,20 @@ -(defproject venantius/ultra "0.3.4" +(defproject venantius/ultra "0.4.0" :description "Ultra: A Leiningen plugin for a superior development environment" :url "http://github.com/venantius/ultra" :license {:name "Eclipse Public License" :url "http://www.eclipse.org/legal/epl-v10.html"} :dependencies [[org.clojure/clojure "1.7.0"] - [org.clojure/tools.nrepl "0.2.10"] + [org.clojure/tools.nrepl "0.2.11"] + [im.chit/hara.class "2.2.11"] + [im.chit/hara.reflect "2.2.11"] [io.aviso/pretty "0.1.18"] - [mvxcvi/whidbey "1.0.0"] - [mvxcvi/puget "0.8.1"] + [mvxcvi/whidbey "1.1.1"] + [mvxcvi/puget "0.9.2"] + [org.clojars.brenton/google-diff-match-patch "0.1"] [robert/hooke "1.3.0"] - [org.clojars.brenton/google-diff-match-patch "0.1"]] + [venantius/glow "0.1.2"]] :test-selectors {:default (complement :demo) :demo :demo} + :min-lein-version "2.5.2" :eval-in-leiningen true) diff --git a/src/ultra/colorscheme.clj b/src/ultra/colorscheme.clj index 5423fa1..af9edc4 100644 --- a/src/ultra/colorscheme.clj +++ b/src/ultra/colorscheme.clj @@ -3,7 +3,7 @@ [clojure.java.io :as io] [io.aviso.exception] [puget.color.ansi :as ansi] - [whidbey.render])) + [whidbey.repl])) (defn valid-colorscheme? [k] @@ -60,7 +60,7 @@ color-scheme (load-colorscheme color-scheme))] (alter-var-root - #'whidbey.render/options + #'whidbey.repl/printer merge - (assoc opts :color-scheme color-scheme)) + {:color-scheme color-scheme}) (set-pretty-colors color-scheme))) diff --git a/src/ultra/hardcore.clj b/src/ultra/hardcore.clj index b7558a0..d64e6dd 100644 --- a/src/ultra/hardcore.clj +++ b/src/ultra/hardcore.clj @@ -1,6 +1,7 @@ (ns ultra.hardcore "See what I did there?" (:require [clojure.tools.nrepl.server] + [ultra.colorscheme :as colorscheme] [robert.hooke :refer [add-hook]])) (def configured? (atom {})) @@ -48,8 +49,7 @@ "Dynamically import ultra's colorscheme namespace and configures it." {:added "0.3.0"} [opts] - `(do ~(require 'ultra.colorscheme) - (ultra.colorscheme/set-colorscheme ~opts))) + `(colorscheme/set-colorscheme ~opts)) (defn run-configuration "Initialize and configure Ultra's various components." @@ -81,5 +81,5 @@ [opts] (add-hook #'clojure.test/try-expr (fn [f & args] - (configure! opts) + (configure! (assoc opts :repl false)) (apply f args)))) diff --git a/src/ultra/plugin.clj b/src/ultra/plugin.clj index 38e3465..fe389b0 100644 --- a/src/ultra/plugin.clj +++ b/src/ultra/plugin.clj @@ -13,7 +13,7 @@ (if (not (false? repl)) (-> project (plugin/set-interactive-eval-renderer - 'whidbey.render/render-str) + 'whidbey.repl/render-str) (plugin/add-nrepl-middleware `clojure.tools.nrepl.middleware.render-values/render-values)) project)) @@ -36,11 +36,7 @@ [project opts] (-> project (plugin/add-dependencies - (plugin/plugin-dependency project 'venantius/ultra) - ['mvxcvi/puget "0.8.1"] - ['mvxcvi/whidbey "1.0.0"] - ['im.chit/hara.class "2.2.7"] - ['im.chit/hara.reflect "2.2.7"]) + (plugin/plugin-dependency project 'venantius/ultra)) (update-in [:injections] concat `[(require 'ultra.hardcore) (ultra.hardcore/add-test-hooks! ~opts)]) (assoc :monkeypatch-clojure-test false) diff --git a/src/ultra/printer.clj b/src/ultra/printer.clj index 6102535..3d437f3 100644 --- a/src/ultra/printer.clj +++ b/src/ultra/printer.clj @@ -1,9 +1,9 @@ (ns ultra.printer (:require [puget.printer :as printer] - [whidbey.render :as render])) + [whidbey.repl :as repl])) (defn cprint "Puget's cprint, set to always use the Puget options." {:added "0.1.3"} [x] - (printer/cprint x render/options)) + (printer/cprint x repl/printer)) diff --git a/src/ultra/printer/escape_hatch.clj b/src/ultra/printer/escape_hatch.clj deleted file mode 100644 index 2fc06af..0000000 --- a/src/ultra/printer/escape_hatch.clj +++ /dev/null @@ -1,17 +0,0 @@ -(ns ultra.printer.escape-hatch - "Hooks into `puget.printer` that are intended as an escape hatch for - custom data types." - (:require [puget.data :as data] - [puget.printer :refer [format-doc]])) - -(def escaped-classes - #{"class datomic.db.Db"}) - -(intern - 'puget.printer - 'formatter-dispatch - (fn [value] - (cond - (satisfies? data/ExtendedNotation value) ::tagged-literal - (escaped-classes (str (class value))) :default - :else (type value)))) diff --git a/src/ultra/repl.clj b/src/ultra/repl.clj index 56f26a0..10d97da 100644 --- a/src/ultra/repl.clj +++ b/src/ultra/repl.clj @@ -2,23 +2,33 @@ (:require [clojure.main :as main] [clojure.repl :as repl] [clojure.tools.nrepl.server] + [glow.core :as glow] [io.aviso.repl :as pretty-repl] - [ultra.printer :refer [cprint]] - [ultra.printer.escape-hatch])) + [ultra.printer :refer [cprint]])) -(defmacro pprint-source +(defmacro source "Prints the source code for the given symbol, if it can find it. This requires that the symbol resolve to a Var defined in a namespace for which the .clj is in the classpath. - Example: (source filter) - - Note that unlike clojure.repl/source, this fn can execute code, and - as such should only be used with trusted sources." + Example: (source filter)" {:added "0.2.1"} [n] - `(cprint (read-string (or (clojure.repl/source-fn '~n) - (str "Source not found"))))) + `(if-let [source# (clojure.repl/source-fn '~n)] + (println (glow/highlight source#)) + (println "Source not found"))) + +(defn replace-source + "First, re-define `clojure.repl/source (which is a macro) to be false. + Then, install our new preferred macro in its place. + + Note: I'm happy with how this works, but not the code itself. Odds are good + that I'll try to refactor this in the future." + {:added "0.3.5"} + [] + (binding [*ns* (the-ns 'clojure.repl)] + (require '[glow.core :as glow]) + (eval (read-string (repl/source-fn 'ultra.repl/source))))) (defn add-middleware "Alter the default handler to include the provided middleware" @@ -46,7 +56,9 @@ [repl stacktraces] (when (not (false? repl)) (require 'ultra.repl.whidbey) - (eval '(ultra.repl.whidbey/add-whidbey-middleware))) + (require 'whidbey.repl) + (eval '(ultra.repl.whidbey/add-whidbey-middleware)) + (eval `(whidbey.repl/update-options! ~repl)) + (replace-source)) (when (not (false? stacktraces)) (add-pretty-middleware))) - diff --git a/src/ultra/test.clj b/src/ultra/test.clj index 8d3b50d..daa7a7d 100644 --- a/src/ultra/test.clj +++ b/src/ultra/test.clj @@ -3,9 +3,7 @@ (:require [clojure.data :as data] [clojure.pprint :as pp] [puget.color.ansi :as ansi] - [puget.printer :as printer] - [ultra.test.diff :as diff] - [whidbey.render :as render])) + [ultra.test.diff :as diff])) (defn generate-diffs diff --git a/src/ultra/test/diff.clj b/src/ultra/test/diff.clj index 2161200..8b9d2e7 100644 --- a/src/ultra/test/diff.clj +++ b/src/ultra/test/diff.clj @@ -55,9 +55,11 @@ (fn [a b actual expected] (cond (and (string? a) (string? b)) ::diff-strs - (and (vector? a) (vector? b)) ::diff-vecs - (and (list? a) (list? b)) ::diff-vecs - (not= (class a) (class b)) ::wrong-class + (and (vector? actual) (vector? expected)) ::diff-vecs + (and (list? actual) (list? expected)) ::diff-vecs + (and (not= (class a) (class b)) + (some? a) + (some? b)) ::wrong-class :default [a b actual expected]))) (defmethod prn-diffs ::diff-strs @@ -71,8 +73,8 @@ (print-expected actual expected) (let [puget-str (fn [x] (s/trim-newline (with-out-str (cprint x))))] (print "\nexpected: ") - (let [a (with-out-str (println (puget-str b) - "to be an instance of" + (let [a (with-out-str (println (puget-str b) + "to be an instance of" (class a))) b (with-out-str (println (puget-str b) "is an instance of"