11-- mod-version:2 -- lite-xl 2.0
22local core = require " core"
3+ local common = require " core.common"
34local config = require " core.config"
45local style = require " core.style"
56local StatusView = require " core.statusview"
7+ local TreeView = require " plugins.treeview"
8+
69local 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
921local 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 " "
2146end
2247
2348
2449core .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