diff --git a/lua/nvim-tree/explorer/watch.lua b/lua/nvim-tree/explorer/watch.lua index 7e7441c7a0b..d084fb18e1c 100644 --- a/lua/nvim-tree/explorer/watch.lua +++ b/lua/nvim-tree/explorer/watch.lua @@ -7,7 +7,7 @@ local M = {} local function reload_and_get_git_project(path) local project_root = git.get_project_root(path) - git.reload_project(project_root) + git.reload_project(project_root, path) return project_root, git.get_project(project_root) or {} end diff --git a/lua/nvim-tree/git/init.lua b/lua/nvim-tree/git/init.lua index 41d6f62aa4f..c3278647e67 100644 --- a/lua/nvim-tree/git/init.lua +++ b/lua/nvim-tree/git/init.lua @@ -22,25 +22,36 @@ function M.reload() return M.projects end -function M.reload_project(project_root) +function M.reload_project(project_root, path) local project = M.projects[project_root] if not project or not M.config.enable then return end - local watcher = M.projects[project_root].watcher - M.projects[project_root] = {} + if path and not path:match("^" .. project_root) then + path = nil + end + local git_status = Runner.run { project_root = project_root, + path = path, list_untracked = git_utils.should_show_untracked(project_root), list_ignored = true, timeout = M.config.timeout, } - M.projects[project_root] = { - files = git_status, - dirs = git_utils.file_status_to_dir_status(git_status, project_root), - watcher = watcher, - } + + if path then + for p in pairs(project.files) do + if p:match("^" .. path) then + project.files[p] = nil + end + end + project.files = vim.tbl_deep_extend("force", project.files, git_status) + else + project.files = git_status + end + + project.dirs = git_utils.file_status_to_dir_status(project.files, project_root) end function M.get_project(project_root) diff --git a/lua/nvim-tree/git/runner.lua b/lua/nvim-tree/git/runner.lua index af130b6649b..cd488a15349 100644 --- a/lua/nvim-tree/git/runner.lua +++ b/lua/nvim-tree/git/runner.lua @@ -45,7 +45,7 @@ function Runner:_getopts(stdout_handle, stderr_handle) local untracked = self.list_untracked and "-u" or nil local ignored = (self.list_untracked and self.list_ignored) and "--ignored=matching" or "--ignored=no" return { - args = { "--no-optional-locks", "status", "--porcelain=v1", ignored, untracked }, + args = { "--no-optional-locks", "status", "--porcelain=v1", ignored, untracked, self.path }, cwd = self.project_root, stdio = { nil, stdout_handle, stderr_handle }, } @@ -129,10 +129,11 @@ end -- This module runs a git process, which will be killed if it takes more than timeout which defaults to 400ms function Runner.run(opts) - local ps = log.profile_start("git job %s", opts.project_root) + local ps = log.profile_start("git job %s %s", opts.project_root, opts.path) local self = setmetatable({ project_root = opts.project_root, + path = opts.path, list_untracked = opts.list_untracked, list_ignored = opts.list_ignored, timeout = opts.timeout or 400, @@ -143,7 +144,7 @@ function Runner.run(opts) self:_run_git_job() self:_wait() - log.profile_end(ps, "git job %s", opts.project_root) + log.profile_end(ps, "git job %s %s", opts.project_root, opts.path) if self.rc == -1 then log.line("git", "job timed out")