From 0e06731987a714500c8a76fdbe26bbeaa9d5980d Mon Sep 17 00:00:00 2001 From: Hydroxycarbamide Date: Sat, 1 Mar 2025 17:17:03 +0100 Subject: [PATCH 1/2] Add yazi plugins --- dot_config/yazi/init.lua | 2 + dot_config/yazi/keymap.toml | 5 + dot_config/yazi/package.toml | 17 ++ .../plugins/full-border.yazi/readonly_LICENSE | 21 ++ .../full-border.yazi/readonly_README.md | 32 +++ .../full-border.yazi/readonly_main.lua | 43 ++++ .../yazi/plugins/git.yazi/readonly_LICENSE | 21 ++ .../yazi/plugins/git.yazi/readonly_README.md | 78 +++++++ .../yazi/plugins/git.yazi/readonly_main.lua | 209 ++++++++++++++++++ .../plugins/lazygit.yazi/readonly_LICENSE | 21 ++ .../plugins/lazygit.yazi/readonly_README.md | 29 +++ .../plugins/lazygit.yazi/readonly_main.lua | 31 +++ dot_config/yazi/yazi.toml | 13 +- 13 files changed, 520 insertions(+), 2 deletions(-) create mode 100644 dot_config/yazi/init.lua create mode 100644 dot_config/yazi/package.toml create mode 100644 dot_config/yazi/plugins/full-border.yazi/readonly_LICENSE create mode 100644 dot_config/yazi/plugins/full-border.yazi/readonly_README.md create mode 100644 dot_config/yazi/plugins/full-border.yazi/readonly_main.lua create mode 100644 dot_config/yazi/plugins/git.yazi/readonly_LICENSE create mode 100644 dot_config/yazi/plugins/git.yazi/readonly_README.md create mode 100644 dot_config/yazi/plugins/git.yazi/readonly_main.lua create mode 100644 dot_config/yazi/plugins/lazygit.yazi/readonly_LICENSE create mode 100644 dot_config/yazi/plugins/lazygit.yazi/readonly_README.md create mode 100644 dot_config/yazi/plugins/lazygit.yazi/readonly_main.lua diff --git a/dot_config/yazi/init.lua b/dot_config/yazi/init.lua new file mode 100644 index 0000000..2348504 --- /dev/null +++ b/dot_config/yazi/init.lua @@ -0,0 +1,2 @@ +require("git"):setup() +require("full-border"):setup() diff --git a/dot_config/yazi/keymap.toml b/dot_config/yazi/keymap.toml index 342ed45..ad4538c 100644 --- a/dot_config/yazi/keymap.toml +++ b/dot_config/yazi/keymap.toml @@ -159,6 +159,11 @@ keymap = [ { on = "", run = "help", desc = "Open help" }, ] +[[manager.prepend_keymap]] +on = [ "g", "i" ] +run = "plugin lazygit" +desc = "run lazygit" + [tasks] keymap = [ diff --git a/dot_config/yazi/package.toml b/dot_config/yazi/package.toml new file mode 100644 index 0000000..c984ae9 --- /dev/null +++ b/dot_config/yazi/package.toml @@ -0,0 +1,17 @@ +[[plugin.deps]] +use = "yazi-rs/plugins:git" +rev = "5186af7" +hash = "771f18427fb75fb19990ce602bb322f4" + +[[plugin.deps]] +use = "yazi-rs/plugins:full-border" +rev = "5186af7" +hash = "ae9e1d0c6bfd68cdebc98cc684c22b45" + +[[plugin.deps]] +use = "Lil-Dank/lazygit" +rev = "9f924e3" +hash = "2b0c33928986f126d5c5a4cac31a6b46" + +[flavor] +deps = [] diff --git a/dot_config/yazi/plugins/full-border.yazi/readonly_LICENSE b/dot_config/yazi/plugins/full-border.yazi/readonly_LICENSE new file mode 100644 index 0000000..fb5b1d6 --- /dev/null +++ b/dot_config/yazi/plugins/full-border.yazi/readonly_LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 yazi-rs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dot_config/yazi/plugins/full-border.yazi/readonly_README.md b/dot_config/yazi/plugins/full-border.yazi/readonly_README.md new file mode 100644 index 0000000..6e78bd4 --- /dev/null +++ b/dot_config/yazi/plugins/full-border.yazi/readonly_README.md @@ -0,0 +1,32 @@ +# full-border.yazi + +Add a full border to Yazi to make it look fancier. + +![full-border](https://github.com/yazi-rs/plugins/assets/17523360/ef81b560-2465-4d36-abf2-5d21dcb7b987) + +## Installation + +```sh +ya pack -a yazi-rs/plugins:full-border +``` + +## Usage + +Add this to your `init.lua` to enable the plugin: + +```lua +require("full-border"):setup() +``` + +Or you can customize the border type: + +```lua +require("full-border"):setup { + -- Available values: ui.Border.PLAIN, ui.Border.ROUNDED + type = ui.Border.ROUNDED, +} +``` + +## License + +This plugin is MIT-licensed. For more information check the [LICENSE](LICENSE) file. diff --git a/dot_config/yazi/plugins/full-border.yazi/readonly_main.lua b/dot_config/yazi/plugins/full-border.yazi/readonly_main.lua new file mode 100644 index 0000000..058371a --- /dev/null +++ b/dot_config/yazi/plugins/full-border.yazi/readonly_main.lua @@ -0,0 +1,43 @@ +--- @since 25.2.7 + +local function setup(_, opts) + local type = opts and opts.type or ui.Border.ROUNDED + local old_build = Tab.build + + Tab.build = function(self, ...) + local bar = function(c, x, y) + if x <= 0 or x == self._area.w - 1 then + return ui.Bar(ui.Bar.TOP) + end + + return ui.Bar(ui.Bar.TOP) + :area( + ui.Rect { x = x, y = math.max(0, y), w = ya.clamp(0, self._area.w - x, 1), h = math.min(1, self._area.h) } + ) + :symbol(c) + end + + local c = self._chunks + self._chunks = { + c[1]:pad(ui.Pad.y(1)), + c[2]:pad(ui.Pad(1, c[3].w > 0 and 0 or 1, 1, c[1].w > 0 and 0 or 1)), + c[3]:pad(ui.Pad.y(1)), + } + + local style = THEME.manager.border_style + self._base = ya.list_merge(self._base or {}, { + ui.Border(ui.Border.ALL):area(self._area):type(type):style(style), + ui.Bar(ui.Bar.RIGHT):area(self._chunks[1]):style(style), + ui.Bar(ui.Bar.LEFT):area(self._chunks[3]):style(style), + + bar("┬", c[1].right - 1, c[1].y), + bar("┴", c[1].right - 1, c[1].bottom - 1), + bar("┬", c[2].right, c[2].y), + bar("┴", c[2].right, c[2].bottom - 1), + }) + + old_build(self, ...) + end +end + +return { setup = setup } diff --git a/dot_config/yazi/plugins/git.yazi/readonly_LICENSE b/dot_config/yazi/plugins/git.yazi/readonly_LICENSE new file mode 100644 index 0000000..fb5b1d6 --- /dev/null +++ b/dot_config/yazi/plugins/git.yazi/readonly_LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 yazi-rs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dot_config/yazi/plugins/git.yazi/readonly_README.md b/dot_config/yazi/plugins/git.yazi/readonly_README.md new file mode 100644 index 0000000..1054230 --- /dev/null +++ b/dot_config/yazi/plugins/git.yazi/readonly_README.md @@ -0,0 +1,78 @@ +# git.yazi + +> [!NOTE] +> Yazi v25.2.7 or later is required for this plugin to work. + +Show the status of Git file changes as linemode in the file list. + +https://github.com/user-attachments/assets/34976be9-a871-4ffe-9d5a-c4cdd0bf4576 + +## Installation + +```sh +ya pack -a yazi-rs/plugins:git +``` + +## Setup + +Add the following to your `~/.config/yazi/init.lua`: + +```lua +require("git"):setup() +``` + +And register it as fetchers in your `~/.config/yazi/yazi.toml`: + +```toml +[[plugin.prepend_fetchers]] +id = "git" +name = "*" +run = "git" + +[[plugin.prepend_fetchers]] +id = "git" +name = "*/" +run = "git" +``` + +## Advanced + +You can customize the [Style](https://yazi-rs.github.io/docs/plugins/layout#style) of the status sign with: + +- `THEME.git.modified` +- `THEME.git.added` +- `THEME.git.untracked` +- `THEME.git.ignored` +- `THEME.git.deleted` +- `THEME.git.updated` + +For example: + +```lua +-- ~/.config/yazi/init.lua +THEME.git = THEME.git or {} +THEME.git.modified = ui.Style():fg("blue") +THEME.git.deleted = ui.Style():fg("red"):bold() +``` + +You can also customize the text of the status sign with: + +- `THEME.git.modified_sign` +- `THEME.git.added_sign` +- `THEME.git.untracked_sign` +- `THEME.git.ignored_sign` +- `THEME.git.deleted_sign` +- `THEME.git.updated_sign` + +For example: + +```lua +-- ~/.config/yazi/init.lua +THEME.git = THEME.git or {} +THEME.git.modified_sign = "M" +THEME.git.deleted_sign = "D" +``` + +## License + +This plugin is MIT-licensed. For more information check the [LICENSE](LICENSE) file. diff --git a/dot_config/yazi/plugins/git.yazi/readonly_main.lua b/dot_config/yazi/plugins/git.yazi/readonly_main.lua new file mode 100644 index 0000000..edd54fc --- /dev/null +++ b/dot_config/yazi/plugins/git.yazi/readonly_main.lua @@ -0,0 +1,209 @@ +--- @since 25.2.7 + +local WIN = ya.target_family() == "windows" +local PATS = { + { "[MT]", 6 }, -- Modified + { "[AC]", 5 }, -- Added + { "?$", 4 }, -- Untracked + { "!$", 3 }, -- Ignored + { "D", 2 }, -- Deleted + { "U", 1 }, -- Updated + { "[AD][AD]", 1 }, -- Updated +} + +local function match(line) + local signs = line:sub(1, 2) + for _, p in ipairs(PATS) do + local path + if signs:find(p[1]) then + path = line:sub(4, 4) == '"' and line:sub(5, -2) or line:sub(4) + path = WIN and path:gsub("/", "\\") or path + end + if not path then + elseif path:find("[/\\]$") then + return p[2] == 3 and 30 or p[2], path:sub(1, -2) + else + return p[2], path + end + end +end + +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 + +local function bubble_up(changed) + local new, empty = {}, Url("") + for k, v in pairs(changed) do + if v ~= 3 and v ~= 30 then + local url = Url(k):parent() + while url and url ~= empty do + local s = tostring(url) + new[s] = (new[s] or 0) > v and new[s] or v + url = url:parent() + end + end + end + return new +end + +local function propagate_down(ignored, cwd, repo) + local new, rel = {}, cwd:strip_prefix(repo) + for k, v in pairs(ignored) do + if v == 30 then + if rel:starts_with(k) then + new[tostring(repo:join(rel))] = 30 + elseif cwd == repo:join(k):parent() then + new[k] = 3 + end + end + end + return new +end + +local add = ya.sync(function(st, cwd, repo, changed) + st.dirs[cwd] = repo + st.repos[repo] = st.repos[repo] or {} + for k, v in pairs(changed) do + if v == 0 then + st.repos[repo][k] = nil + elseif v == 30 then + st.dirs[k] = "" + else + st.repos[repo][k] = v + end + end + ya.render() +end) + +local remove = ya.sync(function(st, cwd) + local dir = st.dirs[cwd] + if not dir then + return + end + + ya.render() + st.dirs[cwd] = nil + if not st.repos[dir] then + return + end + + for _, r in pairs(st.dirs) do + if r == dir then + return + end + end + st.repos[dir] = nil +end) + +local function setup(st, opts) + st.dirs = {} + st.repos = {} + + opts = opts or {} + opts.order = opts.order or 1500 + + -- Chosen by ChatGPT fairly, PRs are welcome to adjust them + local t = THEME.git or {} + local styles = { + [6] = t.modified and ui.Style(t.modified) or ui.Style():fg("#ffa500"), + [5] = t.added and ui.Style(t.added) or ui.Style():fg("#32cd32"), + [4] = t.untracked and ui.Style(t.untracked) or ui.Style():fg("#a9a9a9"), + [3] = t.ignored and ui.Style(t.ignored) or ui.Style():fg("#696969"), + [2] = t.deleted and ui.Style(t.deleted) or ui.Style():fg("#ff4500"), + [1] = t.updated and ui.Style(t.updated) or ui.Style():fg("#1e90ff"), + } + local signs = { + [6] = t.modified_sign and t.modified_sign or "", + [5] = t.added_sign and t.added_sign or "", + [4] = t.untracked_sign and t.untracked_sign or "", + [3] = t.ignored_sign and t.ignored_sign or "", + [2] = t.deleted_sign and t.deleted_sign or "", + [1] = t.updated_sign and t.updated_sign or "U", + } + + Linemode:children_add(function(self) + local url = self._file.url + local dir = st.dirs[tostring(url:parent())] + local change + if dir then + change = dir == "" and 3 or st.repos[dir][tostring(url):sub(#dir + 2)] + end + + if not change or signs[change] == "" then + return "" + elseif self._file:is_hovered() then + return ui.Line { " ", signs[change] } + else + return ui.Line { " ", ui.Span(signs[change]):style(styles[change]) } + end + end, opts.order) +end + +local function fetch(_, job) + local cwd = job.files[1].url:parent() + local repo = root(cwd) + if not repo then + remove(tostring(cwd)) + return true + end + + local paths = {} + for _, f in ipairs(job.files) do + paths[#paths + 1] = tostring(f.url) + end + + -- stylua: ignore + local output, err = Command("git") + :cwd(tostring(cwd)) + :args({ "--no-optional-locks", "-c", "core.quotePath=", "status", "--porcelain", "-unormal", "--no-renames", "--ignored=matching" }) + :args(paths) + :stdout(Command.PIPED) + :output() + if not output then + return true, Err("Cannot spawn `git` command, error: %s", err) + end + + local changed, ignored = {}, {} + for line in output.stdout:gmatch("[^\r\n]+") do + local sign, path = match(line) + if sign == 30 then + ignored[path] = sign + else + changed[path] = sign + end + end + + if job.files[1].cha.is_dir then + ya.dict_merge(changed, bubble_up(changed)) + ya.dict_merge(changed, propagate_down(ignored, cwd, Url(repo))) + else + ya.dict_merge(changed, propagate_down(ignored, cwd, Url(repo))) + end + + for _, p in ipairs(paths) do + local s = p:sub(#repo + 2) + changed[s] = changed[s] or 0 + end + add(tostring(cwd), repo, changed) + + return false +end + +return { setup = setup, fetch = fetch } diff --git a/dot_config/yazi/plugins/lazygit.yazi/readonly_LICENSE b/dot_config/yazi/plugins/lazygit.yazi/readonly_LICENSE new file mode 100644 index 0000000..ae1f60d --- /dev/null +++ b/dot_config/yazi/plugins/lazygit.yazi/readonly_LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Darius + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dot_config/yazi/plugins/lazygit.yazi/readonly_README.md b/dot_config/yazi/plugins/lazygit.yazi/readonly_README.md new file mode 100644 index 0000000..e96c9c6 --- /dev/null +++ b/dot_config/yazi/plugins/lazygit.yazi/readonly_README.md @@ -0,0 +1,29 @@ +# lazygit.yazi +Plugin for [Yazi](https://github.com/sxyazi/yazi) to manage git repos with [lazygit](https://github.com/jesseduffield/lazygit) +## Dependencies +Make sure [lazygit](https://github.com/jesseduffield/lazygit) is installed and in your `PATH`. +## Installation + +### Using `ya pack` +``` +ya pack -a Lil-Dank/lazygit +``` + +### Manual +**Linux/macOS** +``` +git clone https://github.com/Lil-Dank/lazygit.yazi.git ~/.config/yazi/plugins/lazygit.yazi +``` +**Windows** +``` +git clone https://github.com/Lil-Dank/lazygit.yazi.git %AppData%\yazi\config\plugins\lazygit.yazi +``` +## Configuration +add this to your **keymap.toml** file +```toml +[[manager.prepend_keymap]] +on = [ "g", "i" ] +run = "plugin lazygit" +desc = "run lazygit" +``` +you can customize the keybinding however you like. Please refer to the [keymap.toml](https://yazi-rs.github.io/docs/configuration/keymap) documentation diff --git a/dot_config/yazi/plugins/lazygit.yazi/readonly_main.lua b/dot_config/yazi/plugins/lazygit.yazi/readonly_main.lua new file mode 100644 index 0000000..a5925ea --- /dev/null +++ b/dot_config/yazi/plugins/lazygit.yazi/readonly_main.lua @@ -0,0 +1,31 @@ +return { + entry = function() + local output = Command("git"):arg("status"):stderr(Command.PIPED):output() + if output.stderr ~= "" then + ya.notify({ + title = "lazygit", + content = "Not in a git directory", + level = "warn", + timeout = 5, + }) + else + permit = ya.hide() + local output, err_code = Command("lazygit"):stderr(Command.PIPED):output() + if err_code ~= nil then + ya.notify({ + title = "Failed to run lazygit command", + content = "Status: " .. err_code, + level = "error", + timeout = 5, + }) + elseif not output.status.success then + ya.notify({ + title = "lazygit in" .. cwd .. "failed, exit code " .. output.status.code, + content = output.stderr, + level = "error", + timeout = 5, + }) + end + end + end, +} \ No newline at end of file diff --git a/dot_config/yazi/yazi.toml b/dot_config/yazi/yazi.toml index d49ba2d..b9d1cc6 100644 --- a/dot_config/yazi/yazi.toml +++ b/dot_config/yazi/yazi.toml @@ -31,8 +31,7 @@ ueberzug_offset = [ 0, 0, 0, 0 ] [opener] edit = [ { run = '${EDITOR:-vi} "$@"', desc = "$EDITOR", block = true, for = "unix" }, - { run = 'code %*', orphan = true, desc = "code", for = "windows" }, - { run = 'code -w %*', block = true, desc = "code (block)", for = "windows" }, + { run = 'hx %*', block = true, desc = "code (block)", for = "windows" }, ] open = [ { run = 'xdg-open "$1"', desc = "Open", for = "linux" }, @@ -147,6 +146,16 @@ previewers = [ { name = "*", run = "file" }, ] +[[plugin.prepend_fetchers]] +id = "git" +name = "*" +run = "git" + +[[plugin.prepend_fetchers]] +id = "git" +name = "*/" +run = "git" + [input] cursor_blink = false From ab39adc2f35c979d655a6a06a2debe832863fd1d Mon Sep 17 00:00:00 2001 From: Hydroxycarbamide Date: Sat, 1 Mar 2025 17:17:53 +0100 Subject: [PATCH 2/2] Add tesseract screenshot --- dot_local/bin/executable_tesseract-shot.sh | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 dot_local/bin/executable_tesseract-shot.sh diff --git a/dot_local/bin/executable_tesseract-shot.sh b/dot_local/bin/executable_tesseract-shot.sh new file mode 100644 index 0000000..3f40081 --- /dev/null +++ b/dot_local/bin/executable_tesseract-shot.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +grim -g "$(slurp)" /tmp/grim.png && tesseract -l eng+jpn /tmp/grim.png - | wl-copy && wl-paste | xargs -I{} notify-send "Tesseract" "Copied '{}'"