Skip to content

Commit 4d94630

Browse files
committed
Merge pull request #3 from archimag/simplify-create-generators.
simplifies the creation of "diff generators" outside the library
2 parents 7842213 + 84a195f commit 4d94630

File tree

2 files changed

+70
-27
lines changed

2 files changed

+70
-27
lines changed

diff.lisp

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,9 @@
241241
(incf modified-start (snake-length snake))
242242
(pop lcs)))))
243243

244+
(defun compute-raw-diff (origin modified)
245+
(convert-lcs-to-diff (compute-lcs origin modified)))
246+
244247

245248
;;; producing diffs in "unified diff" format
246249

@@ -252,10 +255,16 @@ of context; the default of three should be good enough for most situations.")
252255
(defclass diff ()
253256
((original-pathname :initarg :original-pathname :accessor original-pathname)
254257
(modified-pathname :initarg :modified-pathname :accessor modified-pathname)
258+
(window-class :initarg :window-class :reader diff-window-class)
255259
(windows :initform nil :accessor diff-windows)))
256260

257-
(defclass unified-diff (diff) ())
258-
(defclass context-diff (diff) ())
261+
(defclass unified-diff (diff) ()
262+
(:default-initargs
263+
:window-class 'unified-diff-window))
264+
265+
(defclass context-diff (diff) ()
266+
(:default-initargs
267+
:window-class 'context-diff-window))
259268

260269
(defclass diff-generator ()
261270
((interned-lines :initarg :interned-lines :reader interner)
@@ -314,13 +323,8 @@ of context; the default of three should be good enough for most situations.")
314323
(defun create-window (generator)
315324
(create-window-for-diff (diff generator)))
316325

317-
(defgeneric create-window-for-diff (diff))
318-
319-
(defmethod create-window-for-diff ((diff unified-diff))
320-
(make-instance 'unified-diff-window))
321-
322-
(defmethod create-window-for-diff ((context context-diff))
323-
(make-instance 'context-diff-window))
326+
(defun create-window-for-diff (diff)
327+
(make-instance (diff-window-class diff)))
324328

325329
(defun original-window-length (window)
326330
(reduce #'+ (window-chunks window)
@@ -463,6 +467,12 @@ of context; the default of three should be good enough for most situations.")
463467
:original-pathname original-pathname
464468
:modified-pathname modified-pathname)))
465469

470+
(defgeneric render-diff (diff stream)
471+
(:documentation "Print DIFF object to STREAM"))
472+
473+
(defgeneric render-diff-window (window stream)
474+
(:documentation "Print WINDOW to STREAM"))
475+
466476
(defun generate-diff (diff-kind original-pathname modified-pathname)
467477
"Compute a diff between ORIGINAL-PATHNAME and MODIFIED-PATHNAME.
468478
DIFF-KIND indicates the type of DIFF generated and should be the symbol
@@ -477,12 +487,21 @@ DIFF:UNIFIED-DIFF or DIFF:CONTEXT-DIFF."
477487
original-pathname original
478488
modified-pathname modified)))
479489
(walk-diff-regions context diff-regions)))))
480-
490+
491+
(defun format-diff (diff-kind original-pathname modified-pathname &optional (stream *standard-output*))
492+
(render-diff (generate-diff diff-kind
493+
original-pathname
494+
modified-pathname)
495+
stream))
496+
497+
(defun format-diff-string (diff-kind original-pathname modified-pathname)
498+
(with-output-to-string (out)
499+
(format-diff diff-kind original-pathname modified-pathname out)))
500+
481501
;;; printing diffs on streams
482502

483-
(defgeneric print-diff-window-header (window stream))
484503

485-
(defmethod print-diff-window-header ((window unified-diff-window) stream)
504+
(defmethod render-diff-window :before ((window unified-diff-window) stream)
486505
(let ((original-length (original-window-length window))
487506
(modified-length (modified-window-length window)))
488507
(format stream "@@ -~A" (1+ (original-start-line window)))
@@ -494,10 +513,10 @@ DIFF:UNIFIED-DIFF or DIFF:CONTEXT-DIFF."
494513
(write-string " @@" stream)
495514
(terpri stream)))
496515

497-
(defmethod print-diff-window-header ((window context-diff-window) stream)
516+
(defmethod render-diff-window :before ((window context-diff-window) stream)
498517
(format stream "***************~%"))
499518

500-
(defmethod print-object ((object unified-diff-window) stream)
519+
(defmethod render-diff-window ((object unified-diff-window) stream)
501520
(dolist (chunk (window-chunks object))
502521
(let ((prefix (ecase (chunk-kind chunk)
503522
(:common #\Space)
@@ -514,7 +533,7 @@ DIFF:UNIFIED-DIFF or DIFF:CONTEXT-DIFF."
514533
(defun window-contains-inserts-p (window)
515534
(some #'modified-chunk-p (window-chunks window)))
516535

517-
(defmethod print-object ((window context-diff-window) stream)
536+
(defmethod render-diff-window ((window context-diff-window) stream)
518537
(let ((original-length (1- (original-window-length window)))
519538
(original-start-line (1+ (original-start-line window)))
520539
(modified-length (1- (modified-window-length window)))
@@ -551,23 +570,17 @@ DIFF:UNIFIED-DIFF or DIFF:CONTEXT-DIFF."
551570
(write-string line stream)
552571
(terpri stream))))))))
553572

554-
(defgeneric print-diff-header (diff stream))
555-
556-
(defmethod print-diff-header ((diff unified-diff) stream)
573+
(defmethod render-diff :before ((diff unified-diff) stream)
557574
(format stream "--- ~A~%+++ ~A~%"
558575
(namestring (original-pathname diff))
559576
(namestring (modified-pathname diff))))
560577

561-
(defmethod print-diff-header ((diff context-diff) stream)
578+
(defmethod render-diff :before ((diff context-diff) stream)
562579
(format stream "*** ~A~%--- ~A~%"
563580
(namestring (original-pathname diff))
564581
(namestring (modified-pathname diff))))
565582

566-
(defmethod print-object :before ((object diff-window) stream)
567-
(print-diff-window-header object stream))
568-
569-
(defmethod print-object ((object diff) stream)
570-
(print-diff-header object stream)
583+
(defmethod render-diff ((object diff) stream)
571584
(dolist (window (diff-windows object))
572-
(print-object window stream)))
585+
(render-diff-window window stream)))
573586

package.lisp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,35 @@
22

33
(defpackage :diff
44
(:use :cl)
5-
(:export #:generate-diff #:unified-diff #:context-diff
6-
#:*diff-context-lines*))
5+
(:export #:*diff-context-lines*
6+
#:generate-diff
7+
#:unified-diff #:context-diff
8+
9+
#:render-diff
10+
#:render-diff-window
11+
#:format-diff
12+
#:format-diff-string
13+
14+
#:diff
15+
#:original-pathname
16+
#:modified-pathname
17+
#:diff-window-class
18+
#:diff-windows
19+
20+
#:diff-window
21+
#:original-start-line
22+
#:original-length
23+
#:modified-start-line
24+
#:modified-length
25+
#:window-chunks
26+
27+
#:chunk-kind
28+
#:chunk-lines
29+
30+
#:compute-raw-diff
31+
#:common-diff-region
32+
#:modified-diff-region
33+
#:original-start
34+
#:original-length
35+
#:modified-start
36+
#:modified-length))

0 commit comments

Comments
 (0)