Skip to content

Commit a29f6e1

Browse files
committed
chore: resolve undefined-field
1 parent 7839902 commit a29f6e1

File tree

3 files changed

+97
-76
lines changed

3 files changed

+97
-76
lines changed

lua/nvim-tree/git/init.lua

+17-15
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
local log = require("nvim-tree.log")
22
local utils = require("nvim-tree.utils")
33
local git_utils = require("nvim-tree.git.utils")
4-
local Runner = require("nvim-tree.git.runner")
4+
local runner = require("nvim-tree.git.runner")
55
local Watcher = require("nvim-tree.watcher").Watcher
66
local Iterator = require("nvim-tree.iterators.node-iterator")
77
local DirectoryNode = nil -- circular dependency
@@ -36,17 +36,17 @@ local WATCHED_FILES = {
3636
---@param toplevel string|nil
3737
---@param path string|nil
3838
---@param project table
39-
---@param git_status table|nil
40-
local function reload_git_status(toplevel, path, project, git_status)
39+
---@param statuses GitStatusesXYByPath?
40+
local function reload_git_statuses(toplevel, path, project, statuses)
4141
if path then
4242
for p in pairs(project.files) do
4343
if p:find(path, 1, true) == 1 then
4444
project.files[p] = nil
4545
end
4646
end
47-
project.files = vim.tbl_deep_extend("force", project.files, git_status)
47+
project.files = vim.tbl_deep_extend("force", project.files, statuses)
4848
else
49-
project.files = git_status
49+
project.files = statuses
5050
end
5151

5252
project.dirs = git_utils.file_status_to_dir_status(project.files, toplevel)
@@ -105,7 +105,8 @@ function M.reload_project(toplevel, path, callback)
105105
return
106106
end
107107

108-
local opts = {
108+
---@type RunnerOpts
109+
local runner_opts = {
109110
toplevel = toplevel,
110111
path = path,
111112
list_untracked = git_utils.should_show_untracked(toplevel),
@@ -114,14 +115,15 @@ function M.reload_project(toplevel, path, callback)
114115
}
115116

116117
if callback then
117-
Runner.run(opts, function(git_status)
118-
reload_git_status(toplevel, path, project, git_status)
118+
---@param statuses GitStatusesXYByPath
119+
runner_opts.callback = function(statuses)
120+
reload_git_statuses(toplevel, path, project, statuses)
119121
callback()
120-
end)
122+
end
123+
runner(runner_opts)
121124
else
122125
-- TODO #1974 use callback once async/await is available
123-
local git_status = Runner.run(opts)
124-
reload_git_status(toplevel, path, project, git_status)
126+
reload_git_statuses(toplevel, path, project, runner(runner_opts))
125127
end
126128
end
127129

@@ -246,7 +248,7 @@ function M.load_project_status(path)
246248
return status
247249
end
248250

249-
local git_status = Runner.run({
251+
local statuses = runner({
250252
toplevel = toplevel,
251253
list_untracked = git_utils.should_show_untracked(toplevel),
252254
list_ignored = true,
@@ -273,10 +275,10 @@ function M.load_project_status(path)
273275
})
274276
end
275277

276-
if git_status then
278+
if statuses then
277279
M._projects_by_toplevel[toplevel] = {
278-
files = git_status,
279-
dirs = git_utils.file_status_to_dir_status(git_status, toplevel),
280+
files = statuses,
281+
dirs = git_utils.file_status_to_dir_status(statuses, toplevel),
280282
watcher = watcher,
281283
}
282284
return M._projects_by_toplevel[toplevel]

lua/nvim-tree/git/runner.lua

+78-60
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,31 @@ local log = require("nvim-tree.log")
22
local utils = require("nvim-tree.utils")
33
local notify = require("nvim-tree.notify")
44

5-
---@class Runner
6-
local Runner = {}
7-
Runner.__index = Runner
5+
local Class = require("nvim-tree.class")
6+
7+
---@alias GitStatusesXYByPath table<string, string>
8+
9+
---@class (exact) RunnerOpts
10+
---@field toplevel string absolute path
11+
---@field path string? absolute path
12+
---@field list_untracked boolean
13+
---@field list_ignored boolean
14+
---@field timeout integer
15+
---@field callback fun(statuses: GitStatusesXYByPath)?
16+
17+
---@class (exact) Runner: Class
18+
---@field opts RunnerOpts
19+
---@field statuses GitStatusesXYByPath
20+
---@field rc integer? -- -1 indicates timeout
21+
local Runner = Class:new()
822

923
local timeouts = 0
1024
local MAX_TIMEOUTS = 5
1125

1226
---@private
1327
---@param status string
1428
---@param path string|nil
15-
function Runner:_parse_status_output(status, path)
29+
function Runner:parse_status_output(status, path)
1630
if not path then
1731
return
1832
end
@@ -22,15 +36,15 @@ function Runner:_parse_status_output(status, path)
2236
path = path:gsub("/", "\\")
2337
end
2438
if #status > 0 and #path > 0 then
25-
self.output[utils.path_remove_trailing(utils.path_join({ self.toplevel, path }))] = status
39+
self.statuses[utils.path_remove_trailing(utils.path_join({ self.opts.toplevel, path }))] = status
2640
end
2741
end
2842

2943
---@private
3044
---@param prev_output string
3145
---@param incoming string
3246
---@return string
33-
function Runner:_handle_incoming_data(prev_output, incoming)
47+
function Runner:handle_incoming_data(prev_output, incoming)
3448
if incoming and utils.str_find(incoming, "\n") then
3549
local prev = prev_output .. incoming
3650
local i = 1
@@ -45,7 +59,7 @@ function Runner:_handle_incoming_data(prev_output, incoming)
4559
-- skip next line if it is a rename entry
4660
skip_next_line = true
4761
end
48-
self:_parse_status_output(status, path)
62+
self:parse_status_output(status, path)
4963
end
5064
i = i + #line
5165
end
@@ -58,35 +72,38 @@ function Runner:_handle_incoming_data(prev_output, incoming)
5872
end
5973

6074
for line in prev_output:gmatch("[^\n]*\n") do
61-
self:_parse_status_output(line)
75+
self:parse_status_output(line)
6276
end
6377

6478
return ""
6579
end
6680

81+
---@private
6782
---@param stdout_handle uv.uv_pipe_t
6883
---@param stderr_handle uv.uv_pipe_t
69-
---@return table
70-
function Runner:_getopts(stdout_handle, stderr_handle)
71-
local untracked = self.list_untracked and "-u" or nil
72-
local ignored = (self.list_untracked and self.list_ignored) and "--ignored=matching" or "--ignored=no"
84+
---@return uv.spawn.options
85+
function Runner:get_spawn_options(stdout_handle, stderr_handle)
86+
local untracked = self.opts.list_untracked and "-u" or nil
87+
local ignored = (self.opts.list_untracked and self.opts.list_ignored) and "--ignored=matching" or "--ignored=no"
7388
return {
74-
args = { "--no-optional-locks", "status", "--porcelain=v1", "-z", ignored, untracked, self.path },
75-
cwd = self.toplevel,
89+
args = { "--no-optional-locks", "status", "--porcelain=v1", "-z", ignored, untracked, self.opts.path },
90+
cwd = self.opts.toplevel,
7691
stdio = { nil, stdout_handle, stderr_handle },
7792
}
7893
end
7994

95+
---@private
8096
---@param output string
81-
function Runner:_log_raw_output(output)
97+
function Runner:log_raw_output(output)
8298
if log.enabled("git") and output and type(output) == "string" then
8399
log.raw("git", "%s", output)
84100
log.line("git", "done")
85101
end
86102
end
87103

104+
---@private
88105
---@param callback function|nil
89-
function Runner:_run_git_job(callback)
106+
function Runner:run_git_job(callback)
90107
local handle, pid
91108
local stdout = vim.loop.new_pipe(false)
92109
local stderr = vim.loop.new_pipe(false)
@@ -123,20 +140,20 @@ function Runner:_run_git_job(callback)
123140
end
124141
end
125142

126-
local opts = self:_getopts(stdout, stderr)
127-
log.line("git", "running job with timeout %dms", self.timeout)
128-
log.line("git", "git %s", table.concat(utils.array_remove_nils(opts.args), " "))
143+
local spawn_options = self:get_spawn_options(stdout, stderr)
144+
log.line("git", "running job with timeout %dms", self.opts.timeout)
145+
log.line("git", "git %s", table.concat(utils.array_remove_nils(spawn_options.args), " "))
129146

130147
handle, pid = vim.loop.spawn(
131148
"git",
132-
opts,
149+
spawn_options,
133150
vim.schedule_wrap(function(rc)
134151
on_finish(rc)
135152
end)
136153
)
137154

138155
timer:start(
139-
self.timeout,
156+
self.opts.timeout,
140157
0,
141158
vim.schedule_wrap(function()
142159
on_finish(-1)
@@ -151,19 +168,20 @@ function Runner:_run_git_job(callback)
151168
if data then
152169
data = data:gsub("%z", "\n")
153170
end
154-
self:_log_raw_output(data)
155-
output_leftover = self:_handle_incoming_data(output_leftover, data)
171+
self:log_raw_output(data)
172+
output_leftover = self:handle_incoming_data(output_leftover, data)
156173
end
157174

158175
local function manage_stderr(_, data)
159-
self:_log_raw_output(data)
176+
self:log_raw_output(data)
160177
end
161178

162179
vim.loop.read_start(stdout, vim.schedule_wrap(manage_stdout))
163180
vim.loop.read_start(stderr, vim.schedule_wrap(manage_stderr))
164181
end
165182

166-
function Runner:_wait()
183+
---@private
184+
function Runner:wait()
167185
local function is_done()
168186
return self.rc ~= nil
169187
end
@@ -172,64 +190,64 @@ function Runner:_wait()
172190
end
173191
end
174192

175-
---@param opts table
176-
function Runner:_finalise(opts)
193+
---@private
194+
function Runner:finalise()
177195
if self.rc == -1 then
178-
log.line("git", "job timed out %s %s", opts.toplevel, opts.path)
196+
log.line("git", "job timed out %s %s", self.opts.toplevel, self.opts.path)
179197
timeouts = timeouts + 1
180198
if timeouts == MAX_TIMEOUTS then
181-
notify.warn(string.format("%d git jobs have timed out after git.timeout %dms, disabling git integration.", timeouts, opts.timeout))
199+
notify.warn(string.format("%d git jobs have timed out after git.timeout %dms, disabling git integration.", timeouts,
200+
self.opts.timeout))
182201
require("nvim-tree.git").disable_git_integration()
183202
end
184203
elseif self.rc ~= 0 then
185-
log.line("git", "job fail rc %d %s %s", self.rc, opts.toplevel, opts.path)
204+
log.line("git", "job fail rc %d %s %s", self.rc, self.opts.toplevel, self.opts.path)
186205
else
187-
log.line("git", "job success %s %s", opts.toplevel, opts.path)
206+
log.line("git", "job success %s %s", self.opts.toplevel, self.opts.path)
188207
end
189208
end
190209

191-
--- Runs a git process, which will be killed if it takes more than timeout which defaults to 400ms
192-
---@param opts table
193-
---@param callback function|nil executed passing return when complete
194-
---@return table|nil status by absolute path, nil if callback present
195-
function Runner.run(opts, callback)
196-
local self = setmetatable({
197-
toplevel = opts.toplevel,
198-
path = opts.path,
199-
list_untracked = opts.list_untracked,
200-
list_ignored = opts.list_ignored,
201-
timeout = opts.timeout or 400,
202-
output = {},
203-
rc = nil, -- -1 indicates timeout
204-
}, Runner)
205-
206-
local async = callback ~= nil
207-
local profile = log.profile_start("git %s job %s %s", async and "async" or "sync", opts.toplevel, opts.path)
208-
209-
if async and callback then
210+
---@return GitStatusesXYByPath? statuses nil if callback present
211+
function Runner:run()
212+
local async = self.opts.callback ~= nil
213+
local profile = log.profile_start("git %s job %s %s", async and "async" or "sync", self.opts.toplevel, self.opts.path)
214+
215+
if async and self.opts.callback then
210216
-- async, always call back
211-
self:_run_git_job(function()
217+
self:run_git_job(function()
212218
log.profile_end(profile)
213219

214-
self:_finalise(opts)
220+
self:finalise()
215221

216-
callback(self.output)
222+
self.opts.callback(self.statuses)
217223
end)
218224
else
219225
-- sync, maybe call back
220-
self:_run_git_job()
221-
self:_wait()
226+
self:run_git_job()
227+
self:wait()
222228

223229
log.profile_end(profile)
224230

225-
self:_finalise(opts)
231+
self:finalise()
226232

227-
if callback then
228-
callback(self.output)
233+
if self.opts.callback then
234+
self.opts.callback(self.statuses)
229235
else
230-
return self.output
236+
return self.statuses
231237
end
232238
end
233239
end
234240

235-
return Runner
241+
---Runs a git process, which will be killed if it takes more than timeout which defaults to 400ms
242+
---@param opts RunnerOpts
243+
---@return GitStatusesXYByPath? statuses nil if callback present
244+
return function(opts)
245+
---@type Runner
246+
local runner = {
247+
opts = opts,
248+
statuses = {},
249+
}
250+
runner = Runner:new(runner) --[[@as Runner]]
251+
252+
return runner:run()
253+
end

lua/nvim-tree/git/utils.lua

+2-1
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,11 @@ function M.get_toplevel(cwd)
5858
return toplevel, git_dir
5959
end
6060

61+
---@type table<string, boolean>
6162
local untracked = {}
6263

6364
---@param cwd string
64-
---@return string|nil
65+
---@return boolean
6566
function M.should_show_untracked(cwd)
6667
if untracked[cwd] ~= nil then
6768
return untracked[cwd]

0 commit comments

Comments
 (0)