Skip to content

Commit 5eb84c6

Browse files
authored
Merge pull request rxi#93 from jminor/gitstatus_enhancements
Git status enhancements
2 parents 2442193 + 0cbdc9d commit 5eb84c6

File tree

1 file changed

+66
-8
lines changed

1 file changed

+66
-8
lines changed

plugins/gitstatus.lua

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
-- mod-version:2 -- lite-xl 2.0
22
local core = require "core"
3+
local common = require "core.common"
34
local config = require "core.config"
45
local style = require "core.style"
56
local StatusView = require "core.statusview"
7+
local TreeView = require "plugins.treeview"
8+
69
local scan_rate = config.project_scan_rate or 5
10+
local cached_color_for_item = {}
11+
12+
13+
-- Override TreeView's color_for_item, but first
14+
-- stash the old one (using [] in case it is not there at all)
15+
local old_color_for_item = TreeView["color_for_item"]
16+
function TreeView:color_for_item(abs_path)
17+
return cached_color_for_item[abs_path] or old_color_for_item(abs_path)
18+
end
719

820

921
local git = {
@@ -13,24 +25,70 @@ local git = {
1325
}
1426

1527

16-
local function exec(cmd, wait)
28+
config.gitstatus = {
29+
recurse_submodules = true
30+
}
31+
style.gitstatus_addition = {common.color "#587c0c"}
32+
style.gitstatus_modification = {common.color "#0c7d9d"}
33+
style.gitstatus_deletion = {common.color "#94151b"}
34+
35+
36+
local function exec(cmd)
1737
local proc = process.start(cmd)
18-
proc:wait(wait * 1000)
19-
local res = proc:read_stdout()
20-
return res
38+
-- Don't use proc:wait() here - that will freeze the app.
39+
-- Instead, rely on the fact that this is only called within
40+
-- a coroutine, and yield for a fraction of a second, allowing
41+
-- other stuff to happen while we wait for the process to complete.
42+
while proc:running() do
43+
coroutine.yield(0.1)
44+
end
45+
return proc:read_stdout() or ""
2146
end
2247

2348

2449
core.add_thread(function()
2550
while true do
2651
if system.get_file_info(".git") then
2752
-- get branch name
28-
git.branch = exec({"git", "rev-parse", "--abbrev-ref", "HEAD"}, 1):match("[^\n]*")
53+
git.branch = exec({"git", "rev-parse", "--abbrev-ref", "HEAD"}):match("[^\n]*")
54+
55+
local inserts = 0
56+
local deletes = 0
2957

3058
-- get diff
31-
local line = exec({"git", "diff", "--stat"}, 1):match("[^\n]*%s*$")
32-
git.inserts = tonumber(line:match("(%d+) ins")) or 0
33-
git.deletes = tonumber(line:match("(%d+) del")) or 0
59+
local diff = exec({"git", "diff", "--numstat"})
60+
if config.gitstatus.recurse_submodules and system.get_file_info(".gitmodules") then
61+
local diff2 = exec({"git", "submodule", "foreach", "git diff --numstat"})
62+
diff = diff .. diff2
63+
end
64+
65+
-- forget the old state
66+
cached_color_for_item = {}
67+
68+
local folder = core.project_dir
69+
for line in string.gmatch(diff, "[^\n]+") do
70+
local submodule = line:match("^Entering '(.+)'$")
71+
if submodule then
72+
folder = core.project_dir .. PATHSEP .. submodule
73+
else
74+
local ins, dels, path = line:match("(%d+)%s+(%d+)%s+(.+)")
75+
if path then
76+
inserts = inserts + (tonumber(ins) or 0)
77+
deletes = deletes + (tonumber(dels) or 0)
78+
local abs_path = folder .. PATHSEP .. path
79+
-- Color this file, and each parent folder,
80+
-- so you can see at a glance which folders
81+
-- have modified files in them.
82+
while abs_path do
83+
cached_color_for_item[abs_path] = style.gitstatus_modification
84+
abs_path = common.dirname(abs_path)
85+
end
86+
end
87+
end
88+
end
89+
90+
git.inserts = inserts
91+
git.deletes = deletes
3492

3593
else
3694
git.branch = nil

0 commit comments

Comments
 (0)