Skip to content

Commit 4842dcd

Browse files
committed
simplifies the creation of "diff generators" outside the library
1 parent 7842213 commit 4842dcd

File tree

2 files changed

+59
-27
lines changed

2 files changed

+59
-27
lines changed

diff.lisp

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,16 @@ of context; the default of three should be good enough for most situations.")
252252
(defclass diff ()
253253
((original-pathname :initarg :original-pathname :accessor original-pathname)
254254
(modified-pathname :initarg :modified-pathname :accessor modified-pathname)
255+
(window-class :initarg :window-class :reader diff-window-class)
255256
(windows :initform nil :accessor diff-windows)))
256257

257-
(defclass unified-diff (diff) ())
258-
(defclass context-diff (diff) ())
258+
(defclass unified-diff (diff) ()
259+
(:default-initargs
260+
:window-class 'unified-diff-window))
261+
262+
(defclass context-diff (diff) ()
263+
(:default-initargs
264+
:window-class 'context-diff-window))
259265

260266
(defclass diff-generator ()
261267
((interned-lines :initarg :interned-lines :reader interner)
@@ -314,13 +320,8 @@ of context; the default of three should be good enough for most situations.")
314320
(defun create-window (generator)
315321
(create-window-for-diff (diff generator)))
316322

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))
323+
(defun create-window-for-diff (diff)
324+
(make-instance (diff-window-class diff)))
324325

325326
(defun original-window-length (window)
326327
(reduce #'+ (window-chunks window)
@@ -463,6 +464,12 @@ of context; the default of three should be good enough for most situations.")
463464
:original-pathname original-pathname
464465
:modified-pathname modified-pathname)))
465466

467+
(defgeneric render-diff (diff stream)
468+
(:documentation "Print DIFF object to STREAM"))
469+
470+
(defgeneric render-diff-window (window stream)
471+
(:documentation "Print WINDOW to STREAM"))
472+
466473
(defun generate-diff (diff-kind original-pathname modified-pathname)
467474
"Compute a diff between ORIGINAL-PATHNAME and MODIFIED-PATHNAME.
468475
DIFF-KIND indicates the type of DIFF generated and should be the symbol
@@ -477,12 +484,21 @@ DIFF:UNIFIED-DIFF or DIFF:CONTEXT-DIFF."
477484
original-pathname original
478485
modified-pathname modified)))
479486
(walk-diff-regions context diff-regions)))))
480-
487+
488+
(defun format-diff (diff-kind original-pathname modified-pathname &optional (stream *standard-output*))
489+
(render-diff (generate-diff diff-kind
490+
original-pathname
491+
modified-pathname)
492+
stream))
493+
494+
(defun format-diff-string (diff-kind original-pathname modified-pathname)
495+
(with-output-to-string (out)
496+
(format-diff diff-kind original-pathname modified-pathname out)))
497+
481498
;;; printing diffs on streams
482499

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

485-
(defmethod print-diff-window-header ((window unified-diff-window) stream)
501+
(defmethod render-diff-window :before ((window unified-diff-window) stream)
486502
(let ((original-length (original-window-length window))
487503
(modified-length (modified-window-length window)))
488504
(format stream "@@ -~A" (1+ (original-start-line window)))
@@ -494,10 +510,10 @@ DIFF:UNIFIED-DIFF or DIFF:CONTEXT-DIFF."
494510
(write-string " @@" stream)
495511
(terpri stream)))
496512

497-
(defmethod print-diff-window-header ((window context-diff-window) stream)
513+
(defmethod render-diff-window :before ((window context-diff-window) stream)
498514
(format stream "***************~%"))
499515

500-
(defmethod print-object ((object unified-diff-window) stream)
516+
(defmethod render-diff-window ((object unified-diff-window) stream)
501517
(dolist (chunk (window-chunks object))
502518
(let ((prefix (ecase (chunk-kind chunk)
503519
(:common #\Space)
@@ -514,7 +530,7 @@ DIFF:UNIFIED-DIFF or DIFF:CONTEXT-DIFF."
514530
(defun window-contains-inserts-p (window)
515531
(some #'modified-chunk-p (window-chunks window)))
516532

517-
(defmethod print-object ((window context-diff-window) stream)
533+
(defmethod render-diff-window ((window context-diff-window) stream)
518534
(let ((original-length (1- (original-window-length window)))
519535
(original-start-line (1+ (original-start-line window)))
520536
(modified-length (1- (modified-window-length window)))
@@ -551,23 +567,17 @@ DIFF:UNIFIED-DIFF or DIFF:CONTEXT-DIFF."
551567
(write-string line stream)
552568
(terpri stream))))))))
553569

554-
(defgeneric print-diff-header (diff stream))
555-
556-
(defmethod print-diff-header ((diff unified-diff) stream)
570+
(defmethod render-diff :before ((diff unified-diff) stream)
557571
(format stream "--- ~A~%+++ ~A~%"
558572
(namestring (original-pathname diff))
559573
(namestring (modified-pathname diff))))
560574

561-
(defmethod print-diff-header ((diff context-diff) stream)
575+
(defmethod render-diff :before ((diff context-diff) stream)
562576
(format stream "*** ~A~%--- ~A~%"
563577
(namestring (original-pathname diff))
564578
(namestring (modified-pathname diff))))
565579

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)
580+
(defmethod render-diff ((object diff) stream)
571581
(dolist (window (diff-windows object))
572-
(print-object window stream)))
582+
(render-diff-window window stream)))
573583

package.lisp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,27 @@
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))

0 commit comments

Comments
 (0)