forked from nvim-neo-tree/neo-tree.nvim
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathignored.lua
156 lines (144 loc) · 4.85 KB
/
ignored.lua
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
local Job = require("plenary.job")
local utils = require("neo-tree.utils")
local log = require("neo-tree.log")
local git_utils = require("neo-tree.git.utils")
local M = {}
local sep = utils.path_separator
M.is_ignored = function(ignored, path, _type)
if _type == "directory" and not utils.is_windows then
path = path .. sep
end
return vim.tbl_contains(ignored, path)
end
local git_root_cache = {
known_roots = {},
dir_lookup = {},
}
local get_root_for_item = function(item)
local dir = item.type == "directory" and item.path or item.parent_path
if type(git_root_cache.dir_lookup[dir]) ~= "nil" then
return git_root_cache.dir_lookup[dir]
end
--for _, root in ipairs(git_root_cache.known_roots) do
-- if vim.startswith(dir, root) then
-- git_root_cache.dir_lookup[dir] = root
-- return root
-- end
--end
local root = git_utils.get_repository_root(dir)
if root then
git_root_cache.dir_lookup[dir] = root
table.insert(git_root_cache.known_roots, root)
else
git_root_cache.dir_lookup[dir] = false
end
return root
end
M.mark_ignored = function(state, items, callback)
local folders = {}
log.trace("================================================================================")
log.trace("IGNORED: mark_ignore BEGIN...")
for _, item in ipairs(items) do
local folder = utils.split_path(item.path)
if folder then
if not folders[folder] then
folders[folder] = {}
end
table.insert(folders[folder], item.path)
end
end
local function process_result(result)
if utils.is_windows then
--on Windows, git seems to return quotes and double backslash "path\\directory"
result = vim.tbl_map(function(item)
item = item:gsub("\\\\", "\\")
return item
end, result)
else
--check-ignore does not indicate directories the same as 'status' so we need to
--add the trailing slash to the path manually if not on Windows.
log.trace("IGNORED: Checking types of", #result, "items to see which ones are directories")
for i, item in ipairs(result) do
local stat = vim.loop.fs_stat(item)
if stat and stat.type == "directory" then
result[i] = item .. sep
end
end
end
result = vim.tbl_map(function(item)
-- remove leading and trailing " from git output
item = item:gsub('^"', ""):gsub('"$', "")
-- convert octal encoded lines to utf-8
item = git_utils.octal_to_utf8(item)
return item
end, result)
return result
end
local function finalize(all_results)
local show_anyway = state.filtered_items and state.filtered_items.hide_gitignored == false
log.trace("IGNORED: Comparing results to mark items as ignored, show_anyway:", show_anyway)
local ignored, not_ignored = 0, 0
for _, item in ipairs(items) do
if M.is_ignored(all_results, item.path, item.type) then
item.filtered_by = item.filtered_by or {}
item.filtered_by.gitignored = true
item.filtered_by.show_anyway = show_anyway
ignored = ignored + 1
else
not_ignored = not_ignored + 1
end
end
log.trace("IGNORED: mark_ignored is complete, ignored:", ignored, ", not ignored:", not_ignored)
log.trace("================================================================================")
end
local all_results = {}
if type(callback) == "function" then
local jobs = {}
local progress = 0
for folder, folder_items in pairs(folders) do
local args = { "-C", folder, "check-ignore", "--stdin" }
local job = Job:new({
command = "git",
args = args,
enabled_recording = true,
writer = folder_items,
on_start = function()
log.trace("IGNORED: Running async git with args: ", args)
end,
on_exit = function(self, code, _)
local result
if code ~= 0 then
log.debug("Failed to load ignored files for", folder, ":", self:stderr_result())
result = {}
else
result = self:result()
end
vim.list_extend(all_results, process_result(result))
progress = progress + 1
if progress == #jobs then
finalize(all_results)
callback(all_results)
end
end,
})
table.insert(jobs, job)
end
for _, job in ipairs(jobs) do
job:start()
end
else
for folder, folder_items in pairs(folders) do
local cmd = { "git", "-C", folder, "check-ignore", unpack(folder_items) }
log.trace("IGNORED: Running cmd: ", cmd)
local result = vim.fn.systemlist(cmd)
if vim.v.shell_error == 128 then
log.debug("Failed to load ignored files for", state.path, ":", result)
result = {}
end
vim.list_extend(all_results, process_result(result))
end
finalize(all_results)
return all_results
end
end
return M