241
241
(incf modified-start (snake-length snake))
242
242
(pop lcs)))))
243
243
244
+ (defun compute-raw-diff (origin modified)
245
+ (convert-lcs-to-diff (compute-lcs origin modified)))
246
+
244
247
245
248
; ;; producing diffs in "unified diff" format
246
249
@@ -252,10 +255,16 @@ of context; the default of three should be good enough for most situations.")
252
255
(defclass diff ()
253
256
((original-pathname :initarg :original-pathname :accessor original-pathname)
254
257
(modified-pathname :initarg :modified-pathname :accessor modified-pathname)
258
+ (window-class :initarg :window-class :reader diff-window-class)
255
259
(windows :initform nil :accessor diff-windows)))
256
260
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))
259
268
260
269
(defclass diff-generator ()
261
270
((interned-lines :initarg :interned-lines :reader interner)
@@ -314,13 +323,8 @@ of context; the default of three should be good enough for most situations.")
314
323
(defun create-window (generator)
315
324
(create-window-for-diff (diff generator)))
316
325
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)))
324
328
325
329
(defun original-window-length (window)
326
330
(reduce #' + (window-chunks window)
@@ -463,6 +467,12 @@ of context; the default of three should be good enough for most situations.")
463
467
:original-pathname original-pathname
464
468
:modified-pathname modified-pathname)))
465
469
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
+
466
476
(defun generate-diff (diff-kind original-pathname modified-pathname)
467
477
" Compute a diff between ORIGINAL-PATHNAME and MODIFIED-PATHNAME.
468
478
DIFF-KIND indicates the type of DIFF generated and should be the symbol
@@ -477,12 +487,21 @@ DIFF:UNIFIED-DIFF or DIFF:CONTEXT-DIFF."
477
487
original-pathname original
478
488
modified-pathname modified)))
479
489
(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
+
481
501
; ;; printing diffs on streams
482
502
483
- (defgeneric print-diff-window-header (window stream ))
484
503
485
- (defmethod print -diff-window-header ((window unified-diff-window) stream )
504
+ (defmethod render -diff-window :before ((window unified-diff-window) stream )
486
505
(let ((original-length (original-window-length window))
487
506
(modified-length (modified-window-length window)))
488
507
(format stream " @@ -~A " (1+ (original-start-line window)))
@@ -494,10 +513,10 @@ DIFF:UNIFIED-DIFF or DIFF:CONTEXT-DIFF."
494
513
(write-string " @@" stream )
495
514
(terpri stream )))
496
515
497
- (defmethod print -diff-window-header ((window context-diff-window) stream )
516
+ (defmethod render -diff-window :before ((window context-diff-window) stream )
498
517
(format stream " ***************~% " ))
499
518
500
- (defmethod print-object ((object unified-diff-window) stream )
519
+ (defmethod render-diff-window ((object unified-diff-window) stream )
501
520
(dolist (chunk (window-chunks object))
502
521
(let ((prefix (ecase (chunk-kind chunk)
503
522
(:common #\Space )
@@ -514,7 +533,7 @@ DIFF:UNIFIED-DIFF or DIFF:CONTEXT-DIFF."
514
533
(defun window-contains-inserts-p (window)
515
534
(some #' modified-chunk-p (window-chunks window)))
516
535
517
- (defmethod print-object ((window context-diff-window) stream )
536
+ (defmethod render-diff-window ((window context-diff-window) stream )
518
537
(let ((original-length (1- (original-window-length window)))
519
538
(original-start-line (1+ (original-start-line window)))
520
539
(modified-length (1- (modified-window-length window)))
@@ -551,23 +570,17 @@ DIFF:UNIFIED-DIFF or DIFF:CONTEXT-DIFF."
551
570
(write-string line stream )
552
571
(terpri stream ))))))))
553
572
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 )
557
574
(format stream " --- ~A~% +++ ~A~% "
558
575
(namestring (original-pathname diff))
559
576
(namestring (modified-pathname diff))))
560
577
561
- (defmethod print -diff-header ((diff context-diff) stream )
578
+ (defmethod render -diff :before ((diff context-diff) stream )
562
579
(format stream " *** ~A~% --- ~A~% "
563
580
(namestring (original-pathname diff))
564
581
(namestring (modified-pathname diff))))
565
582
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 )
571
584
(dolist (window (diff-windows object))
572
- (print-object window stream )))
585
+ (render-diff-window window stream )))
573
586
0 commit comments