From 198408c106ebacab689e9aa2366b6b0131e6b2ad Mon Sep 17 00:00:00 2001 From: David Chen Date: Tue, 27 Aug 2024 18:03:59 -0500 Subject: [PATCH] yazi! --- .gitignore | 2 + README.md | 2 +- yazi/init.lua | 27 ++ yazi/keymap.toml | 342 +++++++++++++++++ yazi/package.toml | 5 + yazi/plugins/git.yazi | 1 + yazi/plugins/smart-enter.yazi/init.lua | 6 + .../DO_NOT_MODIFY_ANYTHING_IN_THIS_DIRECTORY | 0 yazi/plugins/starship.yazi/LICENSE | 21 ++ yazi/plugins/starship.yazi/README.md | 106 ++++++ yazi/plugins/starship.yazi/init.lua | 78 ++++ yazi/plugins/yamb.yazi/.gitattributes | 1 + yazi/plugins/yamb.yazi/LICENSE | 21 ++ yazi/plugins/yamb.yazi/README.md | 107 ++++++ yazi/plugins/yamb.yazi/init.lua | 352 ++++++++++++++++++ .../DO_NOT_MODIFY_ANYTHING_IN_THIS_DIRECTORY | 0 yazi/plugins/yaziline.yazi/LICENSE | 21 ++ yazi/plugins/yaziline.yazi/README.md | 131 +++++++ yazi/plugins/yaziline.yazi/init.lua | 133 +++++++ yazi/theme.toml | 26 ++ yazi/yazi.toml | 202 ++++++++++ zsh/aliases.zsh | 4 +- 22 files changed, 1585 insertions(+), 3 deletions(-) create mode 100644 yazi/init.lua create mode 100644 yazi/keymap.toml create mode 100644 yazi/package.toml create mode 160000 yazi/plugins/git.yazi create mode 100644 yazi/plugins/smart-enter.yazi/init.lua create mode 100644 yazi/plugins/starship.yazi/DO_NOT_MODIFY_ANYTHING_IN_THIS_DIRECTORY create mode 100644 yazi/plugins/starship.yazi/LICENSE create mode 100644 yazi/plugins/starship.yazi/README.md create mode 100644 yazi/plugins/starship.yazi/init.lua create mode 100644 yazi/plugins/yamb.yazi/.gitattributes create mode 100644 yazi/plugins/yamb.yazi/LICENSE create mode 100644 yazi/plugins/yamb.yazi/README.md create mode 100644 yazi/plugins/yamb.yazi/init.lua create mode 100644 yazi/plugins/yaziline.yazi/DO_NOT_MODIFY_ANYTHING_IN_THIS_DIRECTORY create mode 100644 yazi/plugins/yaziline.yazi/LICENSE create mode 100644 yazi/plugins/yaziline.yazi/README.md create mode 100644 yazi/plugins/yaziline.yazi/init.lua create mode 100644 yazi/theme.toml create mode 100644 yazi/yazi.toml diff --git a/.gitignore b/.gitignore index e5e9f5f..bb21fbd 100755 --- a/.gitignore +++ b/.gitignore @@ -46,8 +46,10 @@ ranger/plugins/devicons_linemode.pyo !/.yabairc !/Default.bttpreset !/joshuto +!/yazi !/*.bttpreset jesseduffield/lazynpm/state.yml ranger/__pycache__/commands.cpython-39.opt-1.pyc +yazi/bookmark diff --git a/README.md b/README.md index 6ad0fe7..db548dc 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ BTW, my scripts are in [this repo](https://github.com/theniceboy/scripts). ``` brew install fzf the_silver_searcher ripgrep fd brew install automake wget gcc gdb bat ccat tree git-delta git-flow git rainbarf jsdoc3 cmake gnu-getopt gnu-sed node go -brew install ccls tmux neovim jesseduffield/lazygit/lazygit joshuto +brew install ccls tmux neovim jesseduffield/lazygit/lazygit yazi starship brew install awscli gh tldr brew install speedtest-cli ncdu neofetch onefetch bmon loc ``` diff --git a/yazi/init.lua b/yazi/init.lua new file mode 100644 index 0000000..b38aa57 --- /dev/null +++ b/yazi/init.lua @@ -0,0 +1,27 @@ +require("yaziline"):setup { + separator_style = "curvy", + select_symbol = "", + yank_symbol = "󰆐", + filename_max_length = 24, -- trim when filename > 24 + filename_trim_length = 6 -- trim 6 chars from both ends +} +require("starship"):setup {} +require("git"):setup {} + +Status:children_add(function() + local h = cx.active.current.hovered + if h == nil or ya.target_family() ~= "unix" then + return ui.Line {} + end + + return ui.Line { + ui.Span(ya.user_name(h.cha.uid) or tostring(h.cha.uid)):fg("magenta"), + ui.Span(":"), + ui.Span(ya.group_name(h.cha.gid) or tostring(h.cha.gid)):fg("magenta"), + ui.Span(" "), + } +end, 500, Status.RIGHT) + +require("yamb"):setup { + cli = "fzf", +} diff --git a/yazi/keymap.toml b/yazi/keymap.toml new file mode 100644 index 0000000..fba9e74 --- /dev/null +++ b/yazi/keymap.toml @@ -0,0 +1,342 @@ +# A TOML linter such as https://taplo.tamasfe.dev/ can use this schema to validate your config. +# If you encounter any issues, please make an issue at https://github.com/yazi-rs/schemas. +"$schema" = "https://yazi-rs.github.io/schemas/keymap.json" + +[manager] +prepend_keymap = [ + { on = "i", run = 'plugin --sync smart-enter' }, + { on = "", run = 'plugin --sync smart-enter' }, + { on = "S", run = 'shell "$SHELL" --block --confirm' }, + { on = [ + "'", + "a", + ], run = "plugin yamb --args=save", desc = "Add bookmark" }, + { on = [ + "'", + "g", + ], run = "plugin yamb --args=jump_by_key", desc = "Jump bookmark by key" }, + { on = [ + "'", + "'", + ], run = "plugin yamb --args=jump_by_fzf", desc = "Jump bookmark by fzf" }, + { on = [ + "'", + "d", + ], run = "plugin yamb --args=delete_by_key", desc = "Delete bookmark by key" }, + { on = [ + "'", + "A", + ], run = "plugin yamb --args=delete_all", desc = "Delete all bookmarks" }, + { on = [ + "'", + "r", + ], run = "plugin yamb --args=rename_by_key", desc = "Rename bookmark by key" }, + { on = [ + "'", + "R", + ], run = "plugin yamb --args=rename_by_fzf", desc = "Rename bookmark by fzf" }, +] + +keymap = [ + { on = "", run = "escape", desc = "Exit visual mode, clear selected, or cancel search" }, + { on = "", run = "escape", desc = "Exit visual mode, clear selected, or cancel search" }, + #{ on = "q", run = "quit", desc = "Exit the process" }, + { on = "q", run = "close", desc = "Close the current tab, or quit if it is last tab" }, + { on = "Q", run = "quit --no-cwd-file", desc = "Exit the process without writing cwd-file" }, + { on = "", run = "suspend", desc = "Suspend the process" }, + + # Hopping + { on = "u", run = "arrow -1", desc = "Move cursor up" }, + { on = "e", run = "arrow 1", desc = "Move cursor down" }, + + { on = "", run = "arrow -1", desc = "Move cursor up" }, + { on = "", run = "arrow 1", desc = "Move cursor down" }, + + { on = "", run = "arrow -50%", desc = "Move cursor up half page" }, + { on = "", run = "arrow 50%", desc = "Move cursor down half page" }, + + { on = "U", run = "arrow -5", desc = "Move cursor up 5 rows" }, + { on = "E", run = "arrow 5", desc = "Move cursor down 5 rows" }, + + { on = "", run = "arrow -50%", desc = "Move cursor up half page" }, + { on = "", run = "arrow 50%", desc = "Move cursor down half page" }, + { on = "", run = "arrow -100%", desc = "Move cursor up one page" }, + { on = "", run = "arrow 100%", desc = "Move cursor down one page" }, + + { on = ["g", "g"], run = "arrow -99999999", desc = "Move cursor to the top" }, + { on = "G", run = "arrow 99999999", desc = "Move cursor to the bottom" }, + + # Navigation + { on = "n", run = "leave", desc = "Go back to the parent directory" }, + + { on = "", run = "leave", desc = "Go back to the parent directory" }, + { on = "", run = "enter", desc = "Enter the child directory" }, + + { on = "N", run = "back", desc = "Go back to the previous directory" }, + { on = "I", run = "forward", desc = "Go forward to the next directory" }, + + # Selection + { on = "", run = ["select --state=none", "arrow 1"], desc = "Toggle the current selection state" }, + { on = "v", run = "visual_mode", desc = "Enter visual mode (selection mode)" }, + { on = "V", run = "visual_mode --unset", desc = "Enter visual mode (unset mode)" }, + { on = "", run = "select_all --state=true", desc = "Select all files" }, + { on = "", run = "select_all --state=none", desc = "Inverse selection of all files" }, + + # Find + { on = "", run = "plugin fzf", desc = "Jump to a directory or reveal a file using fzf" }, + { on = ["z", "o"], run = "plugin zoxide", desc = "Jump to a directory using zoxide" }, + # { on = "f", run = "search fd", desc = "Search files by name using fd" }, + { on = "F", run = "search rg", desc = "Search files by content using ripgrep" }, + { on = "", run = "escape --search", desc = "Cancel the ongoing search" }, + { on = "f", run = "filter --smart", desc = "Filter files" }, + { on = "/", run = "find --smart", desc = "Find next file" }, + { on = "?", run = "find --previous --smart", desc = "Find previous file" }, + { on = "n", run = "find_arrow", desc = "Go to the next found" }, + { on = "N", run = "find_arrow --previous", desc = "Go to the previous found" }, + + # Shell + { on = "", run = "shell --confirm --block lazygit", desc = "Lazygit" }, + { on = ";", run = "shell --interactive", desc = "Run a shell command" }, + { on = ":", run = "shell --block --interactive", desc = "Run a shell command (block until finishes)" }, + + # Hidden files + { on = ["z", "h"], run = "hidden toggle", desc = "Toggle the visibility of hidden files" }, + + # Open + { on = "r", run = "open --interactive", desc = "Open selected files interactively" }, + + # Create + { on = "T", run = "create", desc = "Create a file (ends with / for directories)" }, + + # Rename + { on = "k", run = "rename --cursor=start", desc = "Rename selected file(s)" }, + { on = "a", run = "rename --cursor=before_ext", desc = "Rename selected file(s)" }, + { on = "A", run = "rename --cursor=end", desc = "Rename selected file(s)" }, + + # Operation: D + { on = ["d", "d"], run = "yank --cut", desc = "Yank selected files (cut)" }, + # { on = ["d"], run = "remove", desc = "Trash selected files" }, + { on = ["d", "D"], run = "remove --permanently", desc = "Permanently delete selected files" }, + + # Operation: Y + { on = ["y", "y"], run = "yank", desc = "Yank selected files (copy)" }, + { on = ["y", "p"], run = "copy path", desc = "Copy the file path" }, + { on = ["y", "d"], run = "copy dirname", desc = "Copy the directory path" }, + { on = ["y", "f"], run = "copy filename", desc = "Copy the filename" }, + { on = ["y", "n"], run = "copy name_without_ext", desc = "Copy the filename without extension" }, + { on = ["y", "c"], run = "unyank", desc = "Cancel the yank status" }, + + # Operation: P + { on = ["p", "p"], run = "paste", desc = "Paste yanked files" }, + { on = ["p", "P"], run = "paste --force", desc = "Paste yanked files (overwrite if the destination exists)" }, + { on = ["p", "l"], run = "link", desc = "Symlink the absolute path of yanked files" }, + { on = ["p", "L"], run = "link --relative", desc = "Symlink the relative path of yanked files" }, + { on = ["p", "h"], run = "hardlink", desc = "Hardlink yanked files" }, + + # Linemode + { on = ["m", "s"], run = "linemode size", desc = "Set linemode to size" }, + { on = ["m", "p"], run = "linemode permissions", desc = "Set linemode to permissions" }, + { on = ["m", "c"], run = "linemode ctime", desc = "Set linemode to ctime" }, + { on = ["m", "m"], run = "linemode mtime", desc = "Set linemode to mtime" }, + { on = ["m", "o"], run = "linemode owner", desc = "Set linemode to owner" }, + { on = ["m", "n"], run = "linemode none", desc = "Set linemode to none" }, + + + # Sorting + { on = ["o", "M"], run = ["sort modified --reverse=no", "linemode mtime"], desc = "Sort by modified time" }, + { on = ["o", "m"], run = ["sort modified --reverse", "linemode mtime"], desc = "Sort by modified time (reverse)" }, + { on = ["o", "C"], run = ["sort created --reverse=no", "linemode ctime"], desc = "Sort by created time" }, + { on = ["o", "c"], run = ["sort created --reverse", "linemode ctime"], desc = "Sort by created time (reverse)" }, + { on = ["o", "E"], run = "sort extension --reverse=no", desc = "Sort by extension" }, + { on = ["o", "e"], run = "sort extension --reverse", desc = "Sort by extension (reverse)" }, + { on = ["o", "a"], run = "sort alphabetical --reverse=no", desc = "Sort alphabetically" }, + { on = ["o", "A"], run = "sort alphabetical --reverse", desc = "Sort alphabetically (reverse)" }, + { on = ["o", "n"], run = "sort natural --reverse=no", desc = "Sort naturally" }, + { on = ["o", "N"], run = "sort natural --reverse", desc = "Sort naturally (reverse)" }, + { on = ["o", "s"], run = ["sort size --reverse=no", "linemode size"], desc = "Sort by size" }, + { on = ["o", "S"], run = ["sort size --reverse", "linemode size"], desc = "Sort by size (reverse)" }, + + # Goto + { on = ["g", "r"], run = "cd /", desc = "Go to the root directory" }, + { on = ["g", "h"], run = "cd ~", desc = "Go to the home directory" }, + { on = ["g", "c"], run = "cd ~/.config", desc = "Go to the config directory" }, + { on = ["g", "d"], run = "cd ~/Downloads", desc = "Go to the downloads directory" }, + { on = ["g", "D"], run = "cd ~/Desktop", desc = "Go to the desktop directory" }, + { on = ["g", "i"], run = "cd ~/Github", desc = "Go to the Github directory" }, + { on = ["g", "f", "f"], run = "cd ~/.config" }, + { on = ["g", "f", "n"], run = "cd ~/.config/nvim" }, + { on = ["g", "f", "y"], run = "cd ~/.config/yazi" }, + { on = ["g", "f", "l"], run = "cd ~/.config/jesseduffield/lazygit" }, + { on = ["g", ""], run = "cd --interactive", desc = "Go to a directory interactively" }, + + # Tabs + { on = ["t", "u"], run = "tab_create --current", desc = "Create a new tab with CWD" }, + { on = ["t", "n"], run = "tab_switch -1 --relative", desc = "Switch to the previous tab" }, + { on = ["t", "i"], run = "tab_switch 1 --relative", desc = "Switch to the next tab" }, + #{ on = ["t", ""], run = "tab_swap -1", desc = "Swap current tab with previous tab" }, + #{ on = ["}"], run = "tab_swap 1", desc = "Swap current tab with next tab" }, + { on = "1", run = "tab_switch 0", desc = "Switch to the first tab" }, + { on = "2", run = "tab_switch 1", desc = "Switch to the second tab" }, + { on = "3", run = "tab_switch 2", desc = "Switch to the third tab" }, + { on = "4", run = "tab_switch 3", desc = "Switch to the fourth tab" }, + { on = "5", run = "tab_switch 4", desc = "Switch to the fifth tab" }, + { on = "6", run = "tab_switch 5", desc = "Switch to the sixth tab" }, + { on = "7", run = "tab_switch 6", desc = "Switch to the seventh tab" }, + { on = "8", run = "tab_switch 7", desc = "Switch to the eighth tab" }, + { on = "9", run = "tab_switch 8", desc = "Switch to the ninth tab" }, + + # Tasks + { on = "w", run = "tasks_show", desc = "Show task manager" }, + + # Help + { on = "~", run = "help", desc = "Open help" }, + { on = "", run = "help", desc = "Open help" }, +] + +[tasks] + +keymap = [ + { on = "", run = "close", desc = "Close task manager" }, + { on = "", run = "close", desc = "Close task manager" }, + { on = "", run = "close", desc = "Close task manager" }, + { on = "w", run = "close", desc = "Close task manager" }, + + { on = "u", run = "arrow -1", desc = "Move cursor up" }, + { on = "e", run = "arrow 1", desc = "Move cursor down" }, + + { on = "", run = "arrow -1", desc = "Move cursor up" }, + { on = "", run = "arrow 1", desc = "Move cursor down" }, + + { on = "", run = "inspect", desc = "Inspect the task" }, + { on = "x", run = "cancel", desc = "Cancel the task" }, + + # Help + { on = "~", run = "help", desc = "Open help" }, + { on = "", run = "help", desc = "Open help" }, +] + +[select] + +keymap = [ + { on = "", run = "close", desc = "Cancel selection" }, + { on = "", run = "close", desc = "Cancel selection" }, + { on = "", run = "close", desc = "Cancel selection" }, + { on = "", run = "close --submit", desc = "Submit the selection" }, + + { on = "u", run = "arrow -1", desc = "Move cursor up" }, + { on = "e", run = "arrow 1", desc = "Move cursor down" }, + + { on = "", run = "arrow -1", desc = "Move cursor up" }, + { on = "", run = "arrow 1", desc = "Move cursor down" }, + + # Help + { on = "~", run = "help", desc = "Open help" }, + { on = "", run = "help", desc = "Open help" }, +] + +[input] + +keymap = [ + { on = "", run = "close", desc = "Cancel input" }, + { on = "", run = "close --submit", desc = "Submit the input" }, + { on = "", run = "escape", desc = "Go back the normal mode, or cancel input" }, + { on = "", run = "escape", desc = "Go back the normal mode, or cancel input" }, + + # Mode + { on = "k", run = "insert", desc = "Enter insert mode" }, + { on = "a", run = "insert --append", desc = "Enter append mode" }, + { on = "K", run = ["move -999", "insert"], desc = "Move to the BOL, and enter insert mode" }, + { on = "A", run = ["move 999", "insert --append"], desc = "Move to the EOL, and enter append mode" }, + { on = "v", run = "visual", desc = "Enter visual mode" }, + { on = "V", run = ["move -999", "visual", "move 999"], desc = "Enter visual mode and select all" }, + + # Character-wise movement + { on = "n", run = "move -1", desc = "Move back a character" }, + { on = "i", run = "move 1", desc = "Move forward a character" }, + { on = "", run = "move -1", desc = "Move back a character" }, + { on = "", run = "move 1", desc = "Move forward a character" }, + { on = "", run = "move -1", desc = "Move back a character" }, + { on = "", run = "move 1", desc = "Move forward a character" }, + + # Word-wise movement + { on = "b", run = "backward", desc = "Move back to the start of the current or previous word" }, + { on = "w", run = "forward", desc = "Move forward to the start of the next word" }, + { on = "h", run = "forward --end-of-word", desc = "Move forward to the end of the current or next word" }, + { on = "", run = "backward", desc = "Move back to the start of the current or previous word" }, + { on = "", run = "forward --end-of-word", desc = "Move forward to the end of the current or next word" }, + + # Line-wise movement + { on = "N", run = "move -999", desc = "Move to the BOL" }, + { on = "I", run = "move 999", desc = "Move to the EOL" }, + { on = "", run = "move -999", desc = "Move to the BOL" }, + { on = "", run = "move 999", desc = "Move to the EOL" }, + { on = "", run = "move -999", desc = "Move to the BOL" }, + { on = "", run = "move 999", desc = "Move to the EOL" }, + + # Delete + { on = "", run = "backspace", desc = "Delete the character before the cursor" }, + { on = "", run = "backspace --under", desc = "Delete the character under the cursor" }, + { on = "", run = "backspace", desc = "Delete the character before the cursor" }, + { on = "", run = "backspace --under", desc = "Delete the character under the cursor" }, + + # Kill + { on = "", run = "kill bol", desc = "Kill backwards to the BOL" }, + { on = "", run = "kill eol", desc = "Kill forwards to the EOL" }, + { on = "", run = "kill backward", desc = "Kill backwards to the start of the current word" }, + { on = "", run = "kill forward", desc = "Kill forwards to the end of the current word" }, + + # Cut/Yank/Paste + { on = "d", run = "delete --cut", desc = "Cut the selected characters" }, + { on = "D", run = ["delete --cut", "move 999"], desc = "Cut until the EOL" }, + { on = "c", run = "delete --cut --insert", desc = "Cut the selected characters, and enter insert mode" }, + { on = "C", run = ["delete --cut --insert", "move 999"], desc = "Cut until the EOL, and enter insert mode" }, + { on = "x", run = ["delete --cut", "move 1 --in-operating"], desc = "Cut the current character" }, + { on = "y", run = "yank", desc = "Copy the selected characters" }, + { on = "p", run = "paste", desc = "Paste the copied characters after the cursor" }, + { on = "P", run = "paste --before", desc = "Paste the copied characters before the cursor" }, + + # Undo/Redo + { on = "l", run = "undo", desc = "Undo the last operation" }, + { on = "", run = "redo", desc = "Redo the last operation" }, + + # Help + { on = "~", run = "help", desc = "Open help" }, + { on = "", run = "help", desc = "Open help" }, +] + +[completion] + +keymap = [ + { on = "", run = "close", desc = "Cancel completion" }, + { on = "", run = "close --submit", desc = "Submit the completion" }, + { on = "", run = ["close --submit", "close_input --submit"], desc = "Submit the completion and input" }, + + { on = "", run = "arrow -1", desc = "Move cursor up" }, + { on = "", run = "arrow 1", desc = "Move cursor down" }, + + { on = "", run = "arrow -1", desc = "Move cursor up" }, + { on = "", run = "arrow 1", desc = "Move cursor down" }, + + # Help + { on = "~", run = "help", desc = "Open help" }, + { on = "", run = "help", desc = "Open help" }, +] + +[help] + +keymap = [ + { on = "", run = "escape", desc = "Clear the filter, or hide the help" }, + { on = "", run = "escape", desc = "Clear the filter, or hide the help" }, + { on = "q", run = "close", desc = "Exit the process" }, + { on = "", run = "close", desc = "Hide the help" }, + + # Navigation + { on = "u", run = "arrow -1", desc = "Move cursor up" }, + { on = "e", run = "arrow 1", desc = "Move cursor down" }, + + { on = "", run = "arrow -1", desc = "Move cursor up" }, + { on = "", run = "arrow 1", desc = "Move cursor down" }, + + # Filtering + { on = "f", run = "filter", desc = "Apply a filter for the help items" }, +] diff --git a/yazi/package.toml b/yazi/package.toml new file mode 100644 index 0000000..b43cea4 --- /dev/null +++ b/yazi/package.toml @@ -0,0 +1,5 @@ +[plugin] +deps = [{ use = "llanosrocas/yaziline", rev = "5886330" }, { use = "Rolv-Apneseth/starship", rev = "20d5a4d" }] + +[flavor] +deps = [] diff --git a/yazi/plugins/git.yazi b/yazi/plugins/git.yazi new file mode 160000 index 0000000..b51d050 --- /dev/null +++ b/yazi/plugins/git.yazi @@ -0,0 +1 @@ +Subproject commit b51d05071faf8145cd262da911857bf9bbb5a3ef diff --git a/yazi/plugins/smart-enter.yazi/init.lua b/yazi/plugins/smart-enter.yazi/init.lua new file mode 100644 index 0000000..efa1070 --- /dev/null +++ b/yazi/plugins/smart-enter.yazi/init.lua @@ -0,0 +1,6 @@ +return { + entry = function() + local h = cx.active.current.hovered + ya.manager_emit(h and h.cha.is_dir and "enter" or "open", { hovered = true }) + end, +} diff --git a/yazi/plugins/starship.yazi/DO_NOT_MODIFY_ANYTHING_IN_THIS_DIRECTORY b/yazi/plugins/starship.yazi/DO_NOT_MODIFY_ANYTHING_IN_THIS_DIRECTORY new file mode 100644 index 0000000..e69de29 diff --git a/yazi/plugins/starship.yazi/LICENSE b/yazi/plugins/starship.yazi/LICENSE new file mode 100644 index 0000000..c03ce66 --- /dev/null +++ b/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/yazi/plugins/starship.yazi/README.md b/yazi/plugins/starship.yazi/README.md new file mode 100644 index 0000000..39b632d --- /dev/null +++ b/yazi/plugins/starship.yazi/README.md @@ -0,0 +1,106 @@ +# starship.yazi + +Starship prompt plugin for [Yazi](https://github.com/sxyazi/yazi) + + + +## Requirements + +- [Yazi](https://github.com/sxyazi/yazi) - latest main branch +- [starship](https://github.com/starship/starship) + +### Package manager + +```bash +ya pack -a Rolv-Apneseth/starship +``` + +### Manual + +#### Linux / MacOS + +```sh +git clone https://github.com/Rolv-Apneseth/starship.yazi.git ~/.config/yazi/plugins/starship.yazi +``` + +#### Windows + +```sh +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() +``` + +If you wish to define a custom config file for `starship` to use, you can pass in a path +to the setup function like this: + +```lua +starship:setup({ config_file = "/home/rolv/.config/starship_secondary.toml" }) +``` + +Make sure you have [starship](https://github.com/starship/starship) installed and in your `PATH`. + +## 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.Rect.default, ui.Bar.TOP) + end + + return ui.Bar( + 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), + }), + ui.Bar.TOP + ):symbol(c) + end + + local c = self._chunks + self._chunks = { + c[1]:padding(ui.Padding.y(1)), + c[2]:padding(ui.Padding(c[1].w > 0 and 0 or 1, c[3].w > 0 and 0 or 1, 1, 1)), + c[3]:padding(ui.Padding.y(1)), + } + + local style = THEME.manager.border_style + self._base = ya.list_merge(self._base or {}, { + -- Enable for full border + --[[ ui.Border(self._area, ui.Border.ALL):type(ui.Border.ROUNDED):style(style), ]] + ui.Bar(self._chunks[1], ui.Bar.RIGHT):style(style), + ui.Bar(self._chunks[3], ui.Bar.LEFT):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[1].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/yazi/plugins/starship.yazi/init.lua b/yazi/plugins/starship.yazi/init.lua new file mode 100644 index 0000000..b8672c5 --- /dev/null +++ b/yazi/plugins/starship.yazi/init.lua @@ -0,0 +1,78 @@ +local save = ya.sync(function(st, cwd, output) + if cx.active.current.cwd == Url(cwd) then + st.output = output + ya.render() + end +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 + + --- Setup plugin + --- @param st table State + --- @param args SetupArgs|nil + setup = function(st, args) + -- Replace default header widget + Header:children_remove(1, Header.LEFT) + Header:children_add(function() + return ui.Line.parse(st.output or "") + end, 1000, Header.LEFT) + + -- Check for custom starship config file + if args ~= nil and 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 + + -- 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, + args = ya.quote(tostring(cwd), true), + }) + end + end + + -- Subscribe to events + ps.sub("cd", callback) + ps.sub("tab", callback) + end, + + entry = function(_, args) + local command = Command("starship"):arg("prompt"):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/yazi/plugins/yamb.yazi/.gitattributes b/yazi/plugins/yamb.yazi/.gitattributes new file mode 100644 index 0000000..94f480d --- /dev/null +++ b/yazi/plugins/yamb.yazi/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf \ No newline at end of file diff --git a/yazi/plugins/yamb.yazi/LICENSE b/yazi/plugins/yamb.yazi/LICENSE new file mode 100644 index 0000000..12f8c8b --- /dev/null +++ b/yazi/plugins/yamb.yazi/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Hunter Hwang + +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/yazi/plugins/yamb.yazi/README.md b/yazi/plugins/yamb.yazi/README.md new file mode 100644 index 0000000..40759d4 --- /dev/null +++ b/yazi/plugins/yamb.yazi/README.md @@ -0,0 +1,107 @@ +# Yet another bookmarks + +A [Yazi](https://github.com/sxyazi/yazi) plugin for bookmark management, supporting the following features + +- Persistent bookmarks. No bookmarks are lost after you close yazi. +- Quickly jump, delete, and rename a bookmark by keymap. +- Support fuzzy search through [fzf](https://github.com/junegunn/fzf). +- Configure your bookmarks using Lua language. + +## Installation + +> [!NOTE] +> Yazi >= 0.25. + +```sh +# Linux/macOS +git clone https://github.com/h-hg/yamb.yazi.git ~/.config/yazi/plugins/yamb.yazi + +# Windows +git clone https://github.com/h-hg/yamb.yazi.git $env:APPDATA\yazi\config\plugins\yamb.yazi +``` + +## Usage + +Add this to your `init.lua` + +```lua +-- You can configure your bookmarks by lua language +local bookmarks = {} + +local path_sep = package.config:sub(1, 1) +local home_path = ya.target_family() == "windows" and os.getenv("USERPROFILE") or os.getenv("HOME") +if ya.target_family() == "windows" then + table.insert(bookmarks, { + tag = "Scoop Local", + + path = (os.getenv("SCOOP") or home_path .. "\\scoop") .. "\\", + key = "p" + }) + table.insert(bookmarks, { + tag = "Scoop Global", + path = (os.getenv("SCOOP_GLOBAL") or "C:\\ProgramData\\scoop") .. "\\", + key = "P" + }) +end +table.insert(bookmarks, { + tag = "Desktop", + path = home_path .. path_sep .. "Desktop" .. path_sep, + key = "d" +}) + +require("yamb"):setup { + -- Optional, the path ending with path seperator represents folder. + bookmarks = bookmarks, + -- Optional, the cli of fzf. + cli = "fzf", + -- Optional, a string used for randomly generating keys, where the preceding characters have higher priority. + keys = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", + -- Optional, the path of bookmarks + path = (ya.target_family() == "windows" and os.getenv("APPDATA") .. "\\yazi\\config\\bookmark") or + (os.getenv("HOME") .. "/.config/yazi/bookmark"), +} +``` + +Add this to your `keymap.toml`: + +```toml +[[manager.prepend_keymap]] +on = [ "u", "a" ] +run = "plugin yamb --args=save" +desc = "Add bookmark" + +[[manager.prepend_keymap]] +on = [ "u", "g" ] +run = "plugin yamb --args=jump_by_key" +desc = "Jump bookmark by key" + +[[manager.prepend_keymap]] +on = [ "u", "G" ] +run = "plugin yamb --args=jump_by_fzf" +desc = "Jump bookmark by fzf" + +[[manager.prepend_keymap]] +on = [ "u", "d" ] +run = "plugin yamb --args=delete_by_key" +desc = "Delete bookmark by key" + +[[manager.prepend_keymap]] +on = [ "u", "D" ] +run = "plugin yamb --args=delete_by_fzf" +desc = "Delete bookmark by fzf" + +[[manager.prepend_keymap]] +on = [ "u", "A" ] +run = "plugin yamb --args=delete_all" +desc = "Delete all bookmarks" + +[[manager.prepend_keymap]] +on = [ "u", "r" ] +run = "plugin yamb --args=rename_by_key" +desc = "Rename bookmark by key" + +[[manager.prepend_keymap]] +on = [ "u", "R" ] +run = "plugin yamb --args=rename_by_fzf" +desc = "Rename bookmark by fzf" +``` diff --git a/yazi/plugins/yamb.yazi/init.lua b/yazi/plugins/yamb.yazi/init.lua new file mode 100644 index 0000000..c6505b7 --- /dev/null +++ b/yazi/plugins/yamb.yazi/init.lua @@ -0,0 +1,352 @@ +local path_sep = package.config:sub(1, 1) + +local get_hovered_path = ya.sync(function(state) + local h = cx.active.current.hovered + if h then + local path = tostring(h.url) + if h.cha.is_dir then + return path .. path_sep + end + return path + else + return '' + end +end) + +local get_state_attr = ya.sync(function(state, attr) + return state[attr] +end) + +local set_state_attr = ya.sync(function(state, attr, value) + state[attr] = value +end) + +local set_bookmarks = ya.sync(function(state, path, value) + state.bookmarks[path] = value +end) + +local sort_bookmarks = function(bookmarks, key1, key2, reverse) + reverse = reverse or false + table.sort(bookmarks, function(x, y) + if x[key1] == nil and y[key1] == nil then + return x[key2] < y[key2] + elseif x[key1] == nil then + return false + elseif y[key1] == nil then + return true + else + return x[key1] < y[key1] + end + end) + if reverse then + local n = #bookmarks + for i = 1, math.floor(n / 2) do + bookmarks[i], bookmarks[n - i + 1] = bookmarks[n - i + 1], bookmarks[i] + end + end + return bookmarks +end + +local save_to_file = function(mb_path, bookmarks) + local file = io.open(mb_path, "w") + if file == nil then + return + end + local array = {} + for _, item in pairs(bookmarks) do + table.insert(array, item) + end + sort_bookmarks(array, "tag", "key", true) + for _, item in ipairs(array) do + file:write(string.format("%s\t%s\t%s\n", item.tag, item.path, item.key)) + end + file:close() +end + +local fzf_find = function(cli, mb_path) + local permit = ya.hide() + local cmd = string.format("%s < \"%s\"", cli, mb_path) + local handle = io.popen(cmd, "r") + local result = "" + if handle then + -- strip + result = string.gsub(handle:read("*all") or "", "^%s*(.-)%s*$", "%1") + handle:close() + end + permit:drop() + local tag, path, key = string.match(result or "", "(.-)\t(.-)\t(.*)") + return path +end + +local which_find = function(bookmarks) + local cands = {} + for path, item in pairs(bookmarks) do + if #item.tag ~= 0 then + table.insert(cands, { desc = item.tag, on = item.key, path = item.path }) + end + end + sort_bookmarks(cands, "on", "desc", false) + if #cands == 0 then + ya.notify { + title = "Bookmarks", + content = "Empty bookmarks", + timeout = 2, + level = "info", + } + return nil + end + local idx = ya.which { cands = cands } + if idx == nil then + return nil + end + return cands[idx].path +end + +local action_jump = function(bookmarks, path) + if path == nil then + return + end + local tag = bookmarks[path].tag + if string.sub(path, -1) == path_sep then + ya.manager_emit("cd", { path }) + else + ya.manager_emit("reveal", { path }) + end + ya.notify { + title = "Bookmarks", + content = 'Jump to "' .. tag .. '"', + timeout = 2, + level = "info", + } +end + +local generate_key = function(bookmarks) + local keys = get_state_attr("keys") + local key2rank = get_state_attr("key2rank") + local mb = {} + for _, item in pairs(bookmarks) do + if #item.key == 1 then + table.insert(mb, item.key) + end + end + if #mb == 0 then + return keys[1] + end + table.sort(mb, function(a, b) + return key2rank[a] < key2rank[b] + end) + local idx = 1 + for _, key in ipairs(keys) do + if key2rank[key] < key2rank[mb[idx]] then + return key + end + idx = idx + 1 + end + return nil +end + +local action_save = function(mb_path, bookmarks, path) + if path == nil or #path == 0 then + return + end + + local path_obj = bookmarks[path] + -- check tag + local tag = path_obj and path_obj.tag or path:match(".*[\\/]([^\\/]+)[\\/]?$") + while true do + local value, event = ya.input({ + title = "Tag (alias name)", + value = tag, + position = { "top-center", y = 3, w = 40 }, + }) + if event ~= 1 then + return + end + tag = value or '' + if #tag == 0 then + ya.notify { + title = "Bookmarks", + content = "Empty tag", + timeout = 2, + level = "info", + } + else + -- check the tag + local tag_obj = nil + for _, item in pairs(bookmarks) do + if item.tag == tag then + tag_obj = item + break + end + end + if tag_obj == nil or tag_obj.path == path then + break + end + ya.notify { + title = "Bookmarks", + content = "Duplicated tag", + timeout = 2, + level = "info", + } + end + end + -- check key + local key = path_obj and path_obj.key or generate_key(bookmarks) + while true do + local value, event = ya.input({ + title = "Key (1 character, optional)", + value = key, + position = { "top-center", y = 3, w = 40 }, + }) + if event ~= 1 then + return + end + key = value or "" + if key == "" then + key = "" + break + elseif #key == 1 then + -- check the key + local key_obj = nil + for _, item in pairs(bookmarks) do + if item.key == key then + key_obj = item + break + end + end + if key_obj == nil or key_obj.path == path then + break + else + ya.notify { + title = "Bookmarks", + content = "Duplicated key", + timeout = 2, + level = "info", + } + end + else + ya.notify { + title = "Bookmarks", + content = "The length of key shoule be 1", + timeout = 2, + level = "info", + } + end + end + -- save + set_bookmarks(path, { tag = tag, path = path, key = key }) + bookmarks = get_state_attr("bookmarks") + save_to_file(mb_path, bookmarks) + ya.notify { + title = "Bookmarks", + content = '"' .. tag .. '" saved"', + timeout = 2, + level = "info", + } +end + +local action_delete = function(mb_path, bookmarks, path) + if path == nil then + return + end + local tag = bookmarks[path].tag + set_bookmarks(path, nil) + bookmarks = get_state_attr("bookmarks") + save_to_file(mb_path, bookmarks) + ya.notify { + title = "Bookmarks", + content = '"' .. tag .. '" deleted', + timeout = 2, + level = "info", + } +end + +local action_delete_all = function(mb_path) + local value, event = ya.input({ + title = "Delete all bookmarks? (y/n)", + position = { "top-center", y = 3, w = 40 }, + }) + if event ~= 1 then + return + end + if string.lower(value) == "y" then + set_state_attr("bookmarks", {}) + save_to_file(mb_path, {}) + ya.notify { + title = "Bookmarks", + content = "All bookmarks deleted", + timeout = 2, + level = "info", + } + else + ya.notify { + title = "Bookmarks", + content = "Cancel delete", + timeout = 2, + level = "info", + } + end +end + +return { + setup = function(state, options) + state.path = options.path or + (ya.target_family() == "windows" and os.getenv("APPDATA") .. "\\yazi\\config\\bookmark") or + (os.getenv("HOME") .. "/.config/yazi/bookmark") + state.cli = options.cli or "fzf" + -- init the keys + local keys = options.keys or "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + state.keys = {} + state.key2rank = {} + for i = 1, #keys do + local char = keys:sub(i, i) + table.insert(state.keys, char) + state.key2rank[char] = i + end + + -- init the bookmarks + local bookmarks = {} + for _, item in pairs(options.bookmarks or {}) do + bookmarks[item.path] = { tag = item.tag, path = item.path, key = item.key } + end + -- load the config + local file = io.open(state.path, "r") + if file ~= nil then + for line in file:lines() do + local tag, path, key = string.match(line, "(.-)\t(.-)\t(.*)") + if tag and path then + key = key or "" + bookmarks[path] = { tag = tag, path = path, key = key } + end + end + file:close() + end + -- create bookmarks file to enable fzf + save_to_file(state.path, bookmarks) + state.bookmarks = bookmarks + end, + entry = function(self, args) + local action = args[1] + if not action then + return + end + local mb_path, cli, bookmarks = get_state_attr("path"), get_state_attr("cli"), get_state_attr("bookmarks") + if action == "save" then + action_save(mb_path, bookmarks, get_hovered_path()) + elseif action == "delete_by_key" then + action_delete(mb_path, bookmarks, which_find(bookmarks)) + elseif action == "delete_by_fzf" then + action_delete(mb_path, bookmarks, fzf_find(cli, mb_path)) + elseif action == "delete_all" then + action_delete_all(mb_path) + elseif action == "jump_by_key" then + action_jump(bookmarks, which_find(bookmarks)) + elseif action == "jump_by_fzf" then + action_jump(bookmarks, fzf_find(cli, mb_path)) + elseif action == "rename_by_key" then + action_save(mb_path, bookmarks, which_find(bookmarks)) + elseif action == "rename_by_fzf" then + action_save(mb_path, bookmarks, fzf_find(cli, mb_path)) + end + end, +} diff --git a/yazi/plugins/yaziline.yazi/DO_NOT_MODIFY_ANYTHING_IN_THIS_DIRECTORY b/yazi/plugins/yaziline.yazi/DO_NOT_MODIFY_ANYTHING_IN_THIS_DIRECTORY new file mode 100644 index 0000000..e69de29 diff --git a/yazi/plugins/yaziline.yazi/LICENSE b/yazi/plugins/yaziline.yazi/LICENSE new file mode 100644 index 0000000..82a69f6 --- /dev/null +++ b/yazi/plugins/yaziline.yazi/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 llanosrocas + +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/yazi/plugins/yaziline.yazi/README.md b/yazi/plugins/yaziline.yazi/README.md new file mode 100644 index 0000000..4ae5eb8 --- /dev/null +++ b/yazi/plugins/yaziline.yazi/README.md @@ -0,0 +1,131 @@ +# yaziline.yazi + +Simple lualine-like status line for yazi. + +Read more about features and configuration [here](#features). + +![preview](https://github.com/llanosrocas/yaziline.yazi/blob/master/.github/images/preview.png) + +## Requirements + +- yazi version >= 0.3.0 +- Font with symbol support. For example [Nerd Fonts](https://www.nerdfonts.com/). + +## Installation + +```sh +ya pack -a llanosrocas/yaziline +``` + +Or manually copy `init.lua` to the `~/.config/yazi/plugins/yaziline.yazi/init.lua` + +## Usage + +Add this to your `~/.config/yazi/init.lua`: + +```lua +require("yaziline"):setup() +``` + +Optionally, configure line: + +```lua +require("yaziline"):setup({ + separator_style = "angly" -- "angly" | "curvy" | "liney" | "empty" + separator_open = "", + separator_close = "", + separator_open_thin = "", + separator_close_thin = "", + select_symbol = "", + yank_symbol = "󰆐", + filename_max_length = 24, -- trim when filename > 24 + filename_trim_length = 6 -- trim 6 chars from both ends +}) +``` + +## Features + +### Preconfigured separators + +Choose your style: + +- `angly` + ![angly](https://github.com/llanosrocas/yaziline.yazi/blob/master/.github/images/angly.png) +- `curvy` + ![curvy](https://github.com/llanosrocas/yaziline.yazi/blob/master/.github/images/curvy.png) +- `liney` + ![liney](https://github.com/llanosrocas/yaziline.yazi/blob/master/.github/images/liney.png) +- `empty` + ![empty](https://github.com/llanosrocas/yaziline.yazi/blob/master/.github/images/empty.png) + +### Separator customization + +You can provide your own symbols for separators combined with preconfigured separators. For example: + +```lua +require("yaziline"):setup({ + -- Optinal config + separator_style = "angly", -- preconfigured style + separator_open = "", -- instead of  + separator_close = "", -- instead of  + separator_open_thin = "", -- change to anything + separator_close_thin = "", -- change to anything +}) +``` + +![empty](https://github.com/llanosrocas/yaziline.yazi/blob/master/.github/images/separator-combination.png) + +_You can find more symbols [here](https://www.nerdfonts.com/cheat-sheet)_ + +### File actions icons + +You can provide your own symbols for `select` and `yank`. For example: + +```lua +require("yaziline"):setup({ + -- Optinal config + select_symbol = "", -- "S" by default + yank_symbol = "󰆐", -- "Y" by default +}) +``` + +![empty](https://github.com/llanosrocas/yaziline.yazi/blob/master/.github/images/file-actions.png) + +_You can find more symbols [here](https://www.nerdfonts.com/cheat-sheet)_ + +### Colors and font weight + +You can change background and font weight in your `yazi/flavors/flavor.toml`. + +```toml +mode_normal = { bg = "#98c379", bold = false } +``` + +For example, here is how my line looks like: + +![preview-2](https://github.com/llanosrocas/yaziline.yazi/blob/master/.github/images/preview-2.png) + +### Selected and Yanked Counter + +Displays the number of selected ('S') and yanked ('Y') files on the left. If files are cut, the yank counter changes color, since its `yank --cut` under the hood. + +### Trimmed Filename + +Displays the trimmed filename on the left, which is useful for smaller screens or long filenames. By default, it's 24 characters with trimming to 12. Adjust in the `setup`. + +```lua +require("yaziline"):setup({ + filename_max_length = 24, -- trim when filename > 24 + filename_trim_length = 6 -- trim 6 chars from both ends +}) +``` + +### ISO Date for 'Modified' + +On the right, you'll find the date and time the file was modified, formatted in an [ISO](https://en.wikipedia.org/wiki/ISO_8601)-like string for universal date representation. Adjust in the `Status:date` function. + +## Credits + +- [yazi source code](https://github.com/sxyazi/yazi) +- [yatline.yazi](https://github.com/imsi32/yatline.yazi/tree/main) +- [lualine.nvim](https://github.com/nvim-lualine/lualine.nvim) diff --git a/yazi/plugins/yaziline.yazi/init.lua b/yazi/plugins/yaziline.yazi/init.lua new file mode 100644 index 0000000..32c64f4 --- /dev/null +++ b/yazi/plugins/yaziline.yazi/init.lua @@ -0,0 +1,133 @@ +local function setup(_, options) + options = options or {} + + local default_separators = { + angly = { "", "", "", "" }, + curvy = { "", "", "", "" }, + liney = { "", "", "|", "|" }, + empty = { "", "", "", "" } + } + local separators = default_separators[options.separator_style or "angly"] + + local config = { + separator_styles = { + separator_open = options.separator_open or separators[1], + separator_close = options.separator_close or separators[2], + separator_open_thin = options.separator_open_thin or separators[3], + separator_close_thin = options.separator_close_thin or separators[4] + }, + select_symbol = options.select_symbol or "S", + yank_symbol = options.yank_symbol or "Y", + filename_max_length = options.filename_max_length or 24, + filename_trim_length = options.filename_trim_length or 6 + } + + local current_separator_style = config.separator_styles + + function Header:count() + return ui.Line {} + end + + function Status:mode() + local mode = tostring(self._tab.mode):upper() + if mode == "UNSET" then + mode = "UN-SET" + end + + local style = self:style() + return ui.Span(" " .. mode .. " "):style(style) + end + + function Status:size() + local h = self._tab.current.hovered + if not h then + return ui.Line {} + end + + local style = self:style() + return ui.Span(current_separator_style.separator_close .. " " .. ya.readable_size(h:size() or h.cha.length) .. " ") + :fg(style.bg):bg(THEME.status.separator_style.bg) + end + + function Status:name() + local h = self._tab.current.hovered + if not h then + return ui.Line {} + end + + local trimmed_name = #h.name > config.filename_max_length and + (string.sub(h.name, 1, config.filename_trim_length) .. "..." .. string.sub(h.name, -config.filename_trim_length)) or + h.name + + local style = self:style() + return ui.Line { + ui.Span(current_separator_style.separator_close .. " "):fg(THEME.status.separator_style.fg), + ui.Span(trimmed_name):fg(style.bg), + } + end + + function Status:files() + local files_yanked = #cx.yanked + local files_selected = #cx.active.selected + local files_is_cut = cx.yanked.is_cut + + local selected_fg = files_selected > 0 and THEME.manager.count_selected.bg or THEME.status.separator_style.fg + local yanked_fg = files_yanked > 0 and + (files_is_cut and THEME.manager.count_cut.bg or THEME.manager.count_copied.bg) or + THEME.status.separator_style.fg + + local yanked_text = files_yanked > 0 and config.yank_symbol .. " " .. files_yanked or config.yank_symbol .. " 0" + + return ui.Line { + ui.Span(" " .. current_separator_style.separator_close_thin .. " "):fg(THEME.status.separator_style.fg), + ui.Span(config.select_symbol .. " " .. files_selected .. " "):fg(selected_fg), + ui.Span(yanked_text .. " "):fg(yanked_fg), + } + end + + function Status:modified() + local hovered = cx.active.current.hovered + local cha = hovered.cha + local time = (cha.modified or 0) // 1 + + return ui.Span(os.date("%Y-%m-%d %H:%M", time) .. " " .. current_separator_style.separator_open_thin .. " "):fg( + THEME.status.separator_style.fg) + end + + function Status:percentage() + local percent = 0 + local cursor = self._tab.current.cursor + local length = #self._tab.current.files + if cursor ~= 0 and length ~= 0 then + percent = math.floor((cursor + 1) * 100 / length) + end + + if percent == 0 then + percent = " Top " + elseif percent == 100 then + percent = " Bot " + else + percent = string.format(" %3d%% ", percent) + end + + local style = self:style() + return ui.Line { + ui.Span(" " .. current_separator_style.separator_open):fg(THEME.status.separator_style.fg), + ui.Span(percent):fg(style.bg):bg(THEME.status.separator_style.bg), + ui.Span(current_separator_style.separator_open):fg(style.bg):bg(THEME.status.separator_style.bg) + } + end + + function Status:position() + local cursor = self._tab.current.cursor + local length = #self._tab.current.files + + local style = self:style() + return ui.Span(string.format(" %2d/%-2d ", cursor + 1, length)):style(style) + end + + Status:children_add(Status.files, 4000, Status.LEFT) + Status:children_add(Status.modified, 0, Status.RIGHT) +end + +return { setup = setup } diff --git a/yazi/theme.toml b/yazi/theme.toml new file mode 100644 index 0000000..0cf7ec0 --- /dev/null +++ b/yazi/theme.toml @@ -0,0 +1,26 @@ +# A TOML linter such as https://taplo.tamasfe.dev/ can use this schema to validate your config. +# If you encounter any issues, please make an issue at https://github.com/yazi-rs/schemas. +"$schema" = "https://yazi-rs.github.io/schemas/theme.json" + +# vim:fileencoding=utf-8:foldmethod=marker + +[flavor] +use = "" + + +[manager] + +# Tab +tab_width = 12 + +# Border +border_symbol = " " +border_style = { fg = "gray" } + +# Highlighting +syntect_theme = "" + +[status] +mode_normal = { bg = "blue", bold = true } +mode_select = { bg = "red", bold = true } +mode_unset = { bg = "yellow", bold = true } diff --git a/yazi/yazi.toml b/yazi/yazi.toml new file mode 100644 index 0000000..c13b93c --- /dev/null +++ b/yazi/yazi.toml @@ -0,0 +1,202 @@ +# A TOML linter such as https://taplo.tamasfe.dev/ can use this schema to validate your config. +# If you encounter any issues, please make an issue at https://github.com/yazi-rs/schemas. +"$schema" = "https://yazi-rs.github.io/schemas/yazi.json" + +[manager] +ratio = [1, 3, 4] +sort_by = "alphabetical" +sort_sensitive = false +sort_reverse = false +sort_dir_first = true +sort_translit = false +linemode = "size" +show_hidden = false +show_symlink = true +scrolloff = 5 +mouse_events = ["click", "scroll"] +title_format = "Yazi: {cwd}" + +[preview] +tab_size = 2 +max_width = 600 +max_height = 900 +cache_dir = "" +image_filter = "triangle" +image_quality = 75 +sixel_fraction = 15 +ueberzug_scale = 1 +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" }, +] +open = [ + { run = 'xdg-open "$1"', desc = "Open", for = "linux" }, + { run = 'open "$@"', desc = "Open", for = "macos" }, + { run = 'start "" "%1"', orphan = true, desc = "Open", for = "windows" }, +] +reveal = [ + { run = 'xdg-open "$(dirname "$1")"', desc = "Reveal", for = "linux" }, + { run = 'open -R "$1"', desc = "Reveal", for = "macos" }, + { run = 'explorer /select,"%1"', orphan = true, desc = "Reveal", for = "windows" }, + { run = '''exiftool "$1"; echo "Press enter to exit"; read _''', block = true, desc = "Show EXIF", for = "unix" }, +] +extract = [ + { run = 'ya pub extract --list "$@"', desc = "Extract here", for = "unix" }, + { run = 'ya pub extract --list %*', desc = "Extract here", for = "windows" }, +] +play = [ + { run = 'mpv --force-window "$@"', orphan = true, for = "unix" }, + { run = 'mpv --force-window %*', orphan = true, for = "windows" }, + { run = '''mediainfo "$1"; echo "Press enter to exit"; read _''', block = true, desc = "Show media info", for = "unix" }, +] + +[open] +rules = [ + # Folder + { name = "*/", use = ["edit", "open", "reveal"] }, + # Text + { mime = "text/*", use = ["edit", "reveal"] }, + # Image + { mime = "image/*", use = ["open", "reveal"] }, + # Media + { mime = "{audio,video}/*", use = ["play", "reveal"] }, + # Archive + { mime = "application/{,g}zip", use = ["extract", "reveal"] }, + { mime = "application/x-{tar,bzip*,7z-compressed,xz,rar}", use = ["extract", "reveal"] }, + # JSON + { mime = "application/{json,x-ndjson}", use = ["edit", "reveal"] }, + { mime = "*/javascript", use = ["edit", "reveal"] }, + # Empty file + { mime = "inode/x-empty", use = ["edit", "reveal"] }, + # Fallback + { name = "*", use = ["open", "reveal"] }, +] + +[tasks] +micro_workers = 10 +macro_workers = 25 +bizarre_retry = 5 +image_alloc = 536870912 # 512MB +image_bound = [0, 0] +suppress_preload = false + +[plugin] +fetchers = [ + # Mimetype + { id = "mime", name = "*", run = "mime", if = "!mime", prio = "high" }, + { id = "git", name = "*", run = "git", prio = "normal" }, + { id = "git", name = "*/", run = "git", prio = "normal" }, +] +preloaders = [ + # Image + { mime = "image/{avif,hei?,jxl,svg+xml}", run = "magick" }, + { mime = "image/*", run = "image" }, + # Video + { mime = "video/*", run = "video" }, + # PDF + { mime = "application/pdf", run = "pdf" }, + # Font + { mime = "font/*", run = "font" }, + { mime = "application/vnd.ms-opentype", run = "font" }, +] +previewers = [ + { name = "*/", run = "folder", sync = true }, + # Code + { mime = "text/*", run = "code" }, + { mime = "*/{xml,javascript,x-wine-extension-ini}", run = "code" }, + # JSON + { mime = "application/{json,x-ndjson}", run = "json" }, + # Image + { mime = "image/{avif,hei?,jxl,svg+xml}", run = "magick" }, + { mime = "image/*", run = "image" }, + # Video + { mime = "video/*", run = "video" }, + # PDF + { mime = "application/pdf", run = "pdf" }, + # Archive + { mime = "application/{,g}zip", run = "archive" }, + { mime = "application/x-{tar,bzip*,7z-compressed,xz,rar,iso9660-image}", run = "archive" }, + # Font + { mime = "font/*", run = "font" }, + { mime = "application/vnd.ms-opentype", run = "font" }, + # Empty file + { mime = "inode/x-empty", run = "empty" }, + # Fallback + { name = "*", run = "file" }, +] + +[input] +cursor_blink = false + +# cd +cd_title = "Change directory:" +cd_origin = "top-center" +cd_offset = [0, 2, 50, 3] + +# create +create_title = "Create:" +create_origin = "top-center" +create_offset = [0, 2, 50, 3] + +# rename +rename_title = "Rename:" +rename_origin = "hovered" +rename_offset = [0, 1, 50, 3] + +# trash +trash_title = "Move {n} selected file{s} to trash? (y/N)" +trash_origin = "top-center" +trash_offset = [0, 2, 50, 3] + +# delete +delete_title = "Delete {n} selected file{s} permanently? (y/N)" +delete_origin = "top-center" +delete_offset = [0, 2, 50, 3] + +# filter +filter_title = "Filter:" +filter_origin = "top-center" +filter_offset = [0, 2, 50, 3] + +# find +find_title = ["Find next:", "Find previous:"] +find_origin = "top-center" +find_offset = [0, 2, 50, 3] + +# search +search_title = "Search via {n}:" +search_origin = "top-center" +search_offset = [0, 2, 50, 3] + +# shell +shell_title = ["Shell:", "Shell (block):"] +shell_origin = "top-center" +shell_offset = [0, 2, 50, 3] + +# overwrite +overwrite_title = "Overwrite an existing file? (y/N)" +overwrite_origin = "top-center" +overwrite_offset = [0, 2, 50, 3] + +# quit +quit_title = "{n} task{s} running, sure to quit? (y/N)" +quit_origin = "top-center" +quit_offset = [0, 2, 50, 3] + +[select] +open_title = "Open with:" +open_origin = "hovered" +open_offset = [0, 1, 50, 7] + +[which] +sort_by = "none" +sort_sensitive = false +sort_reverse = false +sort_translit = false + +[log] +enabled = false diff --git a/zsh/aliases.zsh b/zsh/aliases.zsh index b908e60..473be07 100644 --- a/zsh/aliases.zsh +++ b/zsh/aliases.zsh @@ -12,7 +12,7 @@ alias ms='mailsync' alias mt='neomutt' alias r='echo $RANGER_LEVEL' alias pu='python3 -m pudb' -alias ra='joshuto' +alias ra='yazi' # ra() { #if [ -z "$RANGER_LEVEL" ] #then @@ -23,7 +23,7 @@ alias ra='joshuto' #} alias s='neofetch' alias g='onefetch' -alias sra='sudo -E ranger' +alias sra='sudo -E yazi' # alias sudo='sudo -E' alias vim='nvim' alias gs='git config credential.helper store'