-
Notifications
You must be signed in to change notification settings - Fork 3
/
diff.clj
47 lines (38 loc) · 1.6 KB
/
diff.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
(ns nsorg.cli.diff
(:require [clojure.term.colors :as colors]))
(defn partition-chunks [lines]
(->> lines
(map-indexed vector)
(partition-by (fn [[i {:keys [type line]}]] [type (- line i)]))
(map (partial map second))))
(defn expand-context [lines distance]
(set (for [line lines
delta (range (- distance) (inc distance))]
(+ line delta))))
(defn line-diffs [s1 s2]
(let [ls1 (clojure.string/split-lines s1)
ls2 (clojure.string/split-lines s2)
diff-lines (set (filter identity (map (fn [i l1 l2] (when-not (= l1 l2) i)) (range) ls1 ls2)))
context-lines (expand-context diff-lines 3)]
(filter identity (map (fn [i l1 l2]
(cond
(diff-lines i) {:type :diff :line i :from l1 :to l2}
(context-lines i) {:type :context :line i :content l1}))
(range)
ls1
ls2))))
(defn context-line [s]
(str " " s))
(defn removed-line [s]
(colors/red (str "-" s)))
(defn added-line [s]
(colors/green (str "+" s)))
(defn chunk->str [chunk]
(clojure.string/join \newline (case (:type (first chunk))
:context (map (comp context-line :content) chunk)
:diff (concat (map (comp removed-line :from) chunk)
(map (comp added-line :to) chunk)))))
(defn diff-chunks [s1 s2]
(partition-chunks (line-diffs s1 s2)))
(defn format-diff [chunks]
(clojure.string/join \newline (map chunk->str chunks)))