Merge pull request #27 from kyazdani42/fix-git-calls
optimize git with buffering
This commit is contained in:
commit
5b69702a52
93
lua/lib/git.lua
Normal file
93
lua/lib/git.lua
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
local M = {}
|
||||||
|
|
||||||
|
local roots = {}
|
||||||
|
|
||||||
|
local not_git = 'not a git repo'
|
||||||
|
|
||||||
|
local function update_root_status(root)
|
||||||
|
local status = vim.fn.systemlist('cd '..root..' && git status --porcelain=v1')
|
||||||
|
roots[root] = {}
|
||||||
|
|
||||||
|
for _, v in pairs(status) do
|
||||||
|
local head = v:sub(0, 2)
|
||||||
|
local body = v:sub(4, -1)
|
||||||
|
if body:match('%->') ~= nil then
|
||||||
|
body = body:gsub('^.* %-> ', '')
|
||||||
|
end
|
||||||
|
roots[root][body] = head
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.reload_roots()
|
||||||
|
for root, status in pairs(roots) do
|
||||||
|
if status ~= not_git then
|
||||||
|
update_root_status(root)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function path_to_matching_str(path)
|
||||||
|
return path:gsub('(%-)', '(%%-)'):gsub('(%.)', '(%%.)')
|
||||||
|
end
|
||||||
|
|
||||||
|
local function get_git_root(path)
|
||||||
|
if roots[path] then
|
||||||
|
return path, roots[path]
|
||||||
|
end
|
||||||
|
|
||||||
|
for name, status in pairs(roots) do
|
||||||
|
if status ~= not_git then
|
||||||
|
if path:match(path_to_matching_str(name)) then
|
||||||
|
return name, status
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function create_root(cwd)
|
||||||
|
local git_root = vim.fn.system('cd '..cwd..' && git rev-parse --show-toplevel')
|
||||||
|
if not git_root or #git_root == 0 or git_root:match('fatal: not a git repository') then
|
||||||
|
roots[cwd] = not_git
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
update_root_status(git_root:sub(0, -2))
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.update_status(entries, cwd)
|
||||||
|
local git_root, git_status = get_git_root(cwd)
|
||||||
|
if not git_root then
|
||||||
|
if not create_root(cwd) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
git_root, git_status = get_git_root(cwd)
|
||||||
|
elseif git_status == not_git then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local matching_cwd = path_to_matching_str(git_root..'/')
|
||||||
|
for _, node in pairs(entries) do
|
||||||
|
local relpath = node.absolute_path:gsub(matching_cwd, '')
|
||||||
|
if node.entries ~= nil then
|
||||||
|
relpath = relpath..'/'
|
||||||
|
node.git_status = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local status = git_status[relpath]
|
||||||
|
if status then
|
||||||
|
node.git_status = status
|
||||||
|
elseif node.entries ~= nil then
|
||||||
|
local matcher = '^'..path_to_matching_str(relpath)
|
||||||
|
for key, _ in pairs(git_status) do
|
||||||
|
if key:match(matcher) then
|
||||||
|
node.git_status = 'dirty'
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
node.git_status = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return M
|
||||||
@ -1,4 +1,5 @@
|
|||||||
local config = require'lib.config'
|
local config = require'lib.config'
|
||||||
|
local git = require'lib.git'
|
||||||
local icon_config = config.get_icon_state()
|
local icon_config = config.get_icon_state()
|
||||||
|
|
||||||
local api = vim.api
|
local api = vim.api
|
||||||
@ -190,52 +191,7 @@ function M.populate(entries, cwd)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
M.update_git_status(entries, cwd)
|
git.update_status(entries, cwd)
|
||||||
end
|
|
||||||
|
|
||||||
function M.update_git_status(entries, cwd)
|
|
||||||
local git_root = vim.fn.system('cd '..cwd..' && git rev-parse --show-toplevel')
|
|
||||||
if not git_root or #git_root == 0 or git_root:match('fatal: not a git repository') then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
git_root = git_root:sub(0, -2)
|
|
||||||
|
|
||||||
local git_statuslist = vim.fn.systemlist('cd '..cwd..' && git status --porcelain=v1')
|
|
||||||
local git_status = {}
|
|
||||||
|
|
||||||
for _, v in pairs(git_statuslist) do
|
|
||||||
local head = v:sub(0, 2)
|
|
||||||
local body = v:sub(4, -1)
|
|
||||||
if body:match('%->') ~= nil then
|
|
||||||
body = body:gsub('^.* %-> ', '')
|
|
||||||
end
|
|
||||||
git_status[body] = head
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local matching_cwd = path_to_matching_str(git_root..'/')
|
|
||||||
for _, node in pairs(entries) do
|
|
||||||
local relpath = node.absolute_path:gsub(matching_cwd, '')
|
|
||||||
if node.entries ~= nil then
|
|
||||||
relpath = relpath..'/'
|
|
||||||
node.git_status = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
local status = git_status[relpath]
|
|
||||||
if status then
|
|
||||||
node.git_status = status
|
|
||||||
elseif node.entries ~= nil then
|
|
||||||
local matcher = '^'..path_to_matching_str(relpath)
|
|
||||||
for key, _ in pairs(git_status) do
|
|
||||||
if key:match(matcher) then
|
|
||||||
node.git_status = 'dirty'
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
node.git_status = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|||||||
@ -3,10 +3,10 @@ local luv = vim.loop
|
|||||||
|
|
||||||
local renderer = require'lib.renderer'
|
local renderer = require'lib.renderer'
|
||||||
local config = require'lib.config'
|
local config = require'lib.config'
|
||||||
|
local git = require'lib.git'
|
||||||
local pops = require'lib.populate'
|
local pops = require'lib.populate'
|
||||||
local populate = pops.populate
|
local populate = pops.populate
|
||||||
local refresh_entries = pops.refresh_entries
|
local refresh_entries = pops.refresh_entries
|
||||||
local update_git = pops.update_git_status
|
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ function M.unroll_dir(node)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function refresh_git(node)
|
local function refresh_git(node)
|
||||||
update_git(node.entries, node.absolute_path or node.cwd)
|
git.update_status(node.entries, node.absolute_path or node.cwd)
|
||||||
for _, entry in pairs(node.entries) do
|
for _, entry in pairs(node.entries) do
|
||||||
if entry.entries ~= nil then
|
if entry.entries ~= nil then
|
||||||
refresh_git(entry)
|
refresh_git(entry)
|
||||||
@ -122,6 +122,7 @@ function M.refresh_tree()
|
|||||||
refresh_nodes(M.Tree)
|
refresh_nodes(M.Tree)
|
||||||
-- end
|
-- end
|
||||||
if config.get_icon_state().show_git_icon then
|
if config.get_icon_state().show_git_icon then
|
||||||
|
git.reload_roots()
|
||||||
refresh_git(M.Tree)
|
refresh_git(M.Tree)
|
||||||
end
|
end
|
||||||
if M.Tree.winnr ~= nil then
|
if M.Tree.winnr ~= nil then
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user