@@ -315,6 +315,52 @@ of context; the default of three should be good enough for most situations.")
315
315
(window-chunks :initform nil
316
316
:accessor window-chunks)))
317
317
318
+ (defun apply-seq-window (original-seq window &key (offset 0 ))
319
+ " Apply the edits encoded in WINDOW to the ORIGINAL-SEQ."
320
+ (multiple-value-bind (interner interned-seqs)
321
+ (apply #' intern-seqs original-seq
322
+ (mapcar #' chunk-lines (window-chunks window)))
323
+ (let ((index (original-start-line window))
324
+ (result (coerce (first interned-seqs) ' list)))
325
+ (flet ((ind () (+ index offset))
326
+ (back (line) (interned-object interner line)))
327
+ (loop
328
+ for chunk in (window-chunks window)
329
+ for lines in (mapcar (lambda (l) (coerce l ' list)) (cdr interned-seqs))
330
+ do (case (chunk-kind chunk)
331
+ (:common
332
+ (mapc (lambda (line)
333
+ (assert (eql line (nth (ind) result))
334
+ (line result index)
335
+ " window does not apply at ~d , ~s !=~s "
336
+ (ind) (back line) (back (nth (ind) result)))
337
+ (incf index))
338
+ lines))
339
+ (:delete
340
+ (setf result
341
+ (append (subseq result 0 (ind))
342
+ (subseq result (+ (ind) (length lines)))))
343
+ (incf index (length lines))
344
+ (decf offset (length lines)))
345
+ (:create
346
+ (setf result (append (subseq result 0 (ind))
347
+ lines
348
+ (subseq result (ind))))
349
+ (incf offset (length lines)))
350
+ ((:insert :replace )
351
+ (error " unimplemented chunk-kind ~a " (chunk-kind chunk)))))
352
+ (values (mapcar #' back result) offset)))))
353
+
354
+ (defun apply-seq-diff (original-seq diff)
355
+ " Apply DIFF to the sequence ORIGINAL-SEQ."
356
+ (apply #' values
357
+ (reduce
358
+ (lambda (accumulator window)
359
+ (destructuring-bind (seq offset) accumulator
360
+ (multiple-value-call #' list
361
+ (apply-seq-window seq window :offset offset))))
362
+ (diff-windows diff) :initial-value (list original-seq 0 ))))
363
+
318
364
(deftype chunk-kind () ' (member :common :delete :replace :insert :create ))
319
365
320
366
(defclass chunk ()
0 commit comments