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
155
|
-- mod-version:3
local core = require "core"
local common = require "core.common"
local config = require "core.config"
local style = require "core.style"
local StatusView = require "core.statusview"
local TreeView = require "plugins.treeview"
config.plugins.gitstatus = common.merge({
color_icons = true,
recurse_submodules = true,
-- The config specification used by the settings gui
config_spec = {
name = "Git Status",
{
label = "Colorize icons",
description = "Colorize the icons as well",
path = "color_icons",
type = "toggle",
default = true
},
{
label = "Recurse Submodules",
description = "Also retrieve git stats from submodules.",
path = "recurse_submodules",
type = "toggle",
default = true
}
}
}, config.plugins.gitstatus)
style.gitstatus_addition = {common.color "#587c0c"}
style.gitstatus_modification = {common.color "#0c7d9d"}
style.gitstatus_deletion = {common.color "#94151b"}
local scan_rate = config.project_scan_rate or 5
local cached_color_for_item = {}
-- Override TreeView's get_item_text to add modification color
local treeview_get_item_text = TreeView.get_item_text
function TreeView:get_item_text(item, active, hovered)
local text, font, color = treeview_get_item_text(self, item, active, hovered)
if cached_color_for_item[item.abs_filename] then
color = cached_color_for_item[item.abs_filename]
end
return text, font, color
end
-- Override TreeView's get_item_icon to add modification color
local treeview_get_item_icon = TreeView.get_item_icon
function TreeView:get_item_icon(item, active, hovered)
local character, font, color = treeview_get_item_icon(self, item, active, hovered)
if config.plugins.gitstatus and config.plugins.gitstatus.color_icons and cached_color_for_item[item.abs_filename] then
color = cached_color_for_item[item.abs_filename]
end
return character, font, color
end
local git = {
branch = nil,
inserts = 0,
deletes = 0,
}
local function exec(cmd)
local proc = process.start(cmd)
-- Don't use proc:wait() here - that will freeze the app.
-- Instead, rely on the fact that this is only called within
-- a coroutine, and yield for a fraction of a second, allowing
-- other stuff to happen while we wait for the process to complete.
while proc:running() do
coroutine.yield(0.1)
end
return proc:read_stdout() or ""
end
core.add_thread(function()
while true do
if system.get_file_info(".git") then
-- get branch name
git.branch = exec({"git", "rev-parse", "--abbrev-ref", "HEAD"}):match("[^\n]*")
local inserts = 0
local deletes = 0
-- get diff
local diff = exec({"git", "diff", "--numstat"})
if
config.plugins.gitstatus.recurse_submodules
and
system.get_file_info(".gitmodules")
then
local diff2 = exec({"git", "submodule", "foreach", "git diff --numstat"})
diff = diff .. diff2
end
-- forget the old state
cached_color_for_item = {}
local folder = core.project_dir
for line in string.gmatch(diff, "[^\n]+") do
local submodule = line:match("^Entering '(.+)'$")
if submodule then
folder = core.project_dir .. PATHSEP .. submodule
else
local ins, dels, path = line:match("(%d+)%s+(%d+)%s+(.+)")
if path then
inserts = inserts + (tonumber(ins) or 0)
deletes = deletes + (tonumber(dels) or 0)
local abs_path = folder .. PATHSEP .. path
-- Color this file, and each parent folder,
-- so you can see at a glance which folders
-- have modified files in them.
while abs_path do
cached_color_for_item[abs_path] = style.gitstatus_modification
abs_path = common.dirname(abs_path)
end
end
end
end
git.inserts = inserts
git.deletes = deletes
else
git.branch = nil
end
coroutine.yield(scan_rate)
end
end)
core.status_view:add_item({
name = "status:git",
alignment = StatusView.Item.RIGHT,
get_item = function()
if not git.branch then
return {}
end
return {
(git.inserts ~= 0 or git.deletes ~= 0) and style.accent or style.text,
git.branch,
style.dim, " ",
git.inserts ~= 0 and style.accent or style.text, "+", git.inserts,
style.dim, " / ",
git.deletes ~= 0 and style.accent or style.text, "-", git.deletes,
}
end,
position = -1,
tooltip = "branch and changes",
separator = core.status_view.separator2
})
|