aboutsummaryrefslogtreecommitdiff
path: root/plugins/gitstatus.lua
blob: 54bd6e8ac424b1c72b380d820683042fd2728606 (plain)
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
-- 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 _, TreeView = pcall(require, "plugins.treeview")
local StatusView = require "core.statusview"
local scan_rate = config.project_scan_rate or 5


if TreeView then
  if not (TreeView["set_color_override"] and TreeView["clear_all_color_overrides"]) then
    -- TreeView doesn't have the color override feature we rely on, so skip it.
    TreeView = nil
  end
end


local git = {
  branch = nil,
  inserts = 0,
  deletes = 0,
}


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, wait)
  local proc = process.start(cmd)
  proc:wait(wait * 1000)
	local res = proc:read_stdout()
  return res
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"}, 1):match("[^\n]*")

      if TreeView then
        TreeView:clear_all_color_overrides()
      end

      local inserts = 0
      local deletes = 0

      -- get diff
      local diff = exec({"git", "diff", "--numstat"}, 1)
      if config.gitstatus.recurse_submodules and system.get_file_info(".gitmodules") then
        diff = diff .. exec({"git", "submodule", "foreach", "git diff --numstat --stat"}, 1)
      end

      local root = ""
      for line in string.gmatch(diff, "[^\n]+") do
        local submodule = line:match("^Entering '(.+)'$")
        if submodule then
          root = 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 = core.project_dir.."/"..root..path
            if TreeView then
              -- 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
                TreeView:set_color_override(abs_path, style.gitstatus_modification)
                abs_path = common.dirname(abs_path)
              end
            end
          end
        end
      end

      git.inserts = inserts
      git.deletes = deletes

    else
      git.branch = nil
    end

    coroutine.yield(scan_rate)
  end
end)


local get_items = StatusView.get_items

function StatusView:get_items()
  if not git.branch then
    return get_items(self)
  end
  local left, right = get_items(self)

  local t = {
    style.dim, self.separator,
    (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,
  }
  for _, item in ipairs(t) do
    table.insert(right, item)
  end

  return left, right
end