-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathgit.lisp
41 lines (39 loc) · 1.99 KB
/
git.lisp
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
(defpackage #:inga/git
(:use #:cl
#:inga/utils)
(:import-from #:cl-ppcre)
(:import-from #:inga/errors
#:inga-error)
(:import-from #:inga/file
#:convert-to-top-offset)
(:export #:diff-to-ranges))
(in-package #:inga/git)
(defun diff-to-ranges (diff root-path)
(let ((ranges (make-array 10 :fill-pointer 0 :adjustable t)) to-path)
(with-input-from-string (in diff)
(loop for line = (read-line in nil nil)
while line
do
(let ((found-to-path (car (cdr (multiple-value-list
(ppcre:scan-to-strings "^diff --git a/.+ b/(.+)$" line))))))
(when found-to-path
(setq to-path (aref found-to-path 0))))
(let ((to-range (car (cdr (multiple-value-list
(ppcre:scan-to-strings "@@.+\\+([0-9]+),?([0-9]*) @@" line))))))
(when to-range
(let* ((start (parse-integer (aref to-range 0)))
(rows (if (> (length (aref to-range 1)) 0) (parse-integer (aref to-range 1)) 0))
(end (if (= rows 0) start (- (+ start rows) 1))))
;; extract undeleted files
(when (or (> start 0) (> end 0))
(vector-push-extend `((:path . ,to-path)
(:start-offset .
,(convert-to-top-offset
(merge-pathnames to-path root-path)
(list (cons :line start) (cons :offset 0))))
(:end-offset .
,(convert-to-top-offset
(merge-pathnames to-path root-path)
(list (cons :line end) (cons :offset -1)))))
ranges)))))))
(coerce ranges 'list)))