diff options
Diffstat (limited to 'mac/.config/yazi/plugins.bak/git.yazi/main.lua')
| -rw-r--r-- | mac/.config/yazi/plugins.bak/git.yazi/main.lua | 261 |
1 files changed, 0 insertions, 261 deletions
diff --git a/mac/.config/yazi/plugins.bak/git.yazi/main.lua b/mac/.config/yazi/plugins.bak/git.yazi/main.lua deleted file mode 100644 index e6b3a36..0000000 --- a/mac/.config/yazi/plugins.bak/git.yazi/main.lua +++ /dev/null @@ -1,261 +0,0 @@ ---- @since 25.5.31 - -local WINDOWS = ya.target_family() == "windows" - --- The code of supported git status, --- also used to determine which status to show for directories when they contain different statuses --- see `bubble_up` ----@enum CODES -local CODES = { - excluded = 100, -- ignored directory - ignored = 6, -- ignored file - untracked = 5, - modified = 4, - added = 3, - deleted = 2, - updated = 1, - unknown = 0, -} - -local PATTERNS = { - { "!$", CODES.ignored }, - { "?$", CODES.untracked }, - { "[MT]", CODES.modified }, - { "[AC]", CODES.added }, - { "D", CODES.deleted }, - { "U", CODES.updated }, - { "[AD][AD]", CODES.updated }, -} - ----@param line string ----@return CODES, string -local function match(line) - local signs = line:sub(1, 2) - for _, p in ipairs(PATTERNS) do - local path, pattern, code = nil, p[1], p[2] - if signs:find(pattern) then - path = line:sub(4, 4) == '"' and line:sub(5, -2) or line:sub(4) - path = WINDOWS and path:gsub("/", "\\") or path - end - if not path then - elseif path:find("[/\\]$") then - -- Mark the ignored directory as `excluded`, so we can process it further within `propagate_down` - return code == CODES.ignored and CODES.excluded or code, path:sub(1, -2) - else - return code, path - end - ---@diagnostic disable-next-line: missing-return - end -end - ----@param cwd Url ----@return string? -local function root(cwd) - local is_worktree = function(url) - local file, head = io.open(tostring(url)), nil - if file then - head = file:read(8) - file:close() - end - return head == "gitdir: " - end - - repeat - local next = cwd:join(".git") - local cha = fs.cha(next) - if cha and (cha.is_dir or is_worktree(next)) then - return tostring(cwd) - end - cwd = cwd.parent - until not cwd -end - ----@param changed Changes ----@return Changes -local function bubble_up(changed) - local new, empty = {}, Url("") - for path, code in pairs(changed) do - if code ~= CODES.ignored then - local url = Url(path).parent - while url and url ~= empty do - local s = tostring(url) - new[s] = (new[s] or CODES.unknown) > code and new[s] or code - url = url.parent - end - end - end - return new -end - ----@param excluded string[] ----@param cwd Url ----@param repo Url ----@return Changes -local function propagate_down(excluded, cwd, repo) - local new, rel = {}, cwd:strip_prefix(repo) - for _, path in ipairs(excluded) do - if rel:starts_with(path) then - -- If `cwd` is a subdirectory of an excluded directory, also mark it as `excluded` - new[tostring(cwd)] = CODES.excluded - elseif cwd == repo:join(path).parent then - -- If `path` is a direct subdirectory of `cwd`, mark it as `ignored` - new[path] = CODES.ignored - else - -- Skipping, we only care about `cwd` itself and its direct subdirectories for maximum performance - end - end - return new -end - ----@param cwd string ----@param repo string ----@param changed Changes -local add = ya.sync(function(st, cwd, repo, changed) - ---@cast st State - - st.dirs[cwd] = repo - st.repos[repo] = st.repos[repo] or {} - for path, code in pairs(changed) do - if code == CODES.unknown then - st.repos[repo][path] = nil - elseif code == CODES.excluded then - -- Mark the directory with a special value `excluded` so that it can be distinguished during UI rendering - st.dirs[path] = CODES.excluded - else - st.repos[repo][path] = code - end - end - -- TODO: remove this - if ui.render then - ui.render() - else - ya.render() - end -end) - ----@param cwd string -local remove = ya.sync(function(st, cwd) - ---@cast st State - - local repo = st.dirs[cwd] - if not repo then - return - end - - -- TODO: remove this - if ui.render then - ui.render() - else - ya.render() - end - st.dirs[cwd] = nil - if not st.repos[repo] then - return - end - - for _, r in pairs(st.dirs) do - if r == repo then - return - end - end - st.repos[repo] = nil -end) - ----@param st State ----@param opts Options -local function setup(st, opts) - st.dirs = {} - st.repos = {} - - opts = opts or {} - opts.order = opts.order or 1500 - - local t = th.git or {} - local styles = { - [CODES.ignored] = t.ignored and ui.Style(t.ignored) or ui.Style():fg("darkgray"), - [CODES.untracked] = t.untracked and ui.Style(t.untracked) or ui.Style():fg("magenta"), - [CODES.modified] = t.modified and ui.Style(t.modified) or ui.Style():fg("yellow"), - [CODES.added] = t.added and ui.Style(t.added) or ui.Style():fg("green"), - [CODES.deleted] = t.deleted and ui.Style(t.deleted) or ui.Style():fg("red"), - [CODES.updated] = t.updated and ui.Style(t.updated) or ui.Style():fg("yellow"), - } - local signs = { - [CODES.ignored] = t.ignored_sign or "", - [CODES.untracked] = t.untracked_sign or "?", - [CODES.modified] = t.modified_sign or "", - [CODES.added] = t.added_sign or "", - [CODES.deleted] = t.deleted_sign or "", - [CODES.updated] = t.updated_sign or "", - } - - Linemode:children_add(function(self) - local url = self._file.url - local repo = st.dirs[tostring(url.base)] - local code - if repo then - code = repo == CODES.excluded and CODES.ignored or st.repos[repo][tostring(url):sub(#repo + 2)] - end - - if not code or signs[code] == "" then - return "" - elseif self._file.is_hovered then - return ui.Line { " ", signs[code] } - else - return ui.Line { " ", ui.Span(signs[code]):style(styles[code]) } - end - end, opts.order) -end - ----@type UnstableFetcher -local function fetch(_, job) - local cwd = job.files[1].url.base - local repo = root(cwd) - if not repo then - remove(tostring(cwd)) - return true - end - - local paths = {} - for _, file in ipairs(job.files) do - paths[#paths + 1] = tostring(file.url) - end - - -- stylua: ignore - local output, err = Command("git") - :cwd(tostring(cwd)) - :arg({ "--no-optional-locks", "-c", "core.quotePath=", "status", "--porcelain", "-unormal", "--no-renames", "--ignored=matching" }) - :arg(paths) - :stdout(Command.PIPED) - :output() - if not output then - return true, Err("Cannot spawn `git` command, error: %s", err) - end - - local changed, excluded = {}, {} - for line in output.stdout:gmatch("[^\r\n]+") do - local code, path = match(line) - if code == CODES.excluded then - excluded[#excluded + 1] = path - else - changed[path] = code - end - end - - if job.files[1].cha.is_dir then - ya.dict_merge(changed, bubble_up(changed)) - end - ya.dict_merge(changed, propagate_down(excluded, cwd, Url(repo))) - - -- Reset the status of any files that don't appear in the output of `git status` to `unknown`, - -- so that cleaning up outdated statuses from `st.repos` - for _, path in ipairs(paths) do - local s = path:sub(#repo + 2) - changed[s] = changed[s] or CODES.unknown - end - - add(tostring(cwd), repo, changed) - - return false -end - -return { setup = setup, fetch = fetch } |
