Compare commits
11 commits
3d8e8e1534
...
97bdfbc9d1
Author | SHA1 | Date | |
---|---|---|---|
97bdfbc9d1 | |||
cd81d7b2b4 | |||
ae61234858 | |||
818baa19e0 | |||
89d76f4520 | |||
937b4c1636 | |||
0d4ed43f53 | |||
f33ff5a32f | |||
b7f4de7763 | |||
27c4be39c9 | |||
e0b7568930 |
31 changed files with 1711 additions and 0 deletions
2
.config/nvim/init.lua
Normal file
2
.config/nvim/init.lua
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
-- lazy vim package manager
|
||||||
|
require("config.lazy")
|
92
.config/nvim/lua/config/lazy.lua
Normal file
92
.config/nvim/lua/config/lazy.lua
Normal file
|
@ -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 = {}
|
||||||
|
}
|
32
.config/nvim/lua/plugins/coq.lua
Normal file
32
.config/nvim/lua/plugins/coq.lua
Normal file
|
@ -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,
|
||||||
|
}
|
||||||
|
}
|
7
.config/nvim/lua/plugins/dracula.lua
Normal file
7
.config/nvim/lua/plugins/dracula.lua
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
-- lualine
|
||||||
|
return {
|
||||||
|
{
|
||||||
|
"Mofiqul/dracula.nvim",
|
||||||
|
lazy = false
|
||||||
|
}
|
||||||
|
}
|
8
.config/nvim/lua/plugins/lualine.lua
Normal file
8
.config/nvim/lua/plugins/lualine.lua
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
-- lualine
|
||||||
|
return {
|
||||||
|
{
|
||||||
|
"nvim-lualine/lualine.nvim",
|
||||||
|
dependencies = { 'nvim-tree/nvim-web-devicons' },
|
||||||
|
lazy = false
|
||||||
|
}
|
||||||
|
}
|
170
.config/yazi/flavors/dracula.yazi/flavor.toml
Normal file
170
.config/yazi/flavors/dracula.yazi/flavor.toml
Normal file
|
@ -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" }
|
||||||
|
]
|
||||||
|
|
||||||
|
# : }}}
|
59
.config/yazi/init.lua
Normal file
59
.config/yazi/init.lua
Normal file
|
@ -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()
|
108
.config/yazi/keymap.toml
Normal file
108
.config/yazi/keymap.toml
Normal file
|
@ -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"
|
21
.config/yazi/plugins/chmod.yazi/LICENSE
Normal file
21
.config/yazi/plugins/chmod.yazi/LICENSE
Normal file
|
@ -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.
|
28
.config/yazi/plugins/chmod.yazi/README.md
Normal file
28
.config/yazi/plugins/chmod.yazi/README.md
Normal file
|
@ -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 <kbd>c</kbd> => <kbd>m</kbd> key is not used elsewhere.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This plugin is MIT-licensed. For more information check the [LICENSE](LICENSE) file.
|
41
.config/yazi/plugins/chmod.yazi/main.lua
Normal file
41
.config/yazi/plugins/chmod.yazi/main.lua
Normal file
|
@ -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,
|
||||||
|
}
|
18
.config/yazi/plugins/confirm-quit.yazi/main.lua
Normal file
18
.config/yazi/plugins/confirm-quit.yazi/main.lua
Normal file
|
@ -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 }
|
21
.config/yazi/plugins/full-border.yazi/LICENSE
Normal file
21
.config/yazi/plugins/full-border.yazi/LICENSE
Normal file
|
@ -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.
|
32
.config/yazi/plugins/full-border.yazi/README.md
Normal file
32
.config/yazi/plugins/full-border.yazi/README.md
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# full-border.yazi
|
||||||
|
|
||||||
|
Add a full border to Yazi to make it look fancier.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 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.
|
43
.config/yazi/plugins/full-border.yazi/main.lua
Normal file
43
.config/yazi/plugins/full-border.yazi/main.lua
Normal file
|
@ -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 }
|
21
.config/yazi/plugins/git.yazi/LICENSE
Normal file
21
.config/yazi/plugins/git.yazi/LICENSE
Normal file
|
@ -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.
|
78
.config/yazi/plugins/git.yazi/README.md
Normal file
78
.config/yazi/plugins/git.yazi/README.md
Normal file
|
@ -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.
|
228
.config/yazi/plugins/git.yazi/main.lua
Normal file
228
.config/yazi/plugins/git.yazi/main.lua
Normal file
|
@ -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 }
|
21
.config/yazi/plugins/ouch.yazi/LICENSE
Normal file
21
.config/yazi/plugins/ouch.yazi/LICENSE
Normal file
|
@ -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.
|
79
.config/yazi/plugins/ouch.yazi/README.md
Normal file
79
.config/yazi/plugins/ouch.yazi/README.md
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
# ouch.yazi
|
||||||
|
|
||||||
|
[ouch](https://github.com/ouch-org/ouch) plugin for [Yazi](https://github.com/sxyazi/yazi).
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 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" },
|
||||||
|
]
|
||||||
|
```
|
148
.config/yazi/plugins/ouch.yazi/main.lua
Normal file
148
.config/yazi/plugins/ouch.yazi/main.lua
Normal file
|
@ -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
|
13
.config/yazi/plugins/smart-switch.yazi/main.lua
Normal file
13
.config/yazi/plugins/smart-switch.yazi/main.lua
Normal file
|
@ -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 }
|
7
.config/yazi/plugins/smart-tab.yazi/main.lua
Normal file
7
.config/yazi/plugins/smart-tab.yazi/main.lua
Normal file
|
@ -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,
|
||||||
|
}
|
21
.config/yazi/plugins/starship.yazi/LICENSE
Normal file
21
.config/yazi/plugins/starship.yazi/LICENSE
Normal file
|
@ -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.
|
108
.config/yazi/plugins/starship.yazi/README.md
Normal file
108
.config/yazi/plugins/starship.yazi/README.md
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
# starship.yazi
|
||||||
|
|
||||||
|
Starship prompt plugin for [Yazi](https://github.com/sxyazi/yazi)
|
||||||
|
|
||||||
|
<https://github.com/Rolv-Apneseth/starship.yazi/assets/69486699/f7314687-5cb1-4d66-8d9d-cca960ba6716>
|
||||||
|
|
||||||
|
## 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`:
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Click to expand</summary>
|
||||||
|
|
||||||
|
```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
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
> [!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)
|
123
.config/yazi/plugins/starship.yazi/main.lua
Normal file
123
.config/yazi/plugins/starship.yazi/main.lua
Normal file
|
@ -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,
|
||||||
|
}
|
21
.config/yazi/plugins/toggle-pane.yazi/LICENSE
Normal file
21
.config/yazi/plugins/toggle-pane.yazi/LICENSE
Normal file
|
@ -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.
|
78
.config/yazi/plugins/toggle-pane.yazi/README.md
Normal file
78
.config/yazi/plugins/toggle-pane.yazi/README.md
Normal file
|
@ -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.
|
51
.config/yazi/plugins/toggle-pane.yazi/main.lua
Normal file
51
.config/yazi/plugins/toggle-pane.yazi/main.lua
Normal file
|
@ -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 }
|
2
.config/yazi/theme.toml
Normal file
2
.config/yazi/theme.toml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
[flavor]
|
||||||
|
dark = "dracula"
|
30
.config/yazi/yazi.toml
Normal file
30
.config/yazi/yazi.toml
Normal file
|
@ -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" },
|
||||||
|
]
|
Loading…
Add table
Add a link
Reference in a new issue