 
 (defn pop-trace [printer]
   (update printer :trace rest))
-
-(defn- pretty-coll [printer open xs sep close f]
-  (let [xform (comp (map-indexed #(f printer %1 %2))
-                    (interpose sep))
-        ys (sequence xform xs)]
-    [:group open ys close]))
 
 (defrecord HighlightPrinter [base-printer trace]
   visit/IVisitor

    (wrap visit/visit-record this x))
  )

(defmethod render `s/tuple [{[n] :steps} _ printer x]
  (pretty-coll printer "[" x :line "]"
    (fn [printer i x]
      (visit/visit (cond-> printer (= i n) pop-trace) x))))

(defmethod render `s/map-of [{[key k-or-v] :steps} _ printer x]
  (pretty-coll printer "{" x [:span "," :line] "}"
    (fn [printer i [k v]]
      (let [kprinter (cond-> printer
                       (and (= k key) (= k-or-v 0))
                       pop-trace)
            vprinter (cond-> printer
                       (and (= k key) (= k-or-v 1))
                       pop-trace)]
        [:span (visit/visit kprinter k) " " (visit/visit vprinter v)]))))

(defn highlight-printer [trace]
  (let [base-printer (edn/map->EdnPrinter {:symbols {}})]
    (->HighlightPrinter base-printer trace)))

(defn pr-str [x]
  (with-out-str
    (pr x)))

;;
;; Method implementations of `render`
;;

(defn- pretty-coll [printer open xs sep close f]
  (let [xform (comp (map-indexed #(f printer %1 %2))
                    (interpose sep))
        ys (sequence xform xs)]
    [:group open ys close]))

(defn render-coll
  ([frame printer x]
   (render-coll frame printer x nil))
  ([{[n] :steps} printer x each-fn]
   (let [[open close] (cond (seq? x) ["(" ")"]
                            (vector? x) ["[" "]"]
                            (map? x) ["{" "}"]
                            (set? x) ["#{" "}"])
         sep (if (map? x) [:span "," :line] :line)
         each-fn (if each-fn
                   #(each-fn %2 %3)
                   (fn [_ i x]
                     (visit/visit (cond-> printer (= i n) pop-trace) x)))]
     (pretty-coll printer open x sep close each-fn))))

(defmethod render `s/tuple [frame _ printer x]
  (render-coll frame printer x))

(defn- render-every [{[n] :steps :as frame} printer x]
  (if (map? x)
    (render-coll frame printer x
      (fn [i [k v]]
        (let [printer (cond-> printer (= i n) pop-trace)]
          [:span (visit/visit printer k) " " (visit/visit printer v)])))
    (render-coll frame printer x)))

(defmethod render `s/every [frame _ printer x]
  (render-every frame printer x))

(defmethod render `s/coll-of [frame _ printer x]
  (render-every frame printer x))

(defn- render-every-kv [{[key k-or-v] :steps :as frame} printer x]
  (render-coll frame printer x
    (fn [i [k v]]
      (let [kprinter (cond-> printer
                       (and (= k key) (= k-or-v 0))
                       pop-trace)
            vprinter (cond-> printer
                       (and (= k key) (= k-or-v 1))
                       pop-trace)]
        [:span (visit/visit kprinter k) " " (visit/visit vprinter v)]))))

(defmethod render `s/every-kv [frame _ printer x]
  (render-every-kv frame printer x))

(defmethod render `s/map-of [frame _ printer x]
  (render-every-kv frame printer x))

(defmethod render `s/keys [{[key] :steps :as frame} _ printer x]
  (render-coll frame printer x
    (fn [i [k v]]
      (let [vprinter (cond-> printer (= k key) pop-trace)]
        [:span (visit/visit printer k) " " (visit/visit vprinter v)]))))
