-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
diffsplit.lua
110 lines (96 loc) · 1.89 KB
/
diffsplit.lua
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
local function stringlines(str)
local init = 1
return function()
if init >= #str then
return nil
end
local starts, ends = string.find(str, "\n", init, true)
if not starts then
local sub = string.sub(str, init)
init = #str
return sub
else
local sub = string.sub(str, init, ends - 1)
init = ends + 1
return sub
end
end
end
--[[
diffsplit function splits multiple concatenated diff messages
and returns iterator over them.
--]]
local function diffsplit(data)
local lines
if type(data) == "string" then
lines = stringlines(data)
else
lines = data:lines("l")
end
local savedline = nil
return function()
local filename = nil
local old = nil
local new = nil
local inserted = 0
local removed = 0
local comments = {}
local body = {}
local state = "oldfile"
local line = savedline or lines()
if not line then
return
end
savedline = nil
while line do
if state == "oldfile" then
old = string.match(line, "^--- (%S+)")
if old then
state = "newfile"
else
table.insert(comments, line)
end
elseif state == "newfile" then
new = string.match(line, "^+++ (%S+)")
if not new then
die("error")
end
state = "body"
elseif state == "body" then
local c = string.sub(line, 1, 1)
if c == "@" or c == "-" or c == "+" or c == " " then
if c == "+" then
inserted = inserted + 1
table.insert(body, line)
end
if c == "-" then
removed = removed + 1
table.insert(body, line)
end
else
savedline = line
break
end
end
line = lines()
end
if state ~= "body" then
die("error")
end
if new ~= '/dev/null' then
filename = new
else
filename = old
end
return {
filename = filename,
old = old,
new = new,
inserted = inserted,
removed = removed,
comments = comments,
body = body
}
end
end
return diffsplit