aboutsummaryrefslogtreecommitdiff
path: root/plugins/gitstatus.lua
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/gitstatus.lua')
-rw-r--r--plugins/gitstatus.lua74
1 files changed, 66 insertions, 8 deletions
diff --git a/plugins/gitstatus.lua b/plugins/gitstatus.lua
index bb16025..de5c74b 100644
--- a/plugins/gitstatus.lua
+++ b/plugins/gitstatus.lua
@@ -1,9 +1,21 @@
-- mod-version:2 -- lite-xl 2.0
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"
+
local scan_rate = config.project_scan_rate or 5
+local cached_color_for_item = {}
+
+
+-- Override TreeView's color_for_item, but first
+-- stash the old one (using [] in case it is not there at all)
+local old_color_for_item = TreeView["color_for_item"]
+function TreeView:color_for_item(abs_path)
+ return cached_color_for_item[abs_path] or old_color_for_item(abs_path)
+end
local git = {
@@ -13,11 +25,24 @@ local git = {
}
-local function exec(cmd, wait)
+config.gitstatus = {
+ recurse_submodules = true
+}
+style.gitstatus_addition = {common.color "#587c0c"}
+style.gitstatus_modification = {common.color "#0c7d9d"}
+style.gitstatus_deletion = {common.color "#94151b"}
+
+
+local function exec(cmd)
local proc = process.start(cmd)
- proc:wait(wait * 1000)
- local res = proc:read_stdout()
- return res
+ -- 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
@@ -25,12 +50,45 @@ 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"}, 1):match("[^\n]*")
+ git.branch = exec({"git", "rev-parse", "--abbrev-ref", "HEAD"}):match("[^\n]*")
+
+ local inserts = 0
+ local deletes = 0
-- get diff
- local line = exec({"git", "diff", "--stat"}, 1):match("[^\n]*%s*$")
- git.inserts = tonumber(line:match("(%d+) ins")) or 0
- git.deletes = tonumber(line:match("(%d+) del")) or 0
+ local diff = exec({"git", "diff", "--numstat"})
+ if config.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