-
Notifications
You must be signed in to change notification settings - Fork 1
/
gitblame.lua
154 lines (109 loc) · 3.8 KB
/
gitblame.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
local core = require "core"
local config = require "core.config"
local gitblame = {}
local blame_pattern = "%w+[ (_.%w]+[ ]+%d+[-]?%d+[-]?%d+[ ]?%d+[:]?%d+[:]?%d+[ ]+[+-]?%d+"
local hash_pattern = "[0-9a-f]+"
-- local username_pattern = "[ _.%w]+"
local opening_bracket_pattern = "[ (]*"
local datetime_pattern = "%d+[-]?%d+[-]?%d+[ ]?%d+[:]?%d+[:]?%d+[ ]+[+-]?%d+"
local not_commited_yet_hash = "00000000"
local not_git_repo_message = "fatal: not a git repository"
local function exec(cmd)
local proc = process.start(cmd)
if proc then
local output = ""
while true do
local rdbuf = proc:read_stdout()
if not rdbuf then
break
else
output = output .. rdbuf
end
end
return output
end
return nil
end
local function log_data(var_name, var_value)
if config.plugins.gitblame.debug then
if var_value ~= nil then
if type(var_value) == 'table' then
core.try(function (var)
local data = table.concat(var, " ")
core.log("[GITBLAME] " .. var_name .. " : " .. data)
end, var_value
)
else
core.try(
function (name, value)
core.log("[GITBLAME] " .. name .. " : " .. value)
end, var_name, var_value
)
end
else
core.try(
function (name)
core.log("[GITBLAME] " .. name .. " : nil")
end, var_name
)
end
end
end
local function get_commit_message(commit_hash)
local git_command = {config.plugins.gitblame.git_executable, "show", "--no-color", "--pretty=format:%s", "--no-patch", commit_hash}
log_data("get_commit_message.git_command", git_command)
local result = exec(git_command)
if result ~= nil then
local length = result:len()
if length ~= nil then
if length > config.plugins.gitblame.max_commit_message_length then
result = result:sub(0, config.plugins.gitblame.max_commit_message_length) .. "..."
end
end
end
return result
end
local function truncate_blame_text(blame_text)
local _, first_index = blame_text:find(hash_pattern)
local last_index, _ = blame_text:find(datetime_pattern)
return blame_text:sub(first_index+1, last_index-1)
end
function gitblame.get_blame_text(active_view)
if active_view ~= nil then
local abs_filename = active_view.doc.abs_filename
local line, _ = active_view.doc:get_selection()
local git_command = {config.plugins.gitblame.git_executable, "blame", "-L", line .. "," .. line, abs_filename}
log_data("get_blame_text.git_command", git_command)
local git_output = exec(git_command)
log_data("git_output", git_output)
local blame_text = git_output:match(blame_pattern)
log_data("blame_text", blame_text)
if blame_text == nil then
local a, _ = git_output:find(not_git_repo_message)
if a ~= nil then
return "Not a git repository"
end
return nil
end
local commit_hash = blame_text:match(hash_pattern)
log_data("commit_hash", commit_hash)
if commit_hash == nil then
return nil
end
if commit_hash == not_commited_yet_hash then
return "Not Committed Yet"
end
local datetime = blame_text:match(datetime_pattern)
log_data("datetime", datetime)
blame_text = truncate_blame_text(blame_text)
log_data("truncated_blame_text", blame_text)
local _, username_start_index = blame_text:find(opening_bracket_pattern)
local username = blame_text:sub(username_start_index+1, blame_text:len() - 1)
log_data("username", username)
local commit_message = get_commit_message(commit_hash)
local result = commit_hash .. ' | ' .. "(" .. username .. ") " .. datetime .. ' | ' .. commit_message
log_data("result", result)
return result
end
end
return gitblame