From e0b75689303847c175afb227347ed94b6b181438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Dom=C3=ADnguez?= Date: Thu, 8 May 2025 20:39:49 -0400 Subject: [PATCH 01/11] include lazy.lua file --- .config/nvim/lua/config/lazy.lua | 92 ++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 .config/nvim/lua/config/lazy.lua diff --git a/.config/nvim/lua/config/lazy.lua b/.config/nvim/lua/config/lazy.lua new file mode 100644 index 0000000..2514b1b --- /dev/null +++ b/.config/nvim/lua/config/lazy.lua @@ -0,0 +1,92 @@ +-- Bootstrap lazy.nvim +local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" +if not (vim.uv or vim.loop).fs_stat(lazypath) then + local lazyrepo = "https://github.com/folke/lazy.nvim.git" + local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) + if vim.v.shell_error ~= 0 then + vim.api.nvim_echo({ + { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, + { out, "WarningMsg" }, + { "\nPress any key to exit..." }, + }, true, {}) + vim.fn.getchar() + os.exit(1) + end +end +vim.opt.rtp:prepend(lazypath) + +-- Make sure to setup `mapleader` and `maplocalleader` before +-- loading lazy.nvim so that mappings are correct. +-- This is also a good place to setup other settings (vim.opt) +vim.g.mapleader = "'" +vim.g.maplocalleader = "\\" + +-- Setup lazy.nvim +require("lazy").setup({ + spec = { + -- import your plugins + { import = "plugins" }, + }, + -- Configure any other settings here. See the documentation for more details. + -- colorscheme that will be used when installing plugins. + {colorscheme = "dracula"}, + -- automatically check for plugin updates + checker = { enabled = true }, +}) +-- vim script +vim.cmd[[colorscheme dracula]] +vim.cmd[[syntax enable]] +vim.cmd[[set number noswapfile hlsearch ignorecase incsearch cursorline]] +vim.cmd[[autocmd BufNewFile,BufRead ~/.config/waybar/config,*.json set ft=javascript]] +vim.cmd[[hi Normal guibg=NONE ctermbg=NONE]] +vim.cmd[[highlight CursorLine ctermbg=black]] +vim.cmd[[set noshowmode]] +-- lualine +require('lualine').setup { + options = { + icons_enabled = true, + theme = 'dracula', + component_separators = { left = '', right = ''}, + section_separators = { left = '', right = ''}, + disabled_filetypes = { + statusline = {}, + winbar = {}, + }, + ignore_focus = {}, + always_divide_middle = true, + always_show_tabline = true, + globalstatus = false, + refresh = { + statusline = 100, + tabline = 100, + winbar = 100, + } + }, + sections = { + lualine_a = {'mode'}, + lualine_b = {'branch', 'diff', 'diagnostics'}, + lualine_c = {'filename'}, + lualine_x = {'encoding', 'fileformat', 'filetype'}, + lualine_y = {'progress'}, + lualine_z = {'location'} + }, + inactive_sections = { + lualine_a = {}, + lualine_b = {}, + lualine_c = {'filename'}, + lualine_x = {'location'}, + lualine_y = {}, + lualine_z = {} + }, + tabline = { + lualine_a = {'buffers'}, + lualine_b = {'branch'}, + lualine_c = {'filename'}, + lualine_x = {}, + lualine_y = {}, + lualine_z = {'tabs'} + }, + winbar = {}, + inactive_winbar = {}, + extensions = {} +} From 27c4be39c925f9b47aea6ce40a3f7503f50fc880 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Dom=C3=ADnguez?= Date: Thu, 8 May 2025 20:40:34 -0400 Subject: [PATCH 02/11] include coq.lua file --- .config/nvim/lua/plugins/coq.lua | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .config/nvim/lua/plugins/coq.lua diff --git a/.config/nvim/lua/plugins/coq.lua b/.config/nvim/lua/plugins/coq.lua new file mode 100644 index 0000000..2ce438a --- /dev/null +++ b/.config/nvim/lua/plugins/coq.lua @@ -0,0 +1,32 @@ +-- lualine +return { +{ +"neovim/nvim-lspconfig", -- REQUIRED: for native Neovim LSP integration + lazy = false, -- REQUIRED: tell lazy.nvim to start this plugin at startup + dependencies = { + -- main one + { "ms-jpq/coq_nvim", branch = "coq" }, + + -- 9000+ Snippets + { "ms-jpq/coq.artifacts", branch = "artifacts" }, + + -- lua & third party sources -- See https://github.com/ms-jpq/coq.thirdparty + -- Need to **configure separately** + { 'ms-jpq/coq.thirdparty', branch = "3p" } + -- - shell repl + -- - nvim lua api + -- - scientific calculator + -- - comment banner + -- - etc + }, + init = function() + vim.g.coq_settings = { + auto_start = "shut-up", -- if you want to start COQ at startup + -- Your COQ settings here + } + end, + config = function() + -- Your LSP settings here + end, + } +} From b7f4de7763caf7323b69e2f4826ea114ffa90310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Dom=C3=ADnguez?= Date: Thu, 8 May 2025 20:40:54 -0400 Subject: [PATCH 03/11] include dracula.lua file --- .config/nvim/lua/plugins/dracula.lua | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .config/nvim/lua/plugins/dracula.lua diff --git a/.config/nvim/lua/plugins/dracula.lua b/.config/nvim/lua/plugins/dracula.lua new file mode 100644 index 0000000..70f0c3b --- /dev/null +++ b/.config/nvim/lua/plugins/dracula.lua @@ -0,0 +1,7 @@ +-- lualine +return { +{ + "Mofiqul/dracula.nvim", + lazy = false + } +} From f33ff5a32f27ca4e984fdec76976f79e8249ea86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Dom=C3=ADnguez?= Date: Thu, 8 May 2025 20:41:18 -0400 Subject: [PATCH 04/11] include lualine.lua file --- .config/nvim/lua/plugins/lualine.lua | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .config/nvim/lua/plugins/lualine.lua diff --git a/.config/nvim/lua/plugins/lualine.lua b/.config/nvim/lua/plugins/lualine.lua new file mode 100644 index 0000000..f9a55c4 --- /dev/null +++ b/.config/nvim/lua/plugins/lualine.lua @@ -0,0 +1,8 @@ +-- lualine +return { +{ + "nvim-lualine/lualine.nvim", + dependencies = { 'nvim-tree/nvim-web-devicons' }, + lazy = false + } +} From 0d4ed43f53d41a50de1fce75e9fb3841407580d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Dom=C3=ADnguez?= Date: Thu, 8 May 2025 20:42:07 -0400 Subject: [PATCH 05/11] include init.lua file --- .config/nvim/init.lua | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .config/nvim/init.lua diff --git a/.config/nvim/init.lua b/.config/nvim/init.lua new file mode 100644 index 0000000..0297e90 --- /dev/null +++ b/.config/nvim/init.lua @@ -0,0 +1,2 @@ +-- lazy vim package manager +require("config.lazy") From 937b4c1636c9da3564e5a3d09126a4b7bee3daec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Dom=C3=ADnguez?= Date: Thu, 8 May 2025 20:45:50 -0400 Subject: [PATCH 06/11] include yazi.toml --- .config/yazi/yazi.toml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .config/yazi/yazi.toml diff --git a/.config/yazi/yazi.toml b/.config/yazi/yazi.toml new file mode 100644 index 0000000..49c88e1 --- /dev/null +++ b/.config/yazi/yazi.toml @@ -0,0 +1,30 @@ +[manager] +show_hidden = true +linemode = "size_and_mtime" + +[plugin] +prepend_previewers = [ + # Archive previewer + { mime = "application/*zip", run = "ouch" }, + { mime = "application/x-tar", run = "ouch" }, + { mime = "application/x-bzip2", run = "ouch" }, + { mime = "application/x-7z-compressed", run = "ouch" }, + { mime = "application/x-rar", run = "ouch" }, + { mime = "application/x-xz", run = "ouch" }, + { mime = "application/xz", run = "ouch" }, +] + +[[plugin.prepend_fetchers]] +id = "git" +name = "*" +run = "git" + +[[plugin.prepend_fetchers]] +id = "git" +name = "*/" +run = "git" + +[opener] +extract = [ + { run = 'ouch d -y "$@"', desc = "Extract here with ouch", for = "unix" }, +] From 89d76f45209c0853ba331b9f67f57d3e1f91c012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Dom=C3=ADnguez?= Date: Thu, 8 May 2025 20:46:07 -0400 Subject: [PATCH 07/11] include theme.toml --- .config/yazi/theme.toml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .config/yazi/theme.toml diff --git a/.config/yazi/theme.toml b/.config/yazi/theme.toml new file mode 100644 index 0000000..b91f47c --- /dev/null +++ b/.config/yazi/theme.toml @@ -0,0 +1,2 @@ +[flavor] +dark = "dracula" From 818baa19e09b33090da40b9fd2990672da5ae910 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Dom=C3=ADnguez?= Date: Thu, 8 May 2025 20:46:44 -0400 Subject: [PATCH 08/11] include keymap.toml --- .config/yazi/keymap.toml | 108 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 .config/yazi/keymap.toml diff --git a/.config/yazi/keymap.toml b/.config/yazi/keymap.toml new file mode 100644 index 0000000..a175477 --- /dev/null +++ b/.config/yazi/keymap.toml @@ -0,0 +1,108 @@ +[[manager.prepend_keymap]] +on = "!" +run = 'shell "$SHELL" --block' +desc = "Open shell here" + +[[manager.prepend_keymap]] +on = "T" +run = "plugin toggle-pane min-preview" +desc = "Show or hide the preview pane" + +[[manager.prepend_keymap]] +on = [ "g", "d" ] +run = "cd /mnt/M2/Downloads" +desc = "Downloads" + +[[manager.prepend_keymap]] +on = [ "g", "b" ] +run = "cd /mnt/Backups" +desc = "Backups" + +[[manager.prepend_keymap]] +on = [ "g", "v" ] +run = "cd /media/Games" +desc = "Games" + +[[manager.prepend_keymap]] +on = [ "g", "s" ] +run = "cd /mnt/SSD" +desc = "SSD" + +[[manager.prepend_keymap]] +on = [ "g", "m" ] +run = "cd /mnt/M2" +desc = "M2" + +[[manager.prepend_keymap]] +on = [ "g", "n" ] +run = "cd /mnt/M2/Nextcloud" +desc = "Nextcloud" + +[[manager.prepend_keymap]] +on = [ "g", "r" ] +run = "cd /run/media" +desc = "Media" + +[[manager.prepend_keymap]] +on = [ "g", "a" ] +run = "cd /mnt/M2/Downloads/AUR" +desc = "AUR" + +[[manager.prepend_keymap]] +on = [ "g", "!" ] +run = "cd ~/.bin/sh" +desc = "Scripts" + +[[manager.prepend_keymap]] +on = [ "g", "t" ] +run = "cd ~/.local/share/Trash/files" +desc = "Trash" + +[[manager.prepend_keymap]] +on = [ "g", "y" ] +run = "cd ~/Sync" +desc = "Sync" + +[[manager.prepend_keymap]] +on = [ "c", "m" ] +run = "plugin chmod" +desc = "Chmod on selected files" + +[[manager.prepend_keymap]] +on = ["C"] +run = "plugin ouch" +desc = "Compress with ouch" + +[[manager.prepend_keymap]] +on = "2" +run = "plugin smart-switch 1" +desc = "Switch or create tab 2" + +[[manager.prepend_keymap]] +on = "3" +run = "plugin smart-switch 2" +desc = "Switch or create tab 3" + +[[manager.prepend_keymap]] +on = "4" +run = "plugin smart-switch 3" +desc = "Switch or create tab 4" + +[[manager.prepend_keymap]] +on = "5" +run = "plugin smart-switch 4" +desc = "Switch or create tab 5" + +[[manager.prepend_keymap]] +on = "t" +run = "plugin smart-tab" +desc = "Create a tab and enter the hovered directory" + +[[manager.prepend_keymap]] +on = [ "g", "R" ] +run = 'shell -- ya emit cd "$(git rev-parse --show-toplevel)"' +desc = "Repo root" + +[[manager.prepend_keymap]] +on = "q" +run = "plugin confirm-quit" From ae61234858153eab6aa2114c11c23ea53a3f0356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Dom=C3=ADnguez?= Date: Thu, 8 May 2025 20:47:08 -0400 Subject: [PATCH 09/11] include init.lua --- .config/yazi/init.lua | 59 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 .config/yazi/init.lua diff --git a/.config/yazi/init.lua b/.config/yazi/init.lua new file mode 100644 index 0000000..99e606a --- /dev/null +++ b/.config/yazi/init.lua @@ -0,0 +1,59 @@ +-- full border +require("full-border"):setup() +-- size and time linemode +function Linemode:size_and_mtime() + local time = math.floor(self._file.cha.mtime or 0) + if time == 0 then + time = "" + elseif os.date("%Y", time) == os.date("%Y") then + time = os.date("%b %d %H:%M", time) + else + time = os.date("%b %d %Y", time) + end + + local size = self._file:size() + return string.format("%s %s", size and ya.readable_size(size) or "-", time) +end + +-- show symlinks +Status:children_add(function(self) + local h = self._current.hovered + if h and h.link_to then + return " -> " .. tostring(h.link_to) + else + return "" + end +end, 3300, Status.LEFT) +-- Show user/group of files in status bar +Status:children_add(function() + local h = cx.active.current.hovered + if h == nil or ya.target_family() ~= "unix" then + return "" + end + + return ui.Line { + ui.Span(ya.user_name(h.cha.uid) or tostring(h.cha.uid)):fg("magenta"), + ":", + ui.Span(ya.group_name(h.cha.gid) or tostring(h.cha.gid)):fg("magenta"), + " ", + } +end, 500, Status.RIGHT) +-- Show username and hostname in header +Header:children_add(function() + if ya.target_family() ~= "unix" then + return "" + end + return ui.Span(ya.user_name() .. "@" .. ya.host_name() .. ":"):fg("blue") +end, 500, Header.LEFT) +-- startship prompt +require("starship"):setup({ + -- Hide flags (such as filter, find and search). This is recommended for starship themes which + -- are intended to go across the entire width of the terminal. + hide_flags = false, -- Default: false + -- Whether to place flags after the starship prompt. False means the flags will be placed before the prompt. + flags_after_prompt = true, -- Default: true + -- Custom starship configuration file to use + config_file = "~/.config/starship_full.toml", -- Default: nil +}) +-- git for yazi +require("git"):setup() From cd81d7b2b43e2d4e8681304a1638cdf1ff751050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Dom=C3=ADnguez?= Date: Thu, 8 May 2025 20:48:25 -0400 Subject: [PATCH 10/11] include plugins --- .config/yazi/plugins/chmod.yazi/LICENSE | 21 ++ .config/yazi/plugins/chmod.yazi/README.md | 28 +++ .config/yazi/plugins/chmod.yazi/main.lua | 41 ++++ .../yazi/plugins/confirm-quit.yazi/main.lua | 18 ++ .config/yazi/plugins/full-border.yazi/LICENSE | 21 ++ .../yazi/plugins/full-border.yazi/README.md | 32 +++ .../yazi/plugins/full-border.yazi/main.lua | 43 ++++ .config/yazi/plugins/git.yazi/LICENSE | 21 ++ .config/yazi/plugins/git.yazi/README.md | 78 ++++++ .config/yazi/plugins/git.yazi/main.lua | 228 ++++++++++++++++++ .config/yazi/plugins/ouch.yazi/LICENSE | 21 ++ .config/yazi/plugins/ouch.yazi/README.md | 79 ++++++ .config/yazi/plugins/ouch.yazi/main.lua | 148 ++++++++++++ .../yazi/plugins/smart-switch.yazi/main.lua | 13 + .config/yazi/plugins/smart-tab.yazi/main.lua | 7 + .config/yazi/plugins/starship.yazi/LICENSE | 21 ++ .config/yazi/plugins/starship.yazi/README.md | 108 +++++++++ .config/yazi/plugins/starship.yazi/main.lua | 123 ++++++++++ .config/yazi/plugins/toggle-pane.yazi/LICENSE | 21 ++ .../yazi/plugins/toggle-pane.yazi/README.md | 78 ++++++ .../yazi/plugins/toggle-pane.yazi/main.lua | 51 ++++ 21 files changed, 1201 insertions(+) create mode 100644 .config/yazi/plugins/chmod.yazi/LICENSE create mode 100644 .config/yazi/plugins/chmod.yazi/README.md create mode 100644 .config/yazi/plugins/chmod.yazi/main.lua create mode 100644 .config/yazi/plugins/confirm-quit.yazi/main.lua create mode 100644 .config/yazi/plugins/full-border.yazi/LICENSE create mode 100644 .config/yazi/plugins/full-border.yazi/README.md create mode 100644 .config/yazi/plugins/full-border.yazi/main.lua create mode 100644 .config/yazi/plugins/git.yazi/LICENSE create mode 100644 .config/yazi/plugins/git.yazi/README.md create mode 100644 .config/yazi/plugins/git.yazi/main.lua create mode 100644 .config/yazi/plugins/ouch.yazi/LICENSE create mode 100644 .config/yazi/plugins/ouch.yazi/README.md create mode 100644 .config/yazi/plugins/ouch.yazi/main.lua create mode 100644 .config/yazi/plugins/smart-switch.yazi/main.lua create mode 100644 .config/yazi/plugins/smart-tab.yazi/main.lua create mode 100644 .config/yazi/plugins/starship.yazi/LICENSE create mode 100644 .config/yazi/plugins/starship.yazi/README.md create mode 100644 .config/yazi/plugins/starship.yazi/main.lua create mode 100644 .config/yazi/plugins/toggle-pane.yazi/LICENSE create mode 100644 .config/yazi/plugins/toggle-pane.yazi/README.md create mode 100644 .config/yazi/plugins/toggle-pane.yazi/main.lua diff --git a/.config/yazi/plugins/chmod.yazi/LICENSE b/.config/yazi/plugins/chmod.yazi/LICENSE new file mode 100644 index 0000000..fb5b1d6 --- /dev/null +++ b/.config/yazi/plugins/chmod.yazi/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/.config/yazi/plugins/chmod.yazi/README.md b/.config/yazi/plugins/chmod.yazi/README.md new file mode 100644 index 0000000..e8a6614 --- /dev/null +++ b/.config/yazi/plugins/chmod.yazi/README.md @@ -0,0 +1,28 @@ +# chmod.yazi + +Execute `chmod` on the selected files to change their mode. This plugin is only available on Unix platforms since it relies on [`chmod(2)`](https://man7.org/linux/man-pages/man2/chmod.2.html). + +https://github.com/yazi-rs/plugins/assets/17523360/7aa3abc2-d057-498c-8473-a6282c59c464 + +## Installation + +```sh +ya pack -a yazi-rs/plugins:chmod +``` + +## Usage + +Add this to your `~/.config/yazi/keymap.toml`: + +```toml +[[manager.prepend_keymap]] +on = [ "c", "m" ] +run = "plugin chmod" +desc = "Chmod on selected files" +``` + +Make sure the c => m key is not used elsewhere. + +## License + +This plugin is MIT-licensed. For more information check the [LICENSE](LICENSE) file. diff --git a/.config/yazi/plugins/chmod.yazi/main.lua b/.config/yazi/plugins/chmod.yazi/main.lua new file mode 100644 index 0000000..ad565c6 --- /dev/null +++ b/.config/yazi/plugins/chmod.yazi/main.lua @@ -0,0 +1,41 @@ +--- @since 25.2.26 + +local selected_or_hovered = ya.sync(function() + local tab, paths = cx.active, {} + for _, u in pairs(tab.selected) do + paths[#paths + 1] = tostring(u) + end + if #paths == 0 and tab.current.hovered then + paths[1] = tostring(tab.current.hovered.url) + end + return paths +end) + +return { + entry = function() + ya.mgr_emit("escape", { visual = true }) + + local urls = selected_or_hovered() + if #urls == 0 then + return ya.notify { title = "Chmod", content = "No file selected", level = "warn", timeout = 5 } + end + + local value, event = ya.input { + title = "Chmod:", + position = { "top-center", y = 3, w = 40 }, + } + if event ~= 1 then + return + end + + local status, err = Command("chmod"):arg(value):args(urls):spawn():wait() + if not status or not status.success then + ya.notify { + title = "Chmod", + content = string.format("Chmod on selected files failed, error: %s", status and status.code or err), + level = "error", + timeout = 5, + } + end + end, +} diff --git a/.config/yazi/plugins/confirm-quit.yazi/main.lua b/.config/yazi/plugins/confirm-quit.yazi/main.lua new file mode 100644 index 0000000..6394880 --- /dev/null +++ b/.config/yazi/plugins/confirm-quit.yazi/main.lua @@ -0,0 +1,18 @@ +local count = ya.sync(function() return #cx.tabs end) + +local function entry() + if count() < 2 then + return ya.mgr_emit("quit", {}) + end + + local yes = ya.confirm { + pos = { "center", w = 60, h = 10 }, + title = "Quit?", + content = ui.Text("There are multiple tabs open. Quit anyway?"):wrap(ui.Text.WRAP), + } + if yes then + ya.mgr_emit("quit", {}) + end +end + +return { entry = entry } diff --git a/.config/yazi/plugins/full-border.yazi/LICENSE b/.config/yazi/plugins/full-border.yazi/LICENSE new file mode 100644 index 0000000..fb5b1d6 --- /dev/null +++ b/.config/yazi/plugins/full-border.yazi/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/.config/yazi/plugins/full-border.yazi/README.md b/.config/yazi/plugins/full-border.yazi/README.md new file mode 100644 index 0000000..6e78bd4 --- /dev/null +++ b/.config/yazi/plugins/full-border.yazi/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/.config/yazi/plugins/full-border.yazi/main.lua b/.config/yazi/plugins/full-border.yazi/main.lua new file mode 100644 index 0000000..abb1c3e --- /dev/null +++ b/.config/yazi/plugins/full-border.yazi/main.lua @@ -0,0 +1,43 @@ +--- @since 25.2.26 + +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 or th.mgr.border_symbol ~= "│" 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 = th.mgr.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/.config/yazi/plugins/git.yazi/LICENSE b/.config/yazi/plugins/git.yazi/LICENSE new file mode 100644 index 0000000..fb5b1d6 --- /dev/null +++ b/.config/yazi/plugins/git.yazi/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/.config/yazi/plugins/git.yazi/README.md b/.config/yazi/plugins/git.yazi/README.md new file mode 100644 index 0000000..4c5b07c --- /dev/null +++ b/.config/yazi/plugins/git.yazi/README.md @@ -0,0 +1,78 @@ +# git.yazi + +> [!NOTE] +> Yazi v25.2.26 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: + +- `th.git.modified` +- `th.git.added` +- `th.git.untracked` +- `th.git.ignored` +- `th.git.deleted` +- `th.git.updated` + +For example: + +```lua +-- ~/.config/yazi/init.lua +th.git = th.git or {} +th.git.modified = ui.Style():fg("blue") +th.git.deleted = ui.Style():fg("red"):bold() +``` + +You can also customize the text of the status sign with: + +- `th.git.modified_sign` +- `th.git.added_sign` +- `th.git.untracked_sign` +- `th.git.ignored_sign` +- `th.git.deleted_sign` +- `th.git.updated_sign` + +For example: + +```lua +-- ~/.config/yazi/init.lua +th.git = th.git or {} +th.git.modified_sign = "M" +th.git.deleted_sign = "D" +``` + +## License + +This plugin is MIT-licensed. For more information check the [LICENSE](LICENSE) file. diff --git a/.config/yazi/plugins/git.yazi/main.lua b/.config/yazi/plugins/git.yazi/main.lua new file mode 100644 index 0000000..d8f365a --- /dev/null +++ b/.config/yazi/plugins/git.yazi/main.lua @@ -0,0 +1,228 @@ +--- @since 25.4.4 + +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` +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 }, +} + +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 + 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 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 + +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 + +local add = ya.sync(function(st, cwd, repo, changed) + 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 + ya.render() +end) + +local remove = ya.sync(function(st, cwd) + local repo = st.dirs[cwd] + if not repo then + return + end + + ya.render() + 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) + +local function setup(st, opts) + st.dirs = {} -- Mapping between a directory and its corresponding repository + st.repos = {} -- Mapping between a repository and the status of each of its files + + 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 + +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)) + :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, 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 } diff --git a/.config/yazi/plugins/ouch.yazi/LICENSE b/.config/yazi/plugins/ouch.yazi/LICENSE new file mode 100644 index 0000000..3f9d766 --- /dev/null +++ b/.config/yazi/plugins/ouch.yazi/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 ndtoan96 + +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/.config/yazi/plugins/ouch.yazi/README.md b/.config/yazi/plugins/ouch.yazi/README.md new file mode 100644 index 0000000..e09b3df --- /dev/null +++ b/.config/yazi/plugins/ouch.yazi/README.md @@ -0,0 +1,79 @@ +# ouch.yazi + +[ouch](https://github.com/ouch-org/ouch) plugin for [Yazi](https://github.com/sxyazi/yazi). + +![ouch.yazi](https://github.com/ndtoan96/ouch.yazi/assets/33489972/946397ec-b37b-4bf4-93f1-c676fc8e59f2) + +## Features +- Archive preview +- Compression + +## Installation + +### Yazi package manager +```bash +ya pack -a ndtoan96/ouch +``` + +### Git +```bash +# Linux/macOS +git clone https://github.com/ndtoan96/ouch.yazi.git ~/.config/yazi/plugins/ouch.yazi + +# Windows with cmd +git clone https://github.com/ndtoan96/ouch.yazi.git %AppData%\yazi\config\plugins\ouch.yazi + +# Windows with powershell +git clone https://github.com/ndtoan96/ouch.yazi.git "$($env:APPDATA)\yazi\config\plugins\ouch.yazi" +``` + +Make sure you have [ouch](https://github.com/ouch-org/ouch) installed and in your `PATH`. + +## Usage + +### Preview +For archive preview, add this to your `yazi.toml`: + +```toml +[plugin] +prepend_previewers = [ + # Archive previewer + { mime = "application/*zip", run = "ouch" }, + { mime = "application/x-tar", run = "ouch" }, + { mime = "application/x-bzip2", run = "ouch" }, + { mime = "application/x-7z-compressed", run = "ouch" }, + { mime = "application/x-rar", run = "ouch" }, + { mime = "application/x-xz", run = "ouch" }, + { mime = "application/xz", run = "ouch" }, +] +``` + +Now go to an archive on Yazi, you should see the archive's content in the preview pane. You can use `J` and `K` to roll up and down the preview. + +If you want to change the icon or the style of text, you can modify the `peek` function in `init.lua` file (all of them are stored in the `lines` variable). + +### Compression +For compession, add this to your `keymap.toml`: + +```toml +[[manager.prepend_keymap]] +on = ["C"] +run = "plugin ouch" +desc = "Compress with ouch" +``` + +The plugin uses `zip` format by default. You can change the format when you name the output file, `ouch` will detect format based on file extension. + +And, for example, if you would like to set `7z` as default format, you can use `plugin ouch 7z`. + +### Decompression +This plugin does not provide a decompression feature because it already is supported by Yazi. +To decompress with `ouch`, configure the opener in `yazi.toml`. + +```toml +[opener] +extract = [ + { run = 'ouch d -y "%*"', desc = "Extract here with ouch", for = "windows" }, + { run = 'ouch d -y "$@"', desc = "Extract here with ouch", for = "unix" }, +] +``` diff --git a/.config/yazi/plugins/ouch.yazi/main.lua b/.config/yazi/plugins/ouch.yazi/main.lua new file mode 100644 index 0000000..f642eb3 --- /dev/null +++ b/.config/yazi/plugins/ouch.yazi/main.lua @@ -0,0 +1,148 @@ +local M = {} + +function M:peek(job) + local child = Command("ouch") + :args({ "l", "-t", "-y", tostring(job.file.url) }) + :stdout(Command.PIPED) + :stderr(Command.PIPED) + :spawn() + local limit = job.area.h + local file_name = string.match(tostring(job.file.url), ".*[/\\](.*)") + local lines = string.format("📁 \x1b[2m%s\x1b[0m\n", file_name) + local num_lines = 1 + local num_skip = 0 + repeat + local line, event = child:read_line() + if event == 1 then + ya.err(tostring(event)) + elseif event ~= 0 then + break + end + + if line:find('Archive', 1, true) ~= 1 and line:find('[INFO]', 1, true) ~= 1 then + if num_skip >= job.skip then + lines = lines .. line + num_lines = num_lines + 1 + else + num_skip = num_skip + 1 + end + end + until num_lines >= limit + + child:start_kill() + if job.skip > 0 and num_lines < limit then + ya.manager_emit( + "peek", + { tostring(math.max(0, job.skip - (limit - num_lines))), only_if = tostring(job.file.url), upper_bound = "" } + ) + else + ya.preview_widgets(job, { ui.Text(lines):area(job.area) }) + end +end + +function M:seek(job) + local h = cx.active.current.hovered + if h and h.url == job.file.url then + local step = math.floor(job.units * job.area.h / 10) + ya.manager_emit("peek", { + math.max(0, cx.active.preview.skip + step), + only_if = tostring(job.file.url), + }) + end +end + +-- Check if file exists +local function file_exists(name) + local f = io.open(name, "r") + if f ~= nil then + io.close(f) + return true + else + return false + end +end + +-- Get the files that need to be compressed and infer a default archive name +local get_compression_target = ya.sync(function() + local tab = cx.active + local default_name + local paths = {} + if #tab.selected == 0 then + if tab.current.hovered then + local name = tab.current.hovered.name + default_name = name + table.insert(paths, name) + else + return + end + else + default_name = tab.current.cwd.name + for _, url in pairs(tab.selected) do + table.insert(paths, tostring(url)) + end + -- The compression targets are aquired, now unselect them + ya.manager_emit("escape", {}) + end + return paths, default_name +end) + +local function invoke_compress_command(paths, name) + local cmd_output, err_code = Command("ouch") + :args({ "c", "-y" }) + :args(paths) + :arg(name) + :stderr(Command.PIPED) + :output() + if err_code ~= nil then + ya.notify({ + title = "Failed to run ouch command", + content = "Status: " .. err_code, + timeout = 5.0, + level = "error", + }) + elseif not cmd_output.status.success then + ya.notify({ + title = "Compression failed: status code " .. cmd_output.status.code, + content = cmd_output.stderr, + timeout = 5.0, + level = "error", + }) + end +end + +function M:entry(job) + local default_fmt = job.args[1] + if default_fmt == nil then + default_fmt = "zip" + end + + ya.manager_emit("escape", { visual = true }) + + -- Get the files that need to be compressed and infer a default archive name + local paths, default_name = get_compression_target() + + -- Get archive name from user + local output_name, name_event = ya.input({ + title = "Create archive:", + value = default_name .. "." .. default_fmt, + position = { "top-center", y = 3, w = 40 }, + }) + if name_event ~= 1 then + return + end + + -- Get confirmation if file exists + if file_exists(output_name) then + local confirm, confirm_event = ya.input({ + title = "Overwrite " .. output_name .. "? (y/N)", + position = { "top-center", y = 3, w = 40 }, + }) + if not (confirm_event == 1 and confirm:lower() == "y") then + return + end + end + + invoke_compress_command(paths, output_name) +end + +return M diff --git a/.config/yazi/plugins/smart-switch.yazi/main.lua b/.config/yazi/plugins/smart-switch.yazi/main.lua new file mode 100644 index 0000000..aae94f4 --- /dev/null +++ b/.config/yazi/plugins/smart-switch.yazi/main.lua @@ -0,0 +1,13 @@ +--- @sync entry +local function entry(_, job) + local cur = cx.active.current + for _ = #cx.tabs, job.args[1] do + ya.mgr_emit("tab_create", { cur.cwd }) + if cur.hovered then + ya.mgr_emit("reveal", { cur.hovered.url }) + end + end + ya.mgr_emit("tab_switch", { job.args[1] }) +end + +return { entry = entry } diff --git a/.config/yazi/plugins/smart-tab.yazi/main.lua b/.config/yazi/plugins/smart-tab.yazi/main.lua new file mode 100644 index 0000000..107f706 --- /dev/null +++ b/.config/yazi/plugins/smart-tab.yazi/main.lua @@ -0,0 +1,7 @@ +--- @sync entry +return { + entry = function() + local h = cx.active.current.hovered + ya.mgr_emit("tab_create", h and h.cha.is_dir and { h.url } or { current = true }) + end, +} diff --git a/.config/yazi/plugins/starship.yazi/LICENSE b/.config/yazi/plugins/starship.yazi/LICENSE new file mode 100644 index 0000000..c03ce66 --- /dev/null +++ b/.config/yazi/plugins/starship.yazi/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Rolv Apneseth + +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/.config/yazi/plugins/starship.yazi/README.md b/.config/yazi/plugins/starship.yazi/README.md new file mode 100644 index 0000000..b2b4dd8 --- /dev/null +++ b/.config/yazi/plugins/starship.yazi/README.md @@ -0,0 +1,108 @@ +# starship.yazi + +Starship prompt plugin for [Yazi](https://github.com/sxyazi/yazi) + + + +## Requirements + +- [Yazi](https://github.com/sxyazi/yazi) (v25.4.8+) +- [starship](https://github.com/starship/starship) + +## Installation + +```bash +ya pack -a Rolv-Apneseth/starship +``` + +### Manual + +```sh +# Linux / MacOS +git clone https://github.com/Rolv-Apneseth/starship.yazi.git ~/.config/yazi/plugins/starship.yazi +# Windows +git clone https://github.com/Rolv-Apneseth/starship.yazi.git %AppData%\yazi\config\plugins\starship.yazi +``` + +## Usage + +Add this to `~/.config/yazi/init.lua`: + +```lua +require("starship"):setup() +``` + +Make sure you have [starship](https://github.com/starship/starship) installed and in your `PATH`. + +## Config + +Here is an example with all available config options: + +```lua +require("starship"):setup({ + -- Hide flags (such as filter, find and search). This is recommended for starship themes which + -- are intended to go across the entire width of the terminal. + hide_flags = false, -- Default: false + -- Whether to place flags after the starship prompt. False means the flags will be placed before the prompt. + flags_after_prompt = true, -- Default: true + -- Custom starship configuration file to use + config_file = "~/.config/starship_full.toml", -- Default: nil +}) +``` + +## Extra + +If you use a `starship` theme with a background colour, it might look a bit to cramped on just the one line `Yazi` gives the header by default. To fix this, you can add this to your `init.lua`: + +
+Click to expand + +```lua +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):area(ui.Rect.default) + 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 = th.mgr.border_style + self._base = ya.list_merge(self._base or {}, { + ui.Bar(ui.Bar.RIGHT):area(self._chunks[1]):style(style), + ui.Bar(ui.Bar.LEFT):area(self._chunks[1]):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 +``` + +
+ +> [!NOTE] +> This works by overriding your `Tab.build` function so make sure this is the only place you're doing that in your config. For example, this would be incompatible with the [full-border plugin](https://github.com/yazi-rs/plugins/tree/main/full-border.yazi) + +## Thanks + +- [sxyazi](https://github.com/sxyazi) for providing the code for this plugin and the demo video [in this comment](https://github.com/sxyazi/yazi/issues/767#issuecomment-1977082834) diff --git a/.config/yazi/plugins/starship.yazi/main.lua b/.config/yazi/plugins/starship.yazi/main.lua new file mode 100644 index 0000000..c4d3943 --- /dev/null +++ b/.config/yazi/plugins/starship.yazi/main.lua @@ -0,0 +1,123 @@ +--- @since 25.4.8 + +-- For development +--[[ local function notify(message) ]] +--[[ ya.notify({ title = "Starship", content = message, timeout = 3 }) ]] +--[[ end ]] + +local save = ya.sync(function(st, _cwd, output) + st.output = output + ya.render() +end) + +-- Helper function for accessing the `config_file` state variable +---@return string +local get_config_file = ya.sync(function(st) + return st.config_file +end) + +return { + ---User arguments for setup method + ---@class SetupArgs + ---@field config_file string Absolute path to a starship config file + ---@field hide_flags boolean Whether to hide all flags (such as filter and search). Recommended for themes which are intended to take the full width of the terminal. + ---@field flags_after_prompt boolean Whether to place flags (such as filter and search) after the starship prompt. By default this is true. + + --- Setup plugin + --- @param st table State + --- @param args SetupArgs|nil + setup = function(st, args) + local hide_flags = false + local flags_after_prompt = true + + -- Check setup args + if args ~= nil then + if args.config_file ~= nil then + local url = Url(args.config_file) + if url.is_regular then + local config_file = args.config_file + + -- Manually replace '~' and '$HOME' at the start of the path with the OS environment variable + local home = os.getenv("HOME") + if home then + home = tostring(home) + config_file = config_file:gsub("^~", home):gsub("^$HOME", home) + end + + st.config_file = config_file + end + end + + if args.hide_flags ~= nil then + hide_flags = args.hide_flags + end + + if args.flags_after_prompt ~= nil then + flags_after_prompt = args.flags_after_prompt + end + end + + -- Replace default header widget + Header:children_remove(1, Header.LEFT) + Header:children_add(function(self) + local max = self._area.w - self._right_width + if max <= 0 then + return "" + end + + if hide_flags or not st.output then + return ui.Line.parse(st.output or "") + end + + -- Split `st.output` at the first line break (or keep as is if none was found) + local output = st.output:match("([^\n]*)\n?") or st.output + + local flags = self:flags() + if flags_after_prompt then + output = output .. " " .. flags + else + output = flags .. " " .. output + end + + return ui.Line.parse(output) + end, 1000, Header.LEFT) + + -- Pass current working directory and custom config path (if specified) to the plugin's entry point + ---Callback for subscribers to update the prompt + local callback = function() + local cwd = cx.active.current.cwd + if st.cwd ~= cwd then + st.cwd = cwd + + ya.manager_emit("plugin", { + st._id, + ya.quote(tostring(cwd), true), + }) + end + end + + -- Subscribe to events + ps.sub("cd", callback) + ps.sub("tab", callback) + end, + + entry = function(_, job) + local args = job.args + local command = Command("starship") + :arg("prompt") + :stdin(Command.INHERIT) + :cwd(args[1]) + :env("STARSHIP_SHELL", "") + + -- Point to custom starship config + local config_file = get_config_file() + if config_file then + command = command:env("STARSHIP_CONFIG", config_file) + end + + local output = command:output() + if output then + save(args[1], output.stdout:gsub("^%s+", "")) + end + end, +} diff --git a/.config/yazi/plugins/toggle-pane.yazi/LICENSE b/.config/yazi/plugins/toggle-pane.yazi/LICENSE new file mode 100644 index 0000000..fb5b1d6 --- /dev/null +++ b/.config/yazi/plugins/toggle-pane.yazi/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/.config/yazi/plugins/toggle-pane.yazi/README.md b/.config/yazi/plugins/toggle-pane.yazi/README.md new file mode 100644 index 0000000..d00c169 --- /dev/null +++ b/.config/yazi/plugins/toggle-pane.yazi/README.md @@ -0,0 +1,78 @@ +# toggle-pane.yazi + +Toggle the show, hide, and maximize states for different panes: parent, current, and preview. It respects the user's [`ratio` settings](https://yazi-rs.github.io/docs/configuration/yazi#manager.ratio)! + +Assume the user's `ratio` is $$[A, B, C]$$, that is, $$\text{parent}=A, \text{current}=B, \text{preview}=C$$: + +- `min-parent`: Toggles between $$0$$ and $$A$$ - the parent is either completely hidden or showed with width $$A$$. +- `max-parent`: Toggles between $$A$$ and $$\infty$$ - the parent is either showed with width $$A$$ or fills the entire screen. +- `min-current`: Toggles between $$0$$ and $$B$$ - the current is either completely hidden or showed with width $$B$$. +- `max-current`: Toggles between $$B$$ and $$\infty$$ - the current is either showed with width $$B$$ or fills the entire screen. +- `min-preview`: Toggles between $$0$$ and $$C$$ - the preview is either completely hidden or showed with width $$C$$. +- `max-preview`: Toggles between $$C$$ and $$\infty$$ - the preview is either showed with width $$C$$ or fills the entire screen. +- `reset`: Resets to the user's configured `ratio`. + +## Installation + +```sh +ya pack -a yazi-rs/plugins:toggle-pane +``` + +## Usage + +Hide/Show preview: + +```toml +# keymap.toml +[[manager.prepend_keymap]] +on = "T" +run = "plugin toggle-pane min-preview" +desc = "Show or hide the preview pane" +``` + +Maximize/Restore preview: + +```toml +# keymap.toml +[[manager.prepend_keymap]] +on = "T" +run = "plugin toggle-pane max-preview" +desc = "Maximize or restore the preview pane" +``` + +You can replace `preview` with `current` or `parent` to toggle the other panes. + +## Advanced + +In addition to triggering the plugin with a keypress, you can also trigger it in your `init.lua` file: + +```lua +if os.getenv("NVIM") then + require("toggle-pane"):entry("min-preview") +end +``` + +In the example above, when it detects that you're [using Yazi in nvim](https://yazi-rs.github.io/docs/resources#vim), the preview is hidden by default — you can always press `T` (or any key you've bound) to show it again. + +## Tips + +This plugin only maximizes the "available preview area", without actually changing the content size. + +This means that the appearance of your preview largely depends on the previewer you are using. +However, most previewers tend to make the most of the available space, so this usually isn't an issue. + +For image previews, you may want to tune up the [`max_width`][max-width] and [`max_height`][max-height] options in your `yazi.toml`: + +```toml +[preview] +# Change them to your desired values +max_width = 1000 +max_height = 1000 +``` + +[max-width]: https://yazi-rs.github.io/docs/configuration/yazi/#preview.max_width +[max-height]: https://yazi-rs.github.io/docs/configuration/yazi/#preview.max_height + +## License + +This plugin is MIT-licensed. For more information, check the [LICENSE](LICENSE) file. diff --git a/.config/yazi/plugins/toggle-pane.yazi/main.lua b/.config/yazi/plugins/toggle-pane.yazi/main.lua new file mode 100644 index 0000000..b408692 --- /dev/null +++ b/.config/yazi/plugins/toggle-pane.yazi/main.lua @@ -0,0 +1,51 @@ +--- @since 25.2.26 +--- @sync entry + +local function entry(st, job) + local R = rt.mgr.ratio + job = type(job) == "string" and { args = { job } } or job + + st.parent = st.parent or R.parent + st.current = st.current or R.current + st.preview = st.preview or R.preview + + local act, to = string.match(job.args[1] or "", "(.-)-(.+)") + if act == "min" then + st[to] = st[to] == R[to] and 0 or R[to] + elseif act == "max" then + local max = st[to] == 65535 and R[to] or 65535 + st.parent = st.parent == 65535 and R.parent or st.parent + st.current = st.current == 65535 and R.current or st.current + st.preview = st.preview == 65535 and R.preview or st.preview + st[to] = max + end + + if not st.old then + st.old = Tab.layout + Tab.layout = function(self) + local all = st.parent + st.current + st.preview + self._chunks = ui.Layout() + :direction(ui.Layout.HORIZONTAL) + :constraints({ + ui.Constraint.Ratio(st.parent, all), + ui.Constraint.Ratio(st.current, all), + ui.Constraint.Ratio(st.preview, all), + }) + :split(self._area) + end + end + + if not act then + Tab.layout, st.old = st.old, nil + st.parent, st.current, st.preview = nil, nil, nil + end + + -- TODO: remove this in the future + if ya.emit then + ya.emit("app:resize", {}) + else + ya.app_emit("resize", {}) + end +end + +return { entry = entry } From 97bdfbc9d14f81d738c315db3e509963ae4cfa6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Dom=C3=ADnguez?= Date: Thu, 8 May 2025 20:49:10 -0400 Subject: [PATCH 11/11] include flavor.toml --- .config/yazi/flavors/dracula.yazi/flavor.toml | 170 ++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 .config/yazi/flavors/dracula.yazi/flavor.toml diff --git a/.config/yazi/flavors/dracula.yazi/flavor.toml b/.config/yazi/flavors/dracula.yazi/flavor.toml new file mode 100644 index 0000000..01ded4a --- /dev/null +++ b/.config/yazi/flavors/dracula.yazi/flavor.toml @@ -0,0 +1,170 @@ +# vim:fileencoding=utf-8:foldmethod=marker + +# : Manager {{{ + +[manager] +cwd = { fg = "#8be9fd" } + +# Hovered +hovered = { reversed = true } +preview_hovered = { underline = true } + +# Find +find_keyword = { fg = "#f1fa8c", bold = true, italic = true, underline = true } +find_position = { fg = "#ff79c6", bg = "reset", bold = true, italic = true } + +# Marker +marker_copied = { fg = "#50fa7b", bg = "#50fa7b" } +marker_cut = { fg = "#ff5555", bg = "#ff5555" } +marker_marked = { fg = "#8be9fd", bg = "#8be9fd" } +marker_selected = { fg = "#f1fa8c", bg = "#f1fa8c" } + +# Tab +tab_active = { reversed = true } +tab_inactive = {} +tab_width = 1 + +# Count +count_copied = { fg = "#282a36", bg = "#50fa7b" } +count_cut = { fg = "#282a36", bg = "#ff5555" } +count_selected = { fg = "#282a36", bg = "#f1fa8c" } + +# Border +border_symbol = "│" +border_style = { fg = "#7282b5" } + +# : }}} + + +# : Mode {{{ + +[mode] + +normal_main = { fg = "#282a36", bg = "#bd93f9", bold = true } +normal_alt = { fg = "#bd93f9", bg = "#44475a" } + +# Select mode +select_main = { fg = "#282a36", bg = "#8be9fd", bold = true } +select_alt = { fg = "#8be9fd", bg = "#44475a" } + +# Unset mode +unset_main = { fg = "#282a36", bg = "#ffb86c", bold = true } +unset_alt = { fg = "#ffb86c", bg = "#44475a" } + +# : }}} + + +# : Status bar {{{ + +[status] +# Permissions +perm_sep = { fg = "#7282b5" } +perm_type = { fg = "#bd93f9" } +perm_read = { fg = "#f1fa8c" } +perm_write = { fg = "#ff5555" } +perm_exec = { fg = "#50fa7b" } + +# Progress +progress_label = { fg = "#ffffff", bold = true } +progress_normal = { fg = "#bd93f9", bg = "#63667d" } +progress_error = { fg = "#ff5555", bg = "#63667d" } + +# : }}} + + +# : Pick {{{ + +[pick] +border = { fg = "#bd93f9" } +active = { fg = "#ff79c6", bold = true } +inactive = {} + +# : }}} + + +# : Input {{{ + +[input] +border = { fg = "#bd93f9" } +title = {} +value = {} +selected = { reversed = true } + +# : }}} + + +# : Completion {{{ + +[cmp] +border = { fg = "#bd93f9" } + +# : }}} + + +# : Tasks {{{ + +[tasks] +border = { fg = "#bd93f9" } +title = {} +hovered = { fg = "#ff79c6", underline = true } + +# : }}} + + +# : Which {{{ + +[which] +mask = { bg = "#44475a" } +cand = { fg = "#8be9fd" } +rest = { fg = "#8998c9" } +desc = { fg = "#ff79c6" } +separator = "  " +separator_style = { fg = "#83869c" } + +# : }}} + + +# : Help {{{ + +[help] +on = { fg = "#8be9fd" } +run = { fg = "#ff79c6" } +hovered = { reversed = true, bold = true } +footer = { fg = "#44475a", bg = "#f8f8f2" } + +# : }}} + + +# : Notify {{{ + +[notify] +title_info = { fg = "#50fa7b" } +title_warn = { fg = "#f1fa8c" } +title_error = { fg = "#ff5555" } + +# : }}} + + +# : File-specific styles {{{ + +[filetype] + +rules = [ + # Images + { mime = "image/*", fg = "#8be9fd" }, + + # Media + { mime = "{audio,video}/*", fg = "#f1fa8c" }, + + # Archives + { mime = "application/{zip,rar,7z*,tar,gzip,xz,zstd,bzip*,lzma,compress,archive,cpio,arj,xar,ms-cab*}", fg = "#ff79c6" }, + + # Documents + { mime = "application/{pdf,doc,rtf}", fg = "#50fa7b" }, + + # Fallback + { name = "*", fg = "#f8f8f2" }, + { name = "*/", fg = "#bd93f9" } +] + +# : }}}