mirror of
https://github.com/kristoferssolo/solorice.git
synced 2025-10-21 20:10:34 +00:00
fix(yazi): update plugins
This commit is contained in:
parent
94fabd2f50
commit
473d4a771a
@ -51,9 +51,12 @@ depends = [ "shell" ]
|
||||
[local.files]
|
||||
"local/bin/" = "~/.local/bin/"
|
||||
"local/share/" = "~/.local/share/"
|
||||
"local/share/applications/text.desktop" = {target = "~/.local/share/applications/text.desktop", type = "template"}
|
||||
"local/share/applications/file.desktop" = {target = "~/.local/share/applications/file.desktop", type = "template"}
|
||||
|
||||
[rofi.files]
|
||||
"config/rofi/" = "~/.config/rofi/"
|
||||
"config/rofi/config.rasi" = {target = "~/.config/rofi/config.rasi", type = "template"}
|
||||
|
||||
[misc]
|
||||
depends = [ "torrent", "zathura" ]
|
||||
@ -85,12 +88,12 @@ depends = [ "torrent", "zathura" ]
|
||||
[awesome.files]
|
||||
"config/awesome/json.lua" = "~/.config/awesome/json.lua"
|
||||
"config/awesome/mytheme.lua" = "~/.config/awesome/mytheme.lua"
|
||||
"config/awesome/rc.lua" = "~/.config/awesome/rc.lua"
|
||||
"config/awesome/rc.lua" = {target = "~/.config/awesome/rc.lua", type = "template"}
|
||||
|
||||
[awesome_laptop.files]
|
||||
"config/awesome/json.lua" = "~/.config/awesome/json.lua"
|
||||
"config/awesome/mytheme.lua" = "~/.config/awesome/mytheme.lua"
|
||||
"config/awesome/rc-laptop.lua" = "~/.config/awesome/rc.lua"
|
||||
"config/awesome/rc-laptop.lua" = {target = "~/.config/awesome/rc.lua", type = "template"}
|
||||
|
||||
[dunst.files]
|
||||
"config/dunst/" = "~/.config/dunst/"
|
||||
@ -100,6 +103,7 @@ depends = [ "misc", "local", "eww", "lock" ]
|
||||
|
||||
[hyprland.files]
|
||||
"config/hypr/" = "~/.config/hypr/"
|
||||
"config/hypr/hyprland.conf" = {target = "~/.config/hypr/hyprland.conf", type = "template"}
|
||||
|
||||
[wofi.files]
|
||||
"config/wofi/" = "~/.config/wofi/"
|
||||
|
||||
@ -31,7 +31,7 @@ local hotkeys_popup = require("awful.hotkeys_popup")
|
||||
-- when client with a matching name is opened:
|
||||
require("awful.hotkeys_popup.keys")
|
||||
|
||||
-- {{{ Error handling
|
||||
--- Error handling
|
||||
-- Check if awesome encountered an error during startup and fell back to
|
||||
-- another config (This code will only ever execute for the fallback config)
|
||||
if awesome.startup_errors then
|
||||
@ -60,15 +60,14 @@ do
|
||||
in_error = false
|
||||
end)
|
||||
end
|
||||
-- }}}
|
||||
|
||||
-- {{{ Variable definitions
|
||||
--- Variable definitions
|
||||
-- Themes define colours, icons, font and wallpapers.
|
||||
-- beautiful.init(gears.filesystem.get_themes_dir() .. "default/theme.lua")
|
||||
beautiful.init(gears.filesystem.get_configuration_dir() .. "mytheme.lua")
|
||||
|
||||
-- This is used later as the default terminal and editor to run.
|
||||
local terminal = "alacritty"
|
||||
local terminal = "{{terminal}}"
|
||||
local editor = os.getenv("EDITOR") or "nvim"
|
||||
local editor_cmd = terminal .. " -e " .. editor
|
||||
|
||||
@ -99,9 +98,8 @@ awful.layout.layouts = {
|
||||
-- awful.layout.suit.corner.sw,
|
||||
-- awful.layout.suit.corner.se,
|
||||
}
|
||||
-- }}}
|
||||
|
||||
-- {{{ Menu
|
||||
-- Menu
|
||||
-- Create a launcher widget and a main menu
|
||||
local myawesomemenu = {
|
||||
{
|
||||
@ -128,12 +126,11 @@ local mymainmenu =
|
||||
|
||||
-- Menubar configuration
|
||||
menubar.utils.terminal = terminal -- Set the terminal for applications that require it
|
||||
-- }}}
|
||||
|
||||
-- Keyboard map indicator and switcher
|
||||
-- local mykeyboardlayout = awful.widget.keyboardlayout()
|
||||
|
||||
-- {{{ Wibar
|
||||
-- Wibar
|
||||
-- Create a textclock widget
|
||||
local mytextclock = wibox.widget.textclock(" %d.%m.%Y, %H:%M:%S ", 1)
|
||||
|
||||
@ -327,9 +324,8 @@ awful.screen.connect_for_each_screen(function(s)
|
||||
},
|
||||
})
|
||||
end)
|
||||
-- }}}
|
||||
|
||||
-- {{{ Mouse bindings
|
||||
--- Mouse bindings
|
||||
root.buttons(gears.table.join(
|
||||
awful.button({}, 3, function()
|
||||
mymainmenu:toggle()
|
||||
@ -337,9 +333,8 @@ root.buttons(gears.table.join(
|
||||
awful.button({}, 4, awful.tag.viewnext),
|
||||
awful.button({}, 5, awful.tag.viewprev)
|
||||
))
|
||||
-- }}}
|
||||
|
||||
-- {{{ Key bindings
|
||||
--- Key bindings
|
||||
local globalkeys = gears.table.join(
|
||||
|
||||
awful.key({ "Shift" }, "Pause", function()
|
||||
@ -445,7 +440,7 @@ local globalkeys = gears.table.join(
|
||||
awful.spawn("floorp")
|
||||
end, { description = "open browser", group = "launcher" }),
|
||||
awful.key({ modkey }, "n", function()
|
||||
awful.spawn("alacritty -e yazi")
|
||||
awful.spawn(terminal .. " -e yazi")
|
||||
end, { description = "open yazi", group = "launcher" }),
|
||||
|
||||
awful.key({ modkey }, "l", function()
|
||||
@ -606,9 +601,8 @@ local clientbuttons = gears.table.join(
|
||||
|
||||
-- Set keys
|
||||
root.keys(globalkeys)
|
||||
-- }}}
|
||||
|
||||
-- {{{ Rules
|
||||
--- Rules
|
||||
-- Rules to apply to new clients (through the "manage" signal).
|
||||
awful.rules.rules = {
|
||||
-- All clients will match this rule.
|
||||
@ -694,7 +688,7 @@ awful.rules.rules = {
|
||||
{ rule_any = { class = { "mpv" } }, properties = { fullscreen = true } },
|
||||
}
|
||||
|
||||
-- {{{ Signals
|
||||
--- Signals
|
||||
-- Signal function to execute when a new client appears.
|
||||
client.connect_signal("manage", function(c)
|
||||
-- Set the windows at the slave,
|
||||
|
||||
@ -30,7 +30,7 @@ local hotkeys_popup = require("awful.hotkeys_popup")
|
||||
-- when client with a matching name is opened:
|
||||
require("awful.hotkeys_popup.keys")
|
||||
|
||||
-- {{{ Error handling
|
||||
--- Error handling
|
||||
-- Check if awesome encountered an error during startup and fell back to
|
||||
-- another config (This code will only ever execute for the fallback config)
|
||||
if awesome.startup_errors then
|
||||
@ -59,15 +59,14 @@ do
|
||||
in_error = false
|
||||
end)
|
||||
end
|
||||
-- }}}
|
||||
|
||||
-- {{{ Variable definitions
|
||||
--- Variable definitions
|
||||
-- Themes define colours, icons, font and wallpapers.
|
||||
-- beautiful.init(gears.filesystem.get_themes_dir() .. "default/theme.lua")
|
||||
beautiful.init(gears.filesystem.get_configuration_dir() .. "mytheme.lua")
|
||||
|
||||
-- This is used later as the default terminal and editor to run.
|
||||
local terminal = "alacritty"
|
||||
local terminal = "{{terminal}}"
|
||||
local editor = os.getenv("EDITOR") or "nvim"
|
||||
local editor_cmd = terminal .. " -e " .. editor
|
||||
|
||||
@ -98,9 +97,8 @@ awful.layout.layouts = {
|
||||
-- awful.layout.suit.corner.sw,
|
||||
-- awful.layout.suit.corner.se,
|
||||
}
|
||||
-- }}}
|
||||
|
||||
-- {{{ Menu
|
||||
--- Menu
|
||||
-- Create a launcher widget and a main menu
|
||||
local myawesomemenu = {
|
||||
{
|
||||
@ -127,12 +125,11 @@ local mymainmenu =
|
||||
|
||||
-- Menubar configuration
|
||||
menubar.utils.terminal = terminal -- Set the terminal for applications that require it
|
||||
-- }}}
|
||||
|
||||
-- Keyboard map indicator and switcher
|
||||
-- local mykeyboardlayout = awful.widget.keyboardlayout()
|
||||
|
||||
-- {{{ Wibar
|
||||
--- Wibar
|
||||
-- Create a textclock widget
|
||||
local mytextclock = wibox.widget.textclock(" %d.%m.%Y, %H:%M:%S ", 1)
|
||||
|
||||
@ -320,9 +317,8 @@ awful.screen.connect_for_each_screen(function(s)
|
||||
},
|
||||
})
|
||||
end)
|
||||
-- }}}
|
||||
|
||||
-- {{{ Mouse bindings
|
||||
--- Mouse bindings
|
||||
root.buttons(gears.table.join(
|
||||
awful.button({}, 3, function()
|
||||
mymainmenu:toggle()
|
||||
@ -330,9 +326,8 @@ root.buttons(gears.table.join(
|
||||
awful.button({}, 4, awful.tag.viewnext),
|
||||
awful.button({}, 5, awful.tag.viewprev)
|
||||
))
|
||||
-- }}}
|
||||
|
||||
-- {{{ Key bindings
|
||||
--- Key bindings
|
||||
local globalkeys = gears.table.join(
|
||||
|
||||
awful.key({ "Shift" }, "Pause", function()
|
||||
@ -438,7 +433,7 @@ local globalkeys = gears.table.join(
|
||||
awful.spawn("floorp")
|
||||
end, { description = "open browser", group = "launcher" }),
|
||||
awful.key({ modkey }, "n", function()
|
||||
awful.spawn("alacritty -e yazi")
|
||||
awful.spawn(terminal .. " -e yazi")
|
||||
end, { description = "open yazi", group = "launcher" }),
|
||||
|
||||
awful.key({ modkey }, "l", function()
|
||||
@ -595,9 +590,8 @@ local clientbuttons = gears.table.join(
|
||||
|
||||
-- Set keys
|
||||
root.keys(globalkeys)
|
||||
-- }}}
|
||||
|
||||
-- {{{ Rules
|
||||
--- Rules
|
||||
-- Rules to apply to new clients (through the "manage" signal).
|
||||
awful.rules.rules = {
|
||||
-- All clients will match this rule.
|
||||
@ -683,7 +677,7 @@ awful.rules.rules = {
|
||||
{ rule_any = { class = { "mpv" } }, properties = { fullscreen = true } },
|
||||
}
|
||||
|
||||
-- {{{ Signals
|
||||
--- Signals
|
||||
-- Signal function to execute when a new client appears.
|
||||
client.connect_signal("manage", function(c)
|
||||
-- Set the windows at the slave,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
2510
config/ghostty/default
Normal file
2510
config/ghostty/default
Normal file
File diff suppressed because it is too large
Load Diff
@ -28,7 +28,7 @@ monitor=HDMI-A-1,prefered,auto,1
|
||||
# See https://wiki.hyprland.org/Configuring/Keywords/
|
||||
|
||||
# Set programs that you use
|
||||
$terminal = alacritty
|
||||
$terminal = {{terminal}}
|
||||
$fileManager = $terminal -e yazi
|
||||
$menu = wofi --show drun -ib
|
||||
$browser = floorp
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
bookmark = [
|
||||
{key = "r", path = "/"},
|
||||
{key = "e", path = "/etc"},
|
||||
|
||||
{key = "h", path = "~/"},
|
||||
]
|
||||
@ -1,51 +0,0 @@
|
||||
numbered_command = false
|
||||
|
||||
use_trash = true
|
||||
watch_files = true
|
||||
xdg_open = false
|
||||
xdg_open_fork = false
|
||||
|
||||
|
||||
[display]
|
||||
# default, hsplit
|
||||
mode = "default"
|
||||
|
||||
automatically_count_files = false
|
||||
collapse_preview = true
|
||||
# ratios for parent view (optional), current view and preview
|
||||
column_ratio = [ 1, 4, 4 ]
|
||||
scroll_offset = 6
|
||||
show_borders = true
|
||||
show_hidden = false
|
||||
show_icons = true
|
||||
tilde_in_titlebar = true
|
||||
# none, absolute, relative
|
||||
line_number_style = "none"
|
||||
|
||||
# size, mtime, user, gourp, perm. can be combined with |.
|
||||
# `none` to disable, `all` to enable all
|
||||
# all and none can't be combined with other options
|
||||
linemode = "size"
|
||||
|
||||
[display.sort]
|
||||
# lexical, mtime, natural, size, ext
|
||||
sort_method = "natural"
|
||||
case_sensitive = false
|
||||
directories_first = true
|
||||
reverse = false
|
||||
|
||||
[preview]
|
||||
max_preview_size = 2097152 # 2MB
|
||||
preview_script = "~/.config/joshuto/preview_file.sh" # make sure it's marked as executable
|
||||
|
||||
[search]
|
||||
# insensitive, sensitive, smart
|
||||
string_case_sensitivity = "insensitive"
|
||||
# see above
|
||||
glob_case_sensitivity = "sensitive"
|
||||
# see above
|
||||
fzf_case_sensitivity = "insensitive"
|
||||
|
||||
[tab]
|
||||
# inherit, home, root
|
||||
home_page = "home"
|
||||
@ -1,172 +0,0 @@
|
||||
[default_view]
|
||||
|
||||
keymap = [
|
||||
{keys = [ "escape" ], command = "escape"},
|
||||
{keys = [ "ctrl+t" ], command = "new_tab"},
|
||||
{keys = [ "alt+t" ], command = "new_tab --cursor"},
|
||||
{keys = [ "T" ], command = "new_tab --current"},
|
||||
{keys = [ "W" ], command = "close_tab"},
|
||||
{keys = [ "ctrl+w" ], command = "close_tab"},
|
||||
{keys = [ "q" ], command = "close_tab"},
|
||||
{keys = [ "ctrl+c" ], command = "quit"},
|
||||
{keys = [ "Q" ], command = "quit --output-current-directory"},
|
||||
|
||||
{keys = [ "R" ], command = "reload_dirlist"},
|
||||
{keys = [ "z", "h" ], command = "toggle_hidden"},
|
||||
{keys = [ "ctrl+h" ], command = "toggle_hidden"},
|
||||
{keys = [ "\t" ], command = "tab_switch 1"},
|
||||
{keys = [ "backtab" ], command = "tab_switch -1"},
|
||||
|
||||
{keys = [ "alt+1" ], command = "tab_switch_index 1"},
|
||||
{keys = [ "alt+2" ], command = "tab_switch_index 2"},
|
||||
{keys = [ "alt+3" ], command = "tab_switch_index 3"},
|
||||
{keys = [ "alt+4" ], command = "tab_switch_index 4"},
|
||||
{keys = [ "alt+5" ], command = "tab_switch_index 5"},
|
||||
|
||||
{keys = [ "1" ], command = "numbered_command 1"},
|
||||
{keys = [ "2" ], command = "numbered_command 2"},
|
||||
{keys = [ "3" ], command = "numbered_command 3"},
|
||||
{keys = [ "4" ], command = "numbered_command 4"},
|
||||
{keys = [ "5" ], command = "numbered_command 5"},
|
||||
{keys = [ "6" ], command = "numbered_command 6"},
|
||||
{keys = [ "7" ], command = "numbered_command 7"},
|
||||
{keys = [ "8" ], command = "numbered_command 8"},
|
||||
{keys = [ "9" ], command = "numbered_command 9"},
|
||||
|
||||
# arrow keys
|
||||
{keys = [ "arrow_up" ], command = "cursor_move_up"},
|
||||
{keys = [ "arrow_down" ], command = "cursor_move_down"},
|
||||
{keys = [ "arrow_left" ], command = "cd .."},
|
||||
{keys = [ "arrow_right" ], command = "open"},
|
||||
{keys = [ "\n" ], command = "open"},
|
||||
{keys = [ "home" ], command = "cursor_move_home"},
|
||||
{keys = [ "end" ], command = "cursor_move_end"},
|
||||
{keys = [ "page_up" ], command = "cursor_move_page_up"},
|
||||
{keys = [ "page_down" ], command = "cursor_move_page_down"},
|
||||
{keys = [ "ctrl+u" ], command = "cursor_move_page_up 0.5"},
|
||||
{keys = [ "ctrl+d" ], command = "cursor_move_page_down 0.5"},
|
||||
{keys = [ "ctrl+b" ], command = "cursor_move_page_up"},
|
||||
{keys = [ "ctrl+f" ], command = "cursor_move_page_down"},
|
||||
|
||||
# vim-like keybindings
|
||||
{keys = [ "j" ], command = "cursor_move_down"},
|
||||
{keys = [ "k" ], command = "cursor_move_up"},
|
||||
{keys = [ "h" ], command = "cd .."},
|
||||
{keys = [ "l" ], command = "open"},
|
||||
{keys = [ "g", "g" ], command = "cursor_move_home"},
|
||||
{keys = [ "G" ], command = "cursor_move_end"},
|
||||
{keys = [ "r" ], command = "open_with"},
|
||||
|
||||
{keys = [ "H" ], command = "cursor_move_page_home"},
|
||||
{keys = [ "L" ], command = "cursor_move_page_middle"},
|
||||
{keys = [ "M" ], command = "cursor_move_page_end"},
|
||||
|
||||
{keys = [ "[" ], command = "parent_cursor_move_up"},
|
||||
{keys = [ "]" ], command = "parent_cursor_move_down"},
|
||||
|
||||
{keys = [ "c", "d" ], command = ":cd "},
|
||||
{keys = [ "d", "d" ], command = "cut_files"},
|
||||
{keys = [ "y", "y" ], command = "copy_files"},
|
||||
{keys = [ "y", "n" ], command = "copy_filename"},
|
||||
{keys = [ "y", "." ], command = "copy_filename_without_extension"},
|
||||
{keys = [ "y", "p" ], command = "copy_filepath"},
|
||||
{keys = [ "y", "a" ], command = "copy_filepath --all-selected=true"},
|
||||
{keys = [ "y", "d" ], command = "copy_dirpath"},
|
||||
|
||||
{keys = [ "p", "l" ], command = "symlink_files --relative=false"},
|
||||
{keys = [ "p", "L" ], command = "symlink_files --relative=true"},
|
||||
|
||||
{keys = [ "delete" ], command = "delete_files"},
|
||||
{keys = [ "d", "D" ], command = "delete_files"},
|
||||
|
||||
{keys = [ "p", "p" ], command = "paste_files"},
|
||||
{keys = [ "p", "o" ], command = "paste_files --overwrite=true"},
|
||||
|
||||
{keys = [ "a" ], command = "rename_append"},
|
||||
{keys = [ "A" ], command = "rename_prepend"},
|
||||
|
||||
{keys = [ "f", "t" ], command = ":touch "},
|
||||
|
||||
{keys = [ " " ], command = "select --toggle=true"},
|
||||
{keys = [ "t" ], command = "select --all=true --toggle=true"},
|
||||
{keys = [ "V" ], command = "toggle_visual"},
|
||||
|
||||
{keys = [ "w" ], command = "show_tasks --exit-key=w"},
|
||||
{keys = [ "b", "b" ], command = "bulk_rename"},
|
||||
{keys = [ "=" ], command = "set_mode"},
|
||||
|
||||
{keys = [ ":" ], command = ":"},
|
||||
{keys = [ ";" ], command = ":"},
|
||||
|
||||
{keys = [ "'" ], command = ":shell "},
|
||||
{keys = [ "m", "k" ], command = ":mkdir "},
|
||||
{keys = [ "c", "w" ], command = ":rename "},
|
||||
|
||||
{keys = [ "/" ], command = ":search "},
|
||||
{keys = [ "|" ], command = ":search_inc "},
|
||||
{keys = [ "\\" ], command = ":search_glob "},
|
||||
{keys = [ "S" ], command = "search_fzf"},
|
||||
{keys = [ "C" ], command = "subdir_fzf"},
|
||||
|
||||
{keys = [ "n" ], command = "search_next"},
|
||||
{keys = [ "N" ], command = "search_prev"},
|
||||
|
||||
{keys = [ "s", "r" ], command = "sort reverse"},
|
||||
{keys = [ "s", "l" ], command = "sort lexical"},
|
||||
{keys = [ "s", "m" ], command = "sort mtime"},
|
||||
{keys = [ "s", "n" ], command = "sort natural"},
|
||||
{keys = [ "s", "s" ], command = "sort size"},
|
||||
{keys = [ "s", "e" ], command = "sort ext"},
|
||||
|
||||
{keys = [ "m", "s" ], command = "linemode size"},
|
||||
{keys = [ "m", "m" ], command = "linemode mtime"},
|
||||
{keys = [ "m", "M" ], command = "linemode size | mtime"},
|
||||
{keys = [ "m", "u" ], command = "linemode user"},
|
||||
{keys = [ "m", "U" ], command = "linemode user | group"},
|
||||
{keys = [ "m", "p" ], command = "linemode perm"},
|
||||
|
||||
{keys = [ "g", "r" ], command = "cd /"},
|
||||
{keys = [ "g", "c" ], command = "cd ~/.config"},
|
||||
{keys = [ "g", "d" ], command = "cd ~/Downloads"},
|
||||
{keys = [ "g", "e" ], command = "cd /etc"},
|
||||
{keys = [ "g", "h" ], command = "cd ~/"},
|
||||
{keys = [ "?" ], command = "help"},
|
||||
]
|
||||
|
||||
[task_view]
|
||||
|
||||
keymap = [
|
||||
# arrow keys
|
||||
{keys = [ "arrow_up" ], command = "cursor_move_up"},
|
||||
{keys = [ "arrow_down" ], command = "cursor_move_down"},
|
||||
{keys = [ "home" ], command = "cursor_move_home"},
|
||||
{keys = [ "end" ], command = "cursor_move_end"},
|
||||
|
||||
# vim-like keybindings
|
||||
{keys = [ "j" ], command = "cursor_move_down"},
|
||||
{keys = [ "k" ], command = "cursor_move_up"},
|
||||
{keys = [ "g", "g" ], command = "cursor_move_home"},
|
||||
{keys = [ "G" ], command = "cursor_move_end"},
|
||||
|
||||
{keys = [ "w" ], command = "show_tasks"},
|
||||
{keys = [ "escape" ], command = "show_tasks"},
|
||||
]
|
||||
|
||||
[help_view]
|
||||
|
||||
keymap = [
|
||||
# arrow keys
|
||||
{keys = [ "arrow_up" ], command = "cursor_move_up"},
|
||||
{keys = [ "arrow_down" ], command = "cursor_move_down"},
|
||||
{keys = [ "home" ], command = "cursor_move_home"},
|
||||
{keys = [ "end" ], command = "cursor_move_end"},
|
||||
|
||||
# vim-like keybindings
|
||||
{keys = [ "j" ], command = "cursor_move_down"},
|
||||
{keys = [ "k" ], command = "cursor_move_up"},
|
||||
{keys = [ "g", "g" ], command = "cursor_move_home"},
|
||||
{keys = [ "G" ], command = "cursor_move_end"},
|
||||
|
||||
{keys = [ "w" ], command = "show_tasks"},
|
||||
{keys = [ "escape" ], command = "show_tasks"},
|
||||
]
|
||||
@ -1,229 +0,0 @@
|
||||
[class]
|
||||
audio_default = [
|
||||
{command = "mpv", args = [
|
||||
"--",
|
||||
]},
|
||||
{command = "mediainfo", confirm_exit = true},
|
||||
]
|
||||
|
||||
image_default = [
|
||||
{command = "qimgv", args = [
|
||||
"--",
|
||||
], fork = true, silent = true},
|
||||
{command = "krita", args = [
|
||||
"--",
|
||||
], fork = true, silent = true},
|
||||
{command = "exiftool", confirm_exit = true},
|
||||
{command = "swappy", args = [
|
||||
"-f",
|
||||
], fork = true},
|
||||
]
|
||||
|
||||
video_default = [
|
||||
{command = "mpv", args = [
|
||||
"--",
|
||||
], fork = true, silent = true},
|
||||
{command = "mediainfo", confirm_exit = true},
|
||||
{command = "mpv", args = [
|
||||
"--mute",
|
||||
"on",
|
||||
"--",
|
||||
], fork = true, silent = true},
|
||||
]
|
||||
|
||||
text_default = [
|
||||
{command = "micro"},
|
||||
{command = "gedit", fork = true, silent = true},
|
||||
{command = "bat", args = [
|
||||
"--paging=always",
|
||||
]},
|
||||
]
|
||||
|
||||
reader_default = [ {command = "evince", fork = true, silent = true} ]
|
||||
|
||||
libreoffice_default = [ {command = "libreoffice", fork = true, silent = true} ]
|
||||
|
||||
[extension]
|
||||
|
||||
## image formats
|
||||
avif.inherit = "image_default"
|
||||
bmp.inherit = "image_default"
|
||||
gif.inherit = "image_default"
|
||||
heic.inherit = "image_default"
|
||||
jpeg.inherit = "image_default"
|
||||
jpe.inherit = "image_default"
|
||||
jpg.inherit = "image_default"
|
||||
pgm.inherit = "image_default"
|
||||
png.inherit = "image_default"
|
||||
ppm.inherit = "image_default"
|
||||
webp.inherit = "image_default"
|
||||
|
||||
svg.app_list = [
|
||||
{command = "inkview", fork = true, silent = true},
|
||||
{command = "inkscape", fork = true, silent = true},
|
||||
]
|
||||
tiff.app_list = [
|
||||
{command = "qimgv", fork = true, silent = true},
|
||||
{command = "krita", fork = true, silent = true},
|
||||
]
|
||||
|
||||
## audio formats
|
||||
flac.inherit = "audio_default"
|
||||
m4a.inherit = "audio_default"
|
||||
mp3.inherit = "audio_default"
|
||||
ogg.inherit = "audio_default"
|
||||
wav.inherit = "audio_default"
|
||||
|
||||
## video formats
|
||||
avi.inherit = "video_default"
|
||||
av1.inherit = "video_default"
|
||||
flv.inherit = "video_default"
|
||||
mkv.inherit = "video_default"
|
||||
m4v.inherit = "video_default"
|
||||
mov.inherit = "video_default"
|
||||
mp4.inherit = "video_default"
|
||||
ts.inherit = "video_default"
|
||||
webm.inherit = "video_default"
|
||||
wmv.inherit = "video_default"
|
||||
|
||||
## text formats
|
||||
build.inherit = "text_default"
|
||||
c.inherit = "text_default"
|
||||
cmake.inherit = "text_default"
|
||||
conf.inherit = "text_default"
|
||||
cpp.inherit = "text_default"
|
||||
css.inherit = "text_default"
|
||||
csv.inherit = "text_default"
|
||||
cu.inherit = "text_default"
|
||||
ebuild.inherit = "text_default"
|
||||
eex.inherit = "text_default"
|
||||
env.inherit = "text_default"
|
||||
ex.inherit = "text_default"
|
||||
exs.inherit = "text_default"
|
||||
go.inherit = "text_default"
|
||||
h.inherit = "text_default"
|
||||
hpp.inherit = "text_default"
|
||||
hs.inherit = "text_default"
|
||||
html.inherit = "text_default"
|
||||
ini.inherit = "text_default"
|
||||
java.inherit = "text_default"
|
||||
js.inherit = "text_default"
|
||||
json.inherit = "text_default"
|
||||
kt.inherit = "text_default"
|
||||
lua.inherit = "text_default"
|
||||
log.inherit = "text_default"
|
||||
md.inherit = "text_default"
|
||||
micro.inherit = "text_default"
|
||||
ninja.inherit = "text_default"
|
||||
py.inherit = "text_default"
|
||||
rkt.inherit = "text_default"
|
||||
rs.inherit = "text_default"
|
||||
scss.inherit = "text_default"
|
||||
sh.inherit = "text_default"
|
||||
srt.inherit = "text_default"
|
||||
svelte.inherit = "text_default"
|
||||
toml.inherit = "text_default"
|
||||
tsx.inherit = "text_default"
|
||||
txt.inherit = "text_default"
|
||||
vim.inherit = "text_default"
|
||||
xml.inherit = "text_default"
|
||||
yaml.inherit = "text_default"
|
||||
yml.inherit = "text_default"
|
||||
|
||||
# archive formats
|
||||
7z.app_list = [
|
||||
{command = "7z", args = [
|
||||
"x",
|
||||
], confirm_exit = true},
|
||||
{command = "file-roller", fork = true, silent = true},
|
||||
]
|
||||
bz2.app_list = [
|
||||
{command = "tar", args = [
|
||||
"-xvjf",
|
||||
], confirm_exit = true},
|
||||
{command = "file-roller", fork = true, silent = true},
|
||||
]
|
||||
gz.app_list = [
|
||||
{command = "tar", args = [
|
||||
"-xvzf",
|
||||
], confirm_exit = true},
|
||||
{command = "file-roller", fork = true, silent = true},
|
||||
]
|
||||
tar.app_list = [
|
||||
{command = "tar", args = [
|
||||
"-xvf",
|
||||
], confirm_exit = true},
|
||||
{command = "file-roller", fork = true, silent = true},
|
||||
]
|
||||
tgz.app_list = [
|
||||
{command = "tar", args = [
|
||||
"-xvzf",
|
||||
], confirm_exit = true},
|
||||
{command = "file-roller", fork = true, silent = true},
|
||||
]
|
||||
rar.app_list = [
|
||||
{command = "unrar", args = [
|
||||
"x",
|
||||
], confirm_exit = true},
|
||||
{command = "file-roller", fork = true, silent = true},
|
||||
]
|
||||
xz.app_list = [
|
||||
{command = "tar", args = [
|
||||
"-xvJf",
|
||||
], confirm_exit = true},
|
||||
{command = "file-roller", fork = true, silent = true},
|
||||
]
|
||||
zip.app_list = [
|
||||
{command = "unzip", confirm_exit = true},
|
||||
{command = "file-roller", fork = true, silent = true},
|
||||
]
|
||||
|
||||
# misc formats
|
||||
aup.app_list = [ {command = "audacity", fork = true, silent = true} ]
|
||||
|
||||
m3u.app_list = [
|
||||
{command = "micro"},
|
||||
{command = "mpv"},
|
||||
{command = "gedit", fork = true, silent = true},
|
||||
{command = "bat", confirm_exit = true},
|
||||
]
|
||||
|
||||
odt.inherit = "libreoffice_default"
|
||||
odf.inherit = "libreoffice_default"
|
||||
ods.inherit = "libreoffice_default"
|
||||
odp.inherit = "libreoffice_default"
|
||||
|
||||
doc.inherit = "libreoffice_default"
|
||||
docx.inherit = "libreoffice_default"
|
||||
xls.inherit = "libreoffice_default"
|
||||
xlsx.inherit = "libreoffice_default"
|
||||
ppt.inherit = "libreoffice_default"
|
||||
pptx.inherit = "libreoffice_default"
|
||||
|
||||
pdf.inherit = "reader_default"
|
||||
|
||||
kra.app_list = [ {command = "krita", fork = true, silent = true} ]
|
||||
kdenlive.app_list = [ {command = "kdenlive", fork = true, silent = true} ]
|
||||
|
||||
tex.app_list = [
|
||||
{command = "micro"},
|
||||
{command = "gedit", fork = true, silent = true},
|
||||
{command = "bat", confirm_exit = true},
|
||||
{command = "pdflatex"},
|
||||
]
|
||||
|
||||
torrent.app_list = [ {command = "transmission-gtk"} ]
|
||||
|
||||
[mimetype]
|
||||
|
||||
# application/octet-stream
|
||||
[mimetype.application.subtype.octet-stream]
|
||||
inherit = "video_default"
|
||||
|
||||
# text/*
|
||||
[mimetype.text]
|
||||
inherit = "text_default"
|
||||
|
||||
# text/*
|
||||
[mimetype.video]
|
||||
inherit = "video_default"
|
||||
@ -1,111 +0,0 @@
|
||||
##########################################
|
||||
## Tabs
|
||||
##########################################
|
||||
|
||||
# Inactive tabs
|
||||
[tabs.inactive]
|
||||
|
||||
# Active tabs
|
||||
[tabs.active]
|
||||
invert = true
|
||||
|
||||
##########################################
|
||||
## File List - Selections
|
||||
##########################################
|
||||
|
||||
# Selected files (standard selection)
|
||||
[selection]
|
||||
fg = "light_yellow"
|
||||
bold = true
|
||||
|
||||
# Files selected in current visual mode
|
||||
[visual_mode_selection]
|
||||
fg = "light_red"
|
||||
bold = true
|
||||
|
||||
[selection.prefix]
|
||||
prefix = " "
|
||||
size = 2
|
||||
|
||||
##########################################
|
||||
## File List - System File Types
|
||||
##########################################
|
||||
|
||||
# Basic style, used for regular files (and also device files and FIFOs)
|
||||
[regular]
|
||||
fg = "white"
|
||||
|
||||
# For directories
|
||||
[directory]
|
||||
fg = "light_blue"
|
||||
bold = true
|
||||
|
||||
# For symbolic links
|
||||
[link]
|
||||
fg = "cyan"
|
||||
bold = true
|
||||
|
||||
# For socket files
|
||||
[socket]
|
||||
fg = "light_magenta"
|
||||
bold = true
|
||||
|
||||
##########################################
|
||||
## File List - Exceptional Files
|
||||
##########################################
|
||||
|
||||
# Files marked as executable
|
||||
[executable]
|
||||
fg = "light_green"
|
||||
bold = true
|
||||
|
||||
# Invalid symbolic links (pointing to non-existing target)
|
||||
[link_invalid]
|
||||
fg = "red"
|
||||
bold = true
|
||||
|
||||
##########################################
|
||||
## File list - Override style by extension
|
||||
##########################################
|
||||
# This sections allows to override the basic
|
||||
# style with a specific style for the file's
|
||||
# extension.
|
||||
|
||||
[ext]
|
||||
|
||||
bmp.fg = "yellow"
|
||||
gif.fg = "yellow"
|
||||
heic.fg = "yellow"
|
||||
jpg.fg = "yellow"
|
||||
jpeg.fg = "yellow"
|
||||
pgm.fg = "yellow"
|
||||
png.fg = "yellow"
|
||||
ppm.fg = "yellow"
|
||||
svg.fg = "yellow"
|
||||
|
||||
wav.fg = "magenta"
|
||||
flac.fg = "magenta"
|
||||
mp3.fg = "magenta"
|
||||
amr.fg = "magenta"
|
||||
|
||||
avi.fg = "magenta"
|
||||
flv.fg = "magenta"
|
||||
m3u.fg = "magenta"
|
||||
m4a.fg = "magenta"
|
||||
m4v.fg = "magenta"
|
||||
mkv.fg = "magenta"
|
||||
mov.fg = "magenta"
|
||||
mp4.fg = "magenta"
|
||||
mpg.fg = "magenta"
|
||||
rmvb.fg = "magenta"
|
||||
webm.fg = "magenta"
|
||||
wmv.fg = "magenta"
|
||||
|
||||
7z.fg = "red"
|
||||
bz2.fg = "red"
|
||||
gz.fg = "red"
|
||||
rar.fg = "red"
|
||||
tar.fg = "red"
|
||||
tgz.fg = "red"
|
||||
xz.fg = "red"
|
||||
zip.fg = "red"
|
||||
@ -8,7 +8,7 @@ configuration {
|
||||
// xoffset: 0;
|
||||
fixed-num-lines: true;
|
||||
show-icons: true;
|
||||
terminal: "alacritty";
|
||||
terminal: "{{terminal}}";
|
||||
ssh-clicnt: "ssh";
|
||||
// ssh-command: "{terminal} -e {ssh-client} {host} [-p {port}]";
|
||||
// run-command: "{cmd}";
|
||||
|
||||
@ -26,7 +26,7 @@ export BROWSER="floorp"
|
||||
export EDITOR="nvim"
|
||||
export IMAGE="nsxiv"
|
||||
export READER="zathura"
|
||||
export TERMINAL="alacritty"
|
||||
export TERMINAL="{{terminal}}"
|
||||
export VIDEO="mpv"
|
||||
export VISUAL="$EDITOR"
|
||||
export WM="awesome"
|
||||
|
||||
@ -3,6 +3,8 @@ set -g default-terminal "screen-256color"
|
||||
set-option -sa terminal-overrides ",Alacritty*:Tc"
|
||||
set-option -sa terminal-overrides ",alacritty*:Tc"
|
||||
set-option -sa terminal-overrides ",xterm*:Tc"
|
||||
set-option -sa terminal-overrides ",Ghostty*:Tc"
|
||||
set-option -sa terminal-overrides ",ghostty*:Tc"
|
||||
|
||||
set-option -g status-position top
|
||||
set-option -sg escape-time 0
|
||||
|
||||
@ -196,16 +196,6 @@
|
||||
/* "exec": "$HOME/.config/waybar/scripts/mediaplayer.py --player spotify 2> /dev/null" // Filter player based on name */
|
||||
},
|
||||
|
||||
|
||||
"custom/pacman": {
|
||||
"format": "{} ",
|
||||
"interval": 600, // every hour
|
||||
"exec": "checkupdates | wc -l", // # of updates
|
||||
"exec-if": "exit 0", // always run; consider advanced run conditions
|
||||
"on-click": "alacritty -e paru -Syu --noconfirm; pkill -RTMIN+8 waybar", // update system
|
||||
"signal": 8
|
||||
},
|
||||
|
||||
"custom/weather": {
|
||||
"exec": "curl 'https://wttr.in/?format=1'",
|
||||
"interval": 600,
|
||||
|
||||
@ -1,59 +0,0 @@
|
||||
---@diagnostic disable
|
||||
local xplr = xplr -- The globally exposed configuration to be overridden.
|
||||
---@diagnostic enable
|
||||
|
||||
-- -- Preview images using imv.
|
||||
-- xplr.config.modes.builtin.default.key_bindings.on_key.P = {
|
||||
-- help = "preview",
|
||||
-- messages = {
|
||||
-- {
|
||||
-- BashExecSilently0 = [===[
|
||||
-- FIFO_PATH="/tmp/xplr.fifo"
|
||||
--
|
||||
-- if [ -e "$FIFO_PATH" ]; then
|
||||
-- "$XPLR" -m StopFifo
|
||||
-- rm -f -- "$FIFO_PATH"
|
||||
-- else
|
||||
-- mkfifo "$FIFO_PATH"
|
||||
-- "$HOME/.local/bin/imv-open" "$FIFO_PATH" "$XPLR_FOCUS_PATH" &
|
||||
-- "$XPLR" -m 'StartFifo: %q' "$FIFO_PATH"
|
||||
-- fi
|
||||
-- ]===],
|
||||
-- },
|
||||
-- },
|
||||
-- }
|
||||
--
|
||||
-- -- Batch rename the selected or visible files and directories in `$PWD`.
|
||||
-- xplr.config.modes.builtin.default.key_bindings.on_key.R = {
|
||||
-- help = "batch rename",
|
||||
-- messages = {
|
||||
-- {
|
||||
-- BashExec = [===[
|
||||
-- SELECTION=$(cat "${XPLR_PIPE_SELECTION_OUT:?}")
|
||||
-- NODES=${SELECTION:-$(cat "${XPLR_PIPE_DIRECTORY_NODES_OUT:?}")}
|
||||
-- if [ "$NODES" ]; then
|
||||
-- echo -e "$NODES" | renamer
|
||||
-- "$XPLR" -m ExplorePwdAsync
|
||||
-- fi
|
||||
-- ]===],
|
||||
-- },
|
||||
-- },
|
||||
-- }
|
||||
--
|
||||
-- -- Serve `$PWD` using a static web server via LAN.
|
||||
-- xplr.config.modes.builtin.default.key_bindings.on_key.S = {
|
||||
-- help = "serve $PWD",
|
||||
-- messages = {
|
||||
-- {
|
||||
-- BashExec0 = [===[
|
||||
-- IP=$(ip addr | rg -w inet | cut -d/ -f1 | rg -Eo '[0-9]{1,3}\.[0-9]{ 1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sk --prompt 'Select IP > ')
|
||||
-- echo "IP: ${IP:?}"
|
||||
-- read -p "Port (default 5000): " PORT
|
||||
-- echo
|
||||
-- sfz --all --cors --no-ignore --bind ${IP:?} --port ${PORT:-5000} . &
|
||||
-- sleep 1 && read -p '[press enter to exit]'
|
||||
-- kill -9 %1
|
||||
-- ]===],
|
||||
-- },
|
||||
-- },
|
||||
-- }
|
||||
@ -1,48 +0,0 @@
|
||||
---@diagnostic disable
|
||||
local xplr = xplr -- The globally exposed configuration to be overridden.
|
||||
---@diagnostic enable
|
||||
|
||||
-- This is the built-in configuration file that gets loaded and sets the
|
||||
-- default values when xplr loads, before loading any other custom
|
||||
-- configuration file.
|
||||
--
|
||||
-- You can use this file as a reference to create a your custom config file.
|
||||
--
|
||||
-- To create a custom configuration file, you need to define the script version
|
||||
-- for compatibility checks.
|
||||
--
|
||||
-- See https://xplr.dev/en/upgrade-guide
|
||||
--
|
||||
-- ```lua
|
||||
version = "0.21.3"
|
||||
|
||||
local home = os.getenv("HOME")
|
||||
local xpm_path = home .. "/.local/share/xplr/dtomvan/xpm.xplr"
|
||||
local xpm_url = "https://github.com/dtomvan/xpm.xplr"
|
||||
|
||||
package.path = package.path .. ";" .. xpm_path .. "/?.lua;" .. xpm_path .. "/?/init.lua"
|
||||
|
||||
os.execute(string.format("[ -e '%s' ] || git clone '%s' '%s'", xpm_path, xpm_url, xpm_path))
|
||||
|
||||
require("xpm").setup({
|
||||
plugins = {
|
||||
"dtomvan/xpm.xplr",
|
||||
"sayanarijit/fzf.xplr",
|
||||
"prncss-xyz/icons.xplr",
|
||||
"sayanarijit/xclip.xplr",
|
||||
"sayanarijit/trash-cli.xplr",
|
||||
"sayanarijit/scp.xplr",
|
||||
"sayanarijit/qrcp.xplr",
|
||||
"sayanarijit/preview-tabbed.xplr",
|
||||
"dtomvan/ouch.xplr",
|
||||
"sayanarijit/nvim-ctrl.xplr",
|
||||
"Junker/nuke.xplr",
|
||||
"sayanarijit/fzf.xplr",
|
||||
"sayanarijit/dragon.xplr",
|
||||
"sayanarijit/alacritty.xplr",
|
||||
"sayanarijit/tri-pane.xplr",
|
||||
"sayanarijit/map.xplr",
|
||||
},
|
||||
auto_install = true,
|
||||
auto_cleanup = true,
|
||||
})
|
||||
File diff suppressed because it is too large
Load Diff
@ -20,3 +20,52 @@ require("augment-command"):setup({
|
||||
wraparound_file_navigation = false,
|
||||
})
|
||||
require("git"):setup()
|
||||
require("yatline"):setup({
|
||||
show_background = false,
|
||||
section_separator = { open = "", close = "" },
|
||||
part_separator = { open = "", close = "" },
|
||||
inverse_separator = { open = "", close = "" },
|
||||
|
||||
header_line = {
|
||||
left = {
|
||||
section_a = {
|
||||
{ type = "line", custom = false, name = "tabs", params = { "left" } },
|
||||
},
|
||||
section_b = {},
|
||||
section_c = {},
|
||||
},
|
||||
right = {
|
||||
section_a = {
|
||||
{ type = "string", custom = false, name = "date", params = { "%A, %d %B %Y" } },
|
||||
},
|
||||
section_b = {
|
||||
{ type = "string", custom = false, name = "date", params = { "%X" } },
|
||||
},
|
||||
section_c = {},
|
||||
},
|
||||
},
|
||||
|
||||
status_line = {
|
||||
left = {
|
||||
section_a = {},
|
||||
section_b = {},
|
||||
section_c = {
|
||||
{ type = "string", custom = false, name = "hovered_path" },
|
||||
{ type = "coloreds", custom = false, name = "task_states" },
|
||||
},
|
||||
},
|
||||
right = {
|
||||
section_a = {
|
||||
{ type = "string", custom = false, name = "cursor_position" },
|
||||
{ type = "string", custom = false, name = "cursor_percentage" },
|
||||
},
|
||||
section_b = {
|
||||
{ type = "string", custom = false, name = "hovered_file_extension", params = { true } },
|
||||
},
|
||||
section_c = {
|
||||
{ type = "coloreds", custom = false, name = "permissions" },
|
||||
{ type = "coloreds", custom = false, name = "count", params = "true" },
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@ -116,15 +116,15 @@ keymap = [
|
||||
# Tabs
|
||||
{on = [ "t" ], run = "tab_create --current", desc = "Create a new tab using the current path"},
|
||||
|
||||
{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"},
|
||||
# {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"},
|
||||
|
||||
{on = [ "[" ], run = "tab_switch -1 --relative", desc = "Switch to the previous tab"},
|
||||
{on = [ "]" ], run = "tab_switch 1 --relative", desc = "Switch to the next tab"},
|
||||
@ -156,6 +156,8 @@ prepend_keymap = [
|
||||
{on = [ "y" ], run = [ ''' shell 'fd -a "$1" | xclip -selection clipboard' --confirm ''', "yank" ], desc = "Yank the selected files"},
|
||||
{on = [ "y" ], run = [ ''' shell 'fd -a "$1" | wl-copy' --confirm ''', "yank" ], desc = "Yank the selected files"},
|
||||
{on = [ "b", "g" ], run = [ ''' shell 'setbg "$1"' --confirm ''' ], desc = "Set the background image"},
|
||||
# vidir
|
||||
{on = "B", run = [ "escape --visual", "plugin --sync vidir" ], desc = "Bulk rename with vidir"},
|
||||
# chmod
|
||||
{on = [ "c", "m" ], run = "plugin chmod", desc = "Chmod on selected files"},
|
||||
# Archive
|
||||
@ -169,23 +171,29 @@ prepend_keymap = [
|
||||
# Dragon
|
||||
{on = [ "m", "a" ], run = ''' shell 'ripdrag -atk "$@"' --confirm ''', desc = "Drag and drop all"},
|
||||
{on = [ "m", "i" ], run = ''' shell 'ripdrag -tk "$@"' --confirm ''', desc = "Drag and drop individual"},
|
||||
# vidir
|
||||
{on = "B", run = 'vidir "$1"', desc = "Bulk rename"},
|
||||
# Max Preview
|
||||
{on = "T", run = "plugin --sync max-preview", desc = "Maximize or restore preview"},
|
||||
# Hide Preview
|
||||
{on = "<C-t>", run = "plugin --sync hide-preview", desc = "Hide or show preview"},
|
||||
# Relative motions
|
||||
{on = [ "1" ], run = "plugin relative-motions -- 1", desc = "Move in relative steps"},
|
||||
{on = [ "2" ], run = "plugin relative-motions -- 2", desc = "Move in relative steps"},
|
||||
{on = [ "3" ], run = "plugin relative-motions -- 3", desc = "Move in relative steps"},
|
||||
{on = [ "4" ], run = "plugin relative-motions -- 4", desc = "Move in relative steps"},
|
||||
{on = [ "5" ], run = "plugin relative-motions -- 5", desc = "Move in relative steps"},
|
||||
{on = [ "6" ], run = "plugin relative-motions -- 6", desc = "Move in relative steps"},
|
||||
{on = [ "7" ], run = "plugin relative-motions -- 7", desc = "Move in relative steps"},
|
||||
{on = [ "8" ], run = "plugin relative-motions -- 8", desc = "Move in relative steps"},
|
||||
{on = [ "9" ], run = "plugin relative-motions -- 9", desc = "Move in relative steps"},
|
||||
{on = [ "1" ], run = "plugin relative-motions 1", desc = "Move in relative steps"},
|
||||
{on = [ "2" ], run = "plugin relative-motions 2", desc = "Move in relative steps"},
|
||||
{on = [ "3" ], run = "plugin relative-motions 3", desc = "Move in relative steps"},
|
||||
{on = [ "4" ], run = "plugin relative-motions 4", desc = "Move in relative steps"},
|
||||
{on = [ "5" ], run = "plugin relative-motions 5", desc = "Move in relative steps"},
|
||||
{on = [ "6" ], run = "plugin relative-motions 6", desc = "Move in relative steps"},
|
||||
{on = [ "7" ], run = "plugin relative-motions 7", desc = "Move in relative steps"},
|
||||
{on = [ "8" ], run = "plugin relative-motions 8", desc = "Move in relative steps"},
|
||||
{on = [ "9" ], run = "plugin relative-motions 9", desc = "Move in relative steps"},
|
||||
{on = [ "c", "s" ], run = "plugin what-size", desc = "Calc size of selection or cwd"},
|
||||
{on = "M", run = "plugin mount", desc = "Mount"},
|
||||
{on = "F", run = "plugin smart-filter", desc = "Smart filter"},
|
||||
{on = "<C-d>", run = "plugin diff", desc = "Diff the selected with the hovered file"},
|
||||
{on = [ "<C-e>" ], run = "seek 5"},
|
||||
{on = [ "<C-y>" ], run = "seek -5"},
|
||||
{on = [ "z", "h" ], run = "plugin time-travel --args=prev", desc = "Go to previous snapshot"},
|
||||
{on = [ "z", "l" ], run = "plugin time-travel --args=next", desc = "Go to next snapshot"},
|
||||
{on = [ "z", "e" ], run = "plugin time-travel --args=exit", desc = "Exit browsing snapshots"},
|
||||
]
|
||||
|
||||
[tasks]
|
||||
|
||||
@ -1,23 +1,8 @@
|
||||
[[plugin.deps]]
|
||||
use = "AnirudhG07/nbpreview"
|
||||
rev = "bc573d5"
|
||||
hash = "ab61298c387a63e781a87129f533883b"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "Reledia/glow"
|
||||
rev = "2da96e3"
|
||||
hash = "f9ee1436e3b853508d87f7d49dce56e6"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "Reledia/hexyl"
|
||||
rev = "016a09b"
|
||||
hash = "50da29476e744dba37d77fb209328fd1"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "Sonico98/exifaudio"
|
||||
rev = "7ff7141"
|
||||
hash = "666ccba55119fba4c25b8ad354b2855c"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "dedukun/relative-motions"
|
||||
rev = "ce2e890"
|
||||
@ -28,11 +13,6 @@ use = "hankertrix/augment-command"
|
||||
rev = "91ba6c5"
|
||||
hash = "6ac13898ec80c623e2d9ea90b947c86a"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "imsi32/yatline"
|
||||
rev = "2ecf715"
|
||||
hash = "38e2ea4703ea606d4eef574e8e8b8fd7"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "kirasok/torrent-preview"
|
||||
rev = "4ca5996"
|
||||
@ -50,18 +30,68 @@ hash = "6e789212eb41d937bab04877ca361099"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "yazi-rs/plugins:git"
|
||||
rev = "4b027c7"
|
||||
rev = "864a021"
|
||||
hash = "e0ada736ea676c2bbb3ec705a49526ef"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "yazi-rs/plugins:chmod"
|
||||
rev = "4b027c7"
|
||||
rev = "864a021"
|
||||
hash = "2f1053f89d1a301a648ab181d0948e38"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "yazi-rs/plugins:full-border"
|
||||
rev = "4b027c7"
|
||||
rev = "864a021"
|
||||
hash = "1f3dad061209081a6b04dd6ff2cb06c7"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "yazi-rs/plugins:mount"
|
||||
rev = "864a021"
|
||||
hash = "dd97eede8e20e59cd2604e8006e470e2"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "yazi-rs/plugins:smart-filter"
|
||||
rev = "864a021"
|
||||
hash = "f0c4b41b5d19a3144958383333eff6e7"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "yazi-rs/plugins:mime-ext"
|
||||
rev = "864a021"
|
||||
hash = "5e24c167e9ae9a203a48f2a438b8c705"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "yazi-rs/plugins:diff"
|
||||
rev = "864a021"
|
||||
hash = "7a08e303167d5b655c06da6d570f0333"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "AnirudhG07/rich-preview"
|
||||
rev = "fdcf373"
|
||||
hash = "bd1737dd44b202f412122e6a3b378d4c"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "macydnah/office"
|
||||
rev = "d1e3e51"
|
||||
hash = "35241f7d85abc5a0d2441020bc597ceb"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "boydaihungst/mediainfo"
|
||||
rev = "9629b1e"
|
||||
hash = "5204b4e2bd238c40fa66cf0a0191f084"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "iynaix/time-travel"
|
||||
rev = "7e0179e"
|
||||
hash = "69967963fba96295a07b68354fc91ea9"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "imsi32/yatline"
|
||||
rev = "2ecf715"
|
||||
hash = "38e2ea4703ea606d4eef574e8e8b8fd7"
|
||||
|
||||
[[plugin.deps]]
|
||||
use = "kristoferssolo/vidir"
|
||||
rev = "54ef22b"
|
||||
hash = "e3fe41820f43c3511be9846cc7bdf638"
|
||||
|
||||
[flavor]
|
||||
deps = []
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 Sonico98
|
||||
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
|
||||
28
config/yazi/plugins/diff.yazi/README.md
Normal file
28
config/yazi/plugins/diff.yazi/README.md
Normal file
@ -0,0 +1,28 @@
|
||||
# diff.yazi
|
||||
|
||||
Diff the selected file with the hovered file, create a living patch, and copy it to the clipboard.
|
||||
|
||||
https://github.com/yazi-rs/plugins/assets/17523360/eff5e949-386a-44ea-82f9-4cb4a2c37aad
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
ya pack -a yazi-rs/plugins:diff
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Add this to your `~/.config/yazi/keymap.toml`:
|
||||
|
||||
```toml
|
||||
[[manager.prepend_keymap]]
|
||||
on = "<C-d>"
|
||||
run = "plugin diff"
|
||||
desc = "Diff the selected with the hovered file"
|
||||
```
|
||||
|
||||
Make sure the <kbd>C</kbd> + <kbd>d</kbd> key is not used elsewhere.
|
||||
|
||||
## License
|
||||
|
||||
This plugin is MIT-licensed. For more information check the [LICENSE](LICENSE) file.
|
||||
41
config/yazi/plugins/diff.yazi/main.lua
Normal file
41
config/yazi/plugins/diff.yazi/main.lua
Normal file
@ -0,0 +1,41 @@
|
||||
--- @since 25.2.7
|
||||
|
||||
local function info(content)
|
||||
return ya.notify {
|
||||
title = "Diff",
|
||||
content = content,
|
||||
timeout = 5,
|
||||
}
|
||||
end
|
||||
|
||||
local selected_url = ya.sync(function()
|
||||
for _, u in pairs(cx.active.selected) do
|
||||
return u
|
||||
end
|
||||
end)
|
||||
|
||||
local hovered_url = ya.sync(function()
|
||||
local h = cx.active.current.hovered
|
||||
return h and h.url
|
||||
end)
|
||||
|
||||
return {
|
||||
entry = function()
|
||||
local a, b = selected_url(), hovered_url()
|
||||
if not a then
|
||||
return info("No file selected")
|
||||
elseif not b then
|
||||
return info("No file hovered")
|
||||
end
|
||||
|
||||
local output, err = Command("diff"):arg("-Naur"):arg(tostring(a)):arg(tostring(b)):output()
|
||||
if not output then
|
||||
return info("Failed to run diff, error: " .. err)
|
||||
elseif output.stdout == "" then
|
||||
return info("No differences found")
|
||||
end
|
||||
|
||||
ya.clipboard(output.stdout)
|
||||
info("Diff copied to clipboard")
|
||||
end,
|
||||
}
|
||||
@ -1,38 +0,0 @@
|
||||
# exifaudio.yazi
|
||||
|
||||
Preview audio metadata and cover on [Yazi](https://github.com/sxyazi/yazi).
|
||||
|
||||

|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
# Automatically with yazi 0.3.0
|
||||
ya pack -a "Sonico98/exifaudio"
|
||||
|
||||
# Or manually under:
|
||||
# Linux/macOS
|
||||
git clone https://github.com/Sonico98/exifaudio.yazi.git ~/.config/yazi/plugins/exifaudio.yazi
|
||||
|
||||
# Windows
|
||||
git clone https://github.com/Sonico98/exifaudio.yazi.git %AppData%\yazi\config\plugins\exifaudio.yazi
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Add the following to your `yazi.toml`:
|
||||
|
||||
```toml
|
||||
[plugin]
|
||||
prepend_previewers = [
|
||||
{ mime = "audio/*", run = "exifaudio"}
|
||||
]
|
||||
```
|
||||
|
||||
Make sure you have [exiftool](https://exiftool.org/) installed and in your `PATH`.
|
||||
|
||||
Optional: if you have [mediainfo](https://mediaarea.net/en/MediaInfo) installed and in your `PATH`, it will be used instead for more accurate metadata. Exiftool is still required to display the cover.
|
||||
|
||||
## Thanks
|
||||
|
||||
Thanks to [sxyazi](https://github.com/sxyazi) for the PDF previewer code, on which this previewer is based on.
|
||||
@ -1,237 +0,0 @@
|
||||
local M = {}
|
||||
|
||||
function GetPath(str)
|
||||
local sep = '/'
|
||||
if ya.target_family() == "windows" then
|
||||
sep = '\\'
|
||||
end
|
||||
return str:match("(.*"..sep..")")
|
||||
end
|
||||
|
||||
function Exiftool(...)
|
||||
local child = Command("exiftool")
|
||||
:args({
|
||||
"-q", "-q", "-S", "-Title", "-SortName",
|
||||
"-TitleSort", "-TitleSortOrder", "-Artist",
|
||||
"-SortArtist", "-ArtistSort", "-PerformerSortOrder",
|
||||
"-Album", "-SortAlbum", "-AlbumSort", "-AlbumSortOrder",
|
||||
"-AlbumArtist", "-SortAlbumArtist", "-AlbumArtistSort",
|
||||
"-AlbumArtistSortOrder", "-Genre", "-TrackNumber",
|
||||
"-Year", "-Duration", "-SampleRate",
|
||||
"-AudioSampleRate", "-AudioBitrate", "-AvgBitrate",
|
||||
"-Channels", "-AudioChannels", tostring(...),
|
||||
})
|
||||
:stdout(Command.PIPED)
|
||||
:stderr(Command.NULL)
|
||||
:spawn()
|
||||
return child
|
||||
end
|
||||
|
||||
function Mediainfo(...)
|
||||
local file, cache_dir = ...
|
||||
local template = cache_dir.."mediainfo.txt"
|
||||
local child = Command("mediainfo")
|
||||
:args({
|
||||
"--Output=file://"..template, tostring(file)
|
||||
})
|
||||
:stdout(Command.PIPED)
|
||||
:stderr(Command.NULL)
|
||||
:spawn()
|
||||
return child
|
||||
end
|
||||
|
||||
function M:peek(job)
|
||||
local cache = ya.file_cache(job)
|
||||
if not cache then
|
||||
return
|
||||
end
|
||||
|
||||
-- Get cache dir to find the mediainfo template file
|
||||
local cache_dir = GetPath(tostring(cache))
|
||||
|
||||
-- Try mediainfo, otherwise use exiftool
|
||||
local status, child = pcall(Mediainfo, job.file.url, cache_dir)
|
||||
if not status or child == nil then
|
||||
status, child = pcall(Exiftool, job.file.url)
|
||||
if not status or child == nil then
|
||||
local error = ui.Line { ui.Span("Make sure exiftool is installed and in your PATH") }
|
||||
-- TODO)) Remove legacy method when v0.4 gets released
|
||||
local function display_error_legacy()
|
||||
local p = ui.Paragraph(job.area, { error }):wrap(ui.Paragraph.WRAP)
|
||||
ya.preview_widgets(job, { p })
|
||||
end
|
||||
local function display_error()
|
||||
local p = ui.Text(error):area(job.area):wrap(ui.Text.WRAP)
|
||||
ya.preview_widgets(job, { p })
|
||||
end
|
||||
if pcall(display_error) then else pcall(display_error_legacy) end
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local limit = job.area.h
|
||||
local i, metadata = 0, {}
|
||||
repeat
|
||||
local next, event = child:read_line()
|
||||
if event == 1 then
|
||||
return self:fallback_to_builtin()
|
||||
elseif event ~= 0 then
|
||||
break
|
||||
end
|
||||
|
||||
i = i + 1
|
||||
if i > job.skip then
|
||||
local m_title, m_tag = Prettify(next)
|
||||
if m_title ~= "" and m_tag ~= "" then
|
||||
local ti = ui.Span(m_title):bold()
|
||||
local ta = ui.Span(m_tag)
|
||||
table.insert(metadata, ui.Line{ti, ta})
|
||||
table.insert(metadata, ui.Line{})
|
||||
end
|
||||
end
|
||||
until i >= job.skip + limit
|
||||
|
||||
-- TODO)) Remove legacy method when v0.4 gets released
|
||||
local function display_metadata_legacy()
|
||||
local p = ui.Paragraph(job.area, metadata):wrap(ui.Paragraph.WRAP)
|
||||
ya.preview_widgets(job, { p })
|
||||
end
|
||||
local function display_metadata()
|
||||
local p = ui.Text(metadata):area(job.area):wrap(ui.Text.WRAP)
|
||||
ya.preview_widgets(job, { p })
|
||||
end
|
||||
if pcall(display_metadata) then else pcall(display_metadata_legacy) end
|
||||
|
||||
local cover_width = job.area.w / 2 - 5
|
||||
local cover_height = (job.area.h / 4) + 3
|
||||
|
||||
local bottom_right = ui.Rect {
|
||||
x = job.area.right - cover_width,
|
||||
y = job.area.bottom - cover_height,
|
||||
w = cover_width,
|
||||
h = cover_height,
|
||||
}
|
||||
|
||||
if self:preload(job) == 1 then
|
||||
ya.image_show(cache, bottom_right)
|
||||
end
|
||||
end
|
||||
|
||||
function Prettify(metadata)
|
||||
local substitutions = {
|
||||
Sortname = "Sort Title:",
|
||||
SortName = "Sort Title:",
|
||||
TitleSort = "Sort Title:",
|
||||
TitleSortOrder = "Sort Title:",
|
||||
ArtistSort = "Sort Artist:",
|
||||
SortArtist = "Sort Artist:",
|
||||
Artist = "Artist:",
|
||||
ARTIST = "Artist:",
|
||||
PerformerSortOrder = "Sort Artist:",
|
||||
SortAlbumArtist = "Sort Album Artist:",
|
||||
AlbumArtistSortOrder = "Sort Album Artist:",
|
||||
AlbumArtistSort = "Sort Album Artist:",
|
||||
AlbumSortOrder = "Sort Album:",
|
||||
AlbumSort = "Sort Album:",
|
||||
SortAlbum = "Sort Album:",
|
||||
Album = "Album:",
|
||||
ALBUM = "Album:",
|
||||
AlbumArtist = "Album Artist:",
|
||||
Genre = "Genre:",
|
||||
GENRE = "Genre:",
|
||||
TrackNumber = "Track Number:",
|
||||
Year = "Year:",
|
||||
Duration = "Duration:",
|
||||
AudioBitrate = "Bitrate:",
|
||||
AvgBitrate = "Average Bitrate:",
|
||||
AudioSampleRate = "Sample Rate:",
|
||||
SampleRate = "Sample Rate:",
|
||||
AudioChannels = "Channels:"
|
||||
}
|
||||
|
||||
for k, v in pairs(substitutions) do
|
||||
metadata = metadata:gsub(tostring(k)..":", v, 1)
|
||||
end
|
||||
|
||||
-- Separate the tag title from the tag data
|
||||
local t={}
|
||||
for str in string.gmatch(metadata , "([^"..":".."]+)") do
|
||||
if str ~= "\n" then
|
||||
table.insert(t, str)
|
||||
else
|
||||
table.insert(t, nil)
|
||||
end
|
||||
end
|
||||
|
||||
-- Add back semicolon to title, rejoin tag data if it happened to contain a semicolon
|
||||
local title, tag_data = "", ""
|
||||
if t[1] ~= nil then
|
||||
title, tag_data = t[1]..":", table.concat(t, ":", 2)
|
||||
end
|
||||
return title, tag_data
|
||||
|
||||
end
|
||||
|
||||
function M:seek(job)
|
||||
local h = cx.active.current.hovered
|
||||
if h and h.url == job.file.url then
|
||||
ya.manager_emit("peek", {
|
||||
tostring(math.max(0, cx.active.preview.skip + job.units)),
|
||||
only_if = tostring(job.file.url),
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function M:preload(job)
|
||||
local cache = ya.file_cache(job)
|
||||
if not cache or fs.cha(cache) then
|
||||
if not ya.__250127 then -- TODO: remove this
|
||||
return 1
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local mediainfo_template = 'General;"\
|
||||
$if(%Track%,Title: %Track%,)\
|
||||
$if(%Track/Sort%,Sort Title: %Track/Sort%,)\
|
||||
$if(%Title/Sort%,Sort Title: %Title/Sort%,)\
|
||||
$if(%TITLESORT%,Sort Title: %TITLESORT%,)\
|
||||
$if(%Performer%,Artist: %Performer%,)\
|
||||
$if(%Performer/Sort%,Sort Artist: %Performer/Sort%,)\
|
||||
$if(%ARTISTSORT%,Sort Artist: %ARTISTSORT%,)\
|
||||
$if(%Album%,Album: %Album%,)\
|
||||
$if(%Album/Sort%,Sort Album: %Album/Sort%)\
|
||||
$if(%ALBUMSORT%,Sort Album: %ALBUMSORT%)\
|
||||
$if(%Album/Performer%,Album Artist: %Album/Performer%)\
|
||||
$if(%Album/Performer/Sort%,Sort Album Artist: %Album/Performer/Sort%)\
|
||||
$if(%Genre%,Genre: %Genre%)\
|
||||
$if(%Track/Position%,Track Number: %Track/Position%)\
|
||||
$if(%Recorded_Date%,Year: %Recorded_Date%)\
|
||||
$if(%Duration/String%,Duration: %Duration/String%)\
|
||||
$if(%BitRate/String%,Bitrate: %BitRate/String%)\
|
||||
"\
|
||||
Audio;"Sample Rate: %SamplingRate%\
|
||||
Channels: %Channel(s)%"\
|
||||
'
|
||||
|
||||
-- Write the mediainfo template file into yazi's cache dir
|
||||
local cache_dir = GetPath(tostring(cache))
|
||||
fs.write(Url(cache_dir.."mediainfo.txt"), mediainfo_template)
|
||||
|
||||
local output = Command("exiftool")
|
||||
:args({ "-b", "-CoverArt", "-Picture", tostring(job.file.url) })
|
||||
:stdout(Command.PIPED)
|
||||
:stderr(Command.PIPED)
|
||||
:output()
|
||||
|
||||
if not output then
|
||||
if not ya.__250127 then -- TODO: remove this
|
||||
return 0
|
||||
end
|
||||
return true, Err("Couldn't extract cover art, error: %s", err)
|
||||
end
|
||||
|
||||
return fs.write(cache, output.stdout) and true or false
|
||||
end
|
||||
|
||||
return M
|
||||
@ -1,7 +0,0 @@
|
||||
Copyright © 2024 Reledia <reledia@prontonmail.com>
|
||||
|
||||
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.
|
||||
@ -1,30 +0,0 @@
|
||||
# glow.yazi
|
||||
|
||||
Plugin for [Yazi](https://github.com/sxyazi/yazi) to preview markdown files with [glow](https://github.com/charmbracelet/glow). To install, run the below mentioned command:
|
||||
|
||||
```bash
|
||||
ya pack -a Reledia/glow
|
||||
```
|
||||
|
||||
then include it in your `yazi.toml` to use:
|
||||
|
||||
```toml
|
||||
[plugin]
|
||||
prepend_previewers = [
|
||||
{ name = "*.md", run = "glow" },
|
||||
]
|
||||
```
|
||||
|
||||
Make sure you have [glow](https://github.com/charmbracelet/glow) installed, and can be found in `PATH`.
|
||||
|
||||
## Feature
|
||||
|
||||
+ You can modify line wrap in `main.lua`, the current value is 55.
|
||||
+ You can press `ctrl+e` to scroll up and `ctrl+y` to scroll down the readme file in preview panel in yazi: (add this to `keymap.toml`)
|
||||
```toml
|
||||
prepend_keymap = [
|
||||
# glow.yazi
|
||||
{ on = ["<C-e>"], run = "seek 5" },
|
||||
{ on = ["<C-y>"], run = "seek -5" },
|
||||
]
|
||||
```
|
||||
@ -1,64 +0,0 @@
|
||||
local M = {}
|
||||
|
||||
function M:peek(job)
|
||||
-- Set a fixed width of 50 characters for the preview
|
||||
local preview_width = 55
|
||||
|
||||
local child = Command("glow")
|
||||
:args({
|
||||
"--style",
|
||||
"dark",
|
||||
"--width",
|
||||
tostring(preview_width), -- Use fixed width instead of job.area.w
|
||||
tostring(job.file.url),
|
||||
})
|
||||
:env("CLICOLOR_FORCE", "1")
|
||||
:stdout(Command.PIPED)
|
||||
:stderr(Command.PIPED)
|
||||
:spawn()
|
||||
|
||||
if not child then
|
||||
return require("code").peek(job)
|
||||
end
|
||||
|
||||
local limit = job.area.h
|
||||
local i, lines = 0, ""
|
||||
repeat
|
||||
local next, event = child:read_line()
|
||||
if event == 1 then
|
||||
return require("code").peek(job)
|
||||
elseif event ~= 0 then
|
||||
break
|
||||
end
|
||||
|
||||
i = i + 1
|
||||
if i > job.skip then
|
||||
lines = lines .. next
|
||||
end
|
||||
until i >= job.skip + limit
|
||||
|
||||
child:start_kill()
|
||||
if job.skip > 0 and i < job.skip + limit then
|
||||
ya.mgr_emit("peek", {
|
||||
tostring(math.max(0, i - limit)),
|
||||
only_if = job.file.url,
|
||||
upper_bound = true
|
||||
})
|
||||
else
|
||||
lines = lines:gsub("\t", string.rep(" ", rt.preview.tab_size))
|
||||
ya.preview_widgets(job, { ui.Text.parse(lines):area(job.area) })
|
||||
end
|
||||
end
|
||||
|
||||
function M:seek(job)
|
||||
local h = cx.active.current.hovered
|
||||
if not h or h.url ~= job.file.url then
|
||||
return
|
||||
end
|
||||
ya.mgr_emit('peek', {
|
||||
math.max(0, cx.active.preview.skip + job.units),
|
||||
only_if = job.file.url,
|
||||
})
|
||||
end
|
||||
|
||||
return M
|
||||
19
config/yazi/plugins/mediainfo.yazi/LICENSE
Normal file
19
config/yazi/plugins/mediainfo.yazi/LICENSE
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2024 Lauri Niskanen
|
||||
|
||||
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.
|
||||
98
config/yazi/plugins/mediainfo.yazi/README.md
Normal file
98
config/yazi/plugins/mediainfo.yazi/README.md
Normal file
@ -0,0 +1,98 @@
|
||||
# mediainfo.yazi
|
||||
|
||||
<!--toc:start-->
|
||||
|
||||
- [mediainfo.yazi](#mediainfo-yazi)
|
||||
- [Installation](#installation)
|
||||
<!--toc:end-->
|
||||
|
||||
This is a Yazi plugin for previewing media files. The preview shows thumbnail
|
||||
using `ffmpeg` if available and media metadata using `mediainfo`.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Minimum version: yazi v25.2.7.
|
||||
|
||||
## Preview
|
||||
|
||||
- Video
|
||||
|
||||

|
||||
|
||||
- Audio file with cover
|
||||
|
||||

|
||||
|
||||
- Images
|
||||
|
||||

|
||||
|
||||
- Subtitle
|
||||
|
||||

|
||||
|
||||
- SVG+XML file doesn't have useful information, so it only show the image preview.
|
||||
- There are more extensions which are supported by mediainfo. Just add file's MIME type to `previewers`, `preloaders`.
|
||||
|
||||
## Installation
|
||||
|
||||
Install mediainfo CLI:
|
||||
|
||||
- [https://mediaarea.net/en/MediaInfo/Download](https://mediaarea.net/en/MediaInfo/Download)
|
||||
- Run this command in terminal to check if it's installed correctly:
|
||||
|
||||
```bash
|
||||
mediainfo --version
|
||||
```
|
||||
|
||||
- If it output `Not found` then add it to your PATH environment variable. It's better to ask ChatGPT to help you (Prompt: `Add MediaInfo CLI to PATH environment variable in Windows`).
|
||||
|
||||
Install + config this plugin:
|
||||
|
||||
> [!IMPORTANT]
|
||||
> `mediainfo` use video, image, svg, magick built-in plugins behind the scene to render preview image, song cover.
|
||||
> So you can remove those 3 plugins from `preloaders` and `previewers` sections in `yazi.toml`.
|
||||
|
||||
If you have cache problem, run this cmd, and follow the tips: `yazi --clear-cache`
|
||||
|
||||
```bash
|
||||
ya pack -a boydaihungst/mediainfo
|
||||
```
|
||||
|
||||
Config folder for each OS: https://yazi-rs.github.io/docs/configuration/overview
|
||||
Create `.../yazi/yazi.toml` and add:
|
||||
|
||||
```toml
|
||||
[plugin]
|
||||
prepend_preloaders = [
|
||||
# Replace magick, image, video with mediainfo
|
||||
{ mime = "{audio,video,image}/*", run = "mediainfo" },
|
||||
{ mime = "application/subrip", run = "mediainfo" },
|
||||
]
|
||||
prepend_previewers = [
|
||||
# Replace magick, image, video with mediainfo
|
||||
{ mime = "{audio,video,image}/*", run = "mediainfo"},
|
||||
{ mime = "application/subrip", run = "mediainfo" },
|
||||
]
|
||||
# There are more extensions which are supported by mediainfo.
|
||||
# Just add file's MIME type to `previewers`, `preloaders` above.
|
||||
# https://mediaarea.net/en/MediaInfo/Support/Formats
|
||||
|
||||
```
|
||||
|
||||
## Custom theme
|
||||
|
||||
Using the same style with spotter
|
||||
Read more: https://github.com/sxyazi/yazi/pull/2391
|
||||
|
||||
Edit or add `yazi/theme.toml`:
|
||||
|
||||
```toml
|
||||
[spot]
|
||||
# Section header style.
|
||||
# Example: Video, Text, Image,... with green color in preview images above
|
||||
title = { fg = "green" }
|
||||
|
||||
# Value style.
|
||||
# Example: `Format: FLAC` with blue color in preview images above
|
||||
tbl_col = { fg = "blue" }
|
||||
```
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 186 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 286 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 261 KiB |
237
config/yazi/plugins/mediainfo.yazi/main.lua
Normal file
237
config/yazi/plugins/mediainfo.yazi/main.lua
Normal file
@ -0,0 +1,237 @@
|
||||
--- @since 25.2.7
|
||||
|
||||
local skip_labels = {
|
||||
["Complete name"] = true,
|
||||
["CompleteName_Last"] = true,
|
||||
["Unique ID"] = true,
|
||||
["File size"] = true,
|
||||
["Format/Info"] = true,
|
||||
["Codec ID/Info"] = true,
|
||||
["MD5 of the unencoded content"] = true,
|
||||
}
|
||||
|
||||
local magick_image_mimes = {
|
||||
avif = true,
|
||||
hei = true,
|
||||
heic = true,
|
||||
heif = true,
|
||||
["heif-sequence"] = true,
|
||||
["heic-sequence"] = true,
|
||||
jxl = true,
|
||||
xml = true,
|
||||
["svg+xml"] = true,
|
||||
}
|
||||
|
||||
local M = {}
|
||||
local suffix = "_mediainfo"
|
||||
|
||||
local function read_mediainfo_cached_file(file_path)
|
||||
-- Open the file in read mode
|
||||
local file = io.open(file_path, "r")
|
||||
|
||||
if file then
|
||||
-- Read the entire file content
|
||||
local content = file:read("*all")
|
||||
file:close()
|
||||
return content
|
||||
end
|
||||
end
|
||||
|
||||
function M:peek(job)
|
||||
local start = os.clock()
|
||||
local cache_img_url_no_skip = ya.file_cache({ file = job.file, skip = 0 })
|
||||
if not job.mime then
|
||||
return
|
||||
end
|
||||
local is_video = string.find(job.mime, "^video/")
|
||||
local is_audio = string.find(job.mime, "^audio/")
|
||||
local is_image = string.find(job.mime, "^image/")
|
||||
local cache_img_url = (is_audio or is_image) and cache_img_url_no_skip
|
||||
|
||||
if is_video then
|
||||
cache_img_url = ya.file_cache({ file = job.file, skip = math.min(90, job.skip) })
|
||||
end
|
||||
local ok, err = self:preload(job)
|
||||
if not ok or err then
|
||||
return
|
||||
end
|
||||
local cache_mediainfo_path = tostring(cache_img_url_no_skip) .. suffix
|
||||
ya.sleep(math.max(0, (rt and rt.preview or PREVIEW).image_delay / 1000 + start - os.clock()))
|
||||
local output = read_mediainfo_cached_file(cache_mediainfo_path)
|
||||
|
||||
local lines = {}
|
||||
local max_lines = math.floor(job.area.h / 2)
|
||||
local last_line = 0
|
||||
local is_wrap = rt and rt.preview and rt.preview.wrap == "yes"
|
||||
|
||||
if output then
|
||||
local max_width = math.max(1, job.area.w)
|
||||
if output:match("^Error:") then
|
||||
job.args.force_reload_mediainfo = true
|
||||
local _ok, _err = self:preload(job)
|
||||
if not _ok or _err then
|
||||
return
|
||||
end
|
||||
output = read_mediainfo_cached_file(cache_mediainfo_path)
|
||||
end
|
||||
|
||||
for str in output:gsub("\n+$", ""):gmatch("[^\n]*") do
|
||||
local label, value = str:match("(.*[^ ]) +: (.*)")
|
||||
local line
|
||||
if label then
|
||||
if not skip_labels[label] then
|
||||
line = ui.Line({
|
||||
ui.Span(label .. ": "):style(ui.Style():fg("reset"):bold()),
|
||||
ui.Span(value):style((th and th.spot and th.spot.tbl_col) or ui.Style():fg("blue")),
|
||||
})
|
||||
end
|
||||
elseif str ~= "General" then
|
||||
line = ui.Line({ ui.Span(str):style((th and th.spot and th.spot.title) or ui.Style():fg("green")) })
|
||||
end
|
||||
|
||||
if line then
|
||||
local line_height = math.max(1, is_wrap and math.ceil(line:width() / max_width) or 1)
|
||||
if (last_line + line_height) > job.skip then
|
||||
table.insert(lines, line)
|
||||
end
|
||||
if (last_line + line_height) >= job.skip + max_lines then
|
||||
last_line = job.skip + max_lines
|
||||
break
|
||||
end
|
||||
last_line = last_line + line_height
|
||||
end
|
||||
end
|
||||
end
|
||||
local mediainfo_height = math.min(max_lines, last_line)
|
||||
|
||||
if (job.skip > 0 and #lines == 0) and (not is_video or (is_video and job.skip >= 90)) then
|
||||
ya.manager_emit("peek", { math.max(0, job.skip - max_lines), only_if = job.file.url, upper_bound = false })
|
||||
return
|
||||
end
|
||||
local rendered_img_rect = cache_img_url
|
||||
and ya.image_show(
|
||||
cache_img_url,
|
||||
ui.Rect({
|
||||
x = job.area.x,
|
||||
y = job.area.y,
|
||||
w = job.area.w,
|
||||
h = job.area.h - mediainfo_height,
|
||||
})
|
||||
)
|
||||
or nil
|
||||
local image_height = rendered_img_rect and rendered_img_rect.h or 0
|
||||
|
||||
ya.preview_widgets(job, {
|
||||
ui.Text(lines)
|
||||
:area(ui.Rect({
|
||||
x = job.area.x,
|
||||
y = job.area.y + image_height,
|
||||
w = job.area.w,
|
||||
h = job.area.h - image_height,
|
||||
}))
|
||||
:wrap(is_wrap and ui.Text.WRAP or ui.Text.WRAP_NO),
|
||||
})
|
||||
end
|
||||
|
||||
function M:seek(job)
|
||||
local h = cx.active.current.hovered
|
||||
if h and h.url == job.file.url then
|
||||
local step = ya.clamp(-10, job.units, 10)
|
||||
ya.manager_emit("peek", {
|
||||
math.max(0, cx.active.preview.skip + job.units),
|
||||
only_if = job.file.url,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function M:preload(job)
|
||||
local cache_img_url_no_skip = ya.file_cache({ file = job.file, skip = 0 })
|
||||
local cache_img_url_no_skip_cha = cache_img_url_no_skip and fs.cha(cache_img_url_no_skip)
|
||||
if not cache_img_url_no_skip then
|
||||
return true
|
||||
end
|
||||
local cache_mediainfo_url = Url(tostring(cache_img_url_no_skip) .. suffix)
|
||||
local err_msg = ""
|
||||
-- seekable mimetype
|
||||
if job.mime and string.find(job.mime, "^video/") then
|
||||
local video = require("video")
|
||||
local cache_img_status, video_preload_err = video:preload({ file = job.file, skip = math.min(90, job.skip) })
|
||||
if not cache_img_status and video_preload_err then
|
||||
err_msg = err_msg
|
||||
.. string.format("Failed to start `%s`, Do you have `%s` installed?\n", "ffmpeg", "ffmpeg")
|
||||
end
|
||||
end
|
||||
-- none-seekable mimetype
|
||||
if cache_img_url_no_skip and (not cache_img_url_no_skip_cha or cache_img_url_no_skip_cha.len <= 0) then
|
||||
-- audio
|
||||
if job.mime and string.find(job.mime, "^audio/") then
|
||||
local qv = 31 - math.floor((rt and rt.preview or PREVIEW).image_quality * 0.3)
|
||||
local status, _ = Command("ffmpeg"):args({
|
||||
"-v",
|
||||
"quiet",
|
||||
"-threads",
|
||||
1,
|
||||
"-hwaccel",
|
||||
"auto",
|
||||
"-skip_frame",
|
||||
"nokey",
|
||||
"-an",
|
||||
"-sn",
|
||||
"-dn",
|
||||
"-i",
|
||||
tostring(job.file.url),
|
||||
"-vframes",
|
||||
1,
|
||||
"-q:v",
|
||||
qv,
|
||||
"-vf",
|
||||
string.format(
|
||||
"scale=-1:'min(%d,ih)':flags=fast_bilinear",
|
||||
(rt and rt.preview or PREVIEW).max_height / 2
|
||||
),
|
||||
"-f",
|
||||
"image2",
|
||||
"-y",
|
||||
tostring(cache_img_url_no_skip),
|
||||
}):status()
|
||||
|
||||
-- NOTE: Ignore this err msg because some audio types doesn't have cover image
|
||||
--
|
||||
-- if not status or not status.success then
|
||||
-- err_msg = err_msg
|
||||
-- .. string.format("Failed to start `%s`, Do you have `%s` installed?\n", "ffmpeg", "ffmpeg")
|
||||
-- end
|
||||
|
||||
-- image
|
||||
elseif job.mime and string.find(job.mime, "^image/") then
|
||||
local svg_plugin_ok, svg_plugin = pcall(require, "svg")
|
||||
local mime = job.mime:match(".*/(.*)$")
|
||||
|
||||
local image = magick_image_mimes[mime]
|
||||
and ((mime == "svg+xml" and svg_plugin_ok) and svg_plugin or require("magick"))
|
||||
or require("image")
|
||||
local no_skip_job = { skip = 0, file = job.file }
|
||||
-- image = ya.dict_merge(image, no_skip_job)
|
||||
local cache_img_status, image_preload_err = image:preload(no_skip_job)
|
||||
if not cache_img_status and image_preload_err then
|
||||
err_msg = err_msg .. "Failed to cache image , check cache folder permissions\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local cache_mediainfo_cha = fs.cha(cache_mediainfo_url)
|
||||
if cache_mediainfo_cha and not job.args.force_reload_mediainfo then
|
||||
return true
|
||||
end
|
||||
local cmd = "mediainfo"
|
||||
local output, err = Command(cmd):args({ tostring(job.file.url) }):stdout(Command.PIPED):output()
|
||||
if err then
|
||||
err_msg = err_msg .. string.format("Failed to start `%s`, Do you have `%s` installed?\n", cmd, cmd)
|
||||
end
|
||||
return fs.write(
|
||||
cache_mediainfo_url,
|
||||
(err_msg ~= "" and "Error: " .. err_msg or "") .. (output and output.stdout or "")
|
||||
)
|
||||
end
|
||||
|
||||
return M
|
||||
21
config/yazi/plugins/mime-ext.yazi/LICENSE
Normal file
21
config/yazi/plugins/mime-ext.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.
|
||||
56
config/yazi/plugins/mime-ext.yazi/README.md
Normal file
56
config/yazi/plugins/mime-ext.yazi/README.md
Normal file
@ -0,0 +1,56 @@
|
||||
# mime-ext.yazi
|
||||
|
||||
A mime-type provider based on a file extension database, replacing the [builtin `file(1)`](https://github.com/sxyazi/yazi/blob/main/yazi-plugin/preset/plugins/mime.lua) to speed up mime-type retrieval at the expense of accuracy.
|
||||
|
||||
See https://yazi-rs.github.io/docs/tips#make-yazi-even-faster for more information.
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
ya pack -a yazi-rs/plugins:mime-ext
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Add this to your `~/.config/yazi/yazi.toml`:
|
||||
|
||||
```toml
|
||||
[[plugin.prepend_fetchers]]
|
||||
id = "mime"
|
||||
name = "*"
|
||||
run = "mime-ext"
|
||||
prio = "high"
|
||||
```
|
||||
|
||||
## Advanced
|
||||
|
||||
You can also customize it in your `~/.config/yazi/init.lua` with:
|
||||
|
||||
```lua
|
||||
require("mime-ext"):setup {
|
||||
-- Expand the existing filename database (lowercase), for example:
|
||||
with_files = {
|
||||
makefile = "text/makefile",
|
||||
-- ...
|
||||
},
|
||||
|
||||
-- Expand the existing extension database (lowercase), for example:
|
||||
with_exts = {
|
||||
mk = "text/makefile",
|
||||
-- ...
|
||||
},
|
||||
|
||||
-- If the mime-type is not in both filename and extension databases,
|
||||
-- then fallback to Yazi's preset `mime` plugin, which uses `file(1)`
|
||||
fallback_file1 = false,
|
||||
}
|
||||
```
|
||||
|
||||
## TODO
|
||||
|
||||
- Add more file types (PRs welcome!).
|
||||
- Compress mime-type tables.
|
||||
|
||||
## License
|
||||
|
||||
This plugin is MIT-licensed. For more information check the [LICENSE](LICENSE) file.
|
||||
1126
config/yazi/plugins/mime-ext.yazi/main.lua
Normal file
1126
config/yazi/plugins/mime-ext.yazi/main.lua
Normal file
File diff suppressed because it is too large
Load Diff
21
config/yazi/plugins/mount.yazi/LICENSE
Normal file
21
config/yazi/plugins/mount.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.
|
||||
51
config/yazi/plugins/mount.yazi/README.md
Normal file
51
config/yazi/plugins/mount.yazi/README.md
Normal file
@ -0,0 +1,51 @@
|
||||
# mount.yazi
|
||||
|
||||
> [!NOTE]
|
||||
> Yazi v25.2.7 or later is required for this plugin to work.
|
||||
|
||||
A mount manager for Yazi, providing disk mount, unmount, and eject functionality.
|
||||
|
||||
Supported platforms:
|
||||
|
||||
- Linux with [`udisksctl`](https://github.com/storaged-project/udisks) and [`lsblk`](https://github.com/util-linux/util-linux)
|
||||
- macOS with `diskutil`
|
||||
|
||||
https://github.com/user-attachments/assets/c6f780ab-458b-420f-85cf-2fc45fcfe3a2
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
ya pack -a yazi-rs/plugins:mount
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Add this to your `~/.config/yazi/keymap.toml`:
|
||||
|
||||
```toml
|
||||
[[manager.prepend_keymap]]
|
||||
on = "M"
|
||||
run = "plugin mount"
|
||||
```
|
||||
|
||||
Available keybindings:
|
||||
|
||||
| Key binding | Alternate key | Action |
|
||||
| ------------ | ------------- | --------------------- |
|
||||
| <kbd>q</kbd> | - | Quit the plugin |
|
||||
| <kbd>k</kbd> | <kbd>↑</kbd> | Move up |
|
||||
| <kbd>j</kbd> | <kbd>↓</kbd> | Move down |
|
||||
| <kbd>l</kbd> | <kbd>→</kbd> | Enter the mount point |
|
||||
| <kbd>m</kbd> | - | Mount the partition |
|
||||
| <kbd>u</kbd> | - | Unmount the partition |
|
||||
| <kbd>e</kbd> | - | Eject the disk |
|
||||
|
||||
## TODO
|
||||
|
||||
- Custom keybindings
|
||||
- Windows support (I don't have an Windows machine for testing, PRs welcome!)
|
||||
- Support mount, unmount, and eject the entire disk
|
||||
|
||||
## License
|
||||
|
||||
This plugin is MIT-licensed. For more information check the [LICENSE](LICENSE) file.
|
||||
285
config/yazi/plugins/mount.yazi/main.lua
Normal file
285
config/yazi/plugins/mount.yazi/main.lua
Normal file
@ -0,0 +1,285 @@
|
||||
--- @since 25.2.26
|
||||
|
||||
local toggle_ui = ya.sync(function(self)
|
||||
if self.children then
|
||||
Modal:children_remove(self.children)
|
||||
self.children = nil
|
||||
else
|
||||
self.children = Modal:children_add(self, 10)
|
||||
end
|
||||
ya.render()
|
||||
end)
|
||||
|
||||
local subscribe = ya.sync(function(self)
|
||||
ps.unsub("mount")
|
||||
ps.sub("mount", function() ya.mgr_emit("plugin", { self._id, "refresh" }) end)
|
||||
end)
|
||||
|
||||
local update_partitions = ya.sync(function(self, partitions)
|
||||
self.partitions = partitions
|
||||
self.cursor = math.max(0, math.min(self.cursor or 0, #self.partitions - 1))
|
||||
ya.render()
|
||||
end)
|
||||
|
||||
local active_partition = ya.sync(function(self) return self.partitions[self.cursor + 1] end)
|
||||
|
||||
local update_cursor = ya.sync(function(self, cursor)
|
||||
if #self.partitions == 0 then
|
||||
self.cursor = 0
|
||||
else
|
||||
self.cursor = ya.clamp(0, self.cursor + cursor, #self.partitions - 1)
|
||||
end
|
||||
ya.render()
|
||||
end)
|
||||
|
||||
local M = {
|
||||
keys = {
|
||||
{ on = "q", run = "quit" },
|
||||
|
||||
{ on = "k", run = "up" },
|
||||
{ on = "j", run = "down" },
|
||||
{ on = "l", run = { "enter", "quit" } },
|
||||
|
||||
{ on = "<Up>", run = "up" },
|
||||
{ on = "<Down>", run = "down" },
|
||||
{ on = "<Right>", run = { "enter", "quit" } },
|
||||
|
||||
{ on = "m", run = "mount" },
|
||||
{ on = "u", run = "unmount" },
|
||||
{ on = "e", run = "eject" },
|
||||
},
|
||||
}
|
||||
|
||||
function M:new(area)
|
||||
self:layout(area)
|
||||
return self
|
||||
end
|
||||
|
||||
function M:layout(area)
|
||||
local chunks = ui.Layout()
|
||||
:constraints({
|
||||
ui.Constraint.Percentage(10),
|
||||
ui.Constraint.Percentage(80),
|
||||
ui.Constraint.Percentage(10),
|
||||
})
|
||||
:split(area)
|
||||
|
||||
local chunks = ui.Layout()
|
||||
:direction(ui.Layout.HORIZONTAL)
|
||||
:constraints({
|
||||
ui.Constraint.Percentage(10),
|
||||
ui.Constraint.Percentage(80),
|
||||
ui.Constraint.Percentage(10),
|
||||
})
|
||||
:split(chunks[2])
|
||||
|
||||
self._area = chunks[2]
|
||||
end
|
||||
|
||||
function M:entry(job)
|
||||
if job.args[1] == "refresh" then
|
||||
return update_partitions(self.obtain())
|
||||
end
|
||||
|
||||
toggle_ui()
|
||||
update_partitions(self.obtain())
|
||||
subscribe()
|
||||
|
||||
local tx1, rx1 = ya.chan("mpsc")
|
||||
local tx2, rx2 = ya.chan("mpsc")
|
||||
function producer()
|
||||
while true do
|
||||
local cand = self.keys[ya.which { cands = self.keys, silent = true }] or { run = {} }
|
||||
for _, r in ipairs(type(cand.run) == "table" and cand.run or { cand.run }) do
|
||||
tx1:send(r)
|
||||
if r == "quit" then
|
||||
toggle_ui()
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function consumer1()
|
||||
repeat
|
||||
local run = rx1:recv()
|
||||
if run == "quit" then
|
||||
tx2:send(run)
|
||||
break
|
||||
elseif run == "up" then
|
||||
update_cursor(-1)
|
||||
elseif run == "down" then
|
||||
update_cursor(1)
|
||||
elseif run == "enter" then
|
||||
local active = active_partition()
|
||||
if active and active.dist then
|
||||
ya.mgr_emit("cd", { active.dist })
|
||||
end
|
||||
else
|
||||
tx2:send(run)
|
||||
end
|
||||
until not run
|
||||
end
|
||||
|
||||
function consumer2()
|
||||
repeat
|
||||
local run = rx2:recv()
|
||||
if run == "quit" then
|
||||
break
|
||||
elseif run == "mount" then
|
||||
self.operate("mount")
|
||||
elseif run == "unmount" then
|
||||
self.operate("unmount")
|
||||
elseif run == "eject" then
|
||||
self.operate("eject")
|
||||
end
|
||||
until not run
|
||||
end
|
||||
|
||||
ya.join(producer, consumer1, consumer2)
|
||||
end
|
||||
|
||||
function M:reflow() return { self } end
|
||||
|
||||
function M:redraw()
|
||||
local rows = {}
|
||||
for _, p in ipairs(self.partitions or {}) do
|
||||
if not p.sub then
|
||||
rows[#rows + 1] = ui.Row { p.main }
|
||||
elseif p.sub == "" then
|
||||
rows[#rows + 1] = ui.Row { p.main, p.label or "", p.dist or "", p.fstype or "" }
|
||||
else
|
||||
rows[#rows + 1] = ui.Row { " " .. p.sub, p.label or "", p.dist or "", p.fstype or "" }
|
||||
end
|
||||
end
|
||||
|
||||
return {
|
||||
ui.Clear(self._area),
|
||||
ui.Border(ui.Border.ALL)
|
||||
:area(self._area)
|
||||
:type(ui.Border.ROUNDED)
|
||||
:style(ui.Style():fg("blue"))
|
||||
:title(ui.Line("Mount"):align(ui.Line.CENTER)),
|
||||
ui.Table(rows)
|
||||
:area(self._area:pad(ui.Pad(1, 2, 1, 2)))
|
||||
:header(ui.Row({ "Src", "Label", "Dist", "FSType" }):style(ui.Style():bold()))
|
||||
:row(self.cursor)
|
||||
:row_style(ui.Style():fg("blue"):underline())
|
||||
:widths {
|
||||
ui.Constraint.Length(20),
|
||||
ui.Constraint.Length(20),
|
||||
ui.Constraint.Percentage(70),
|
||||
ui.Constraint.Length(10),
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
function M.obtain()
|
||||
local tbl = {}
|
||||
local last
|
||||
for _, p in ipairs(fs.partitions()) do
|
||||
local main, sub = M.split(p.src)
|
||||
if main and last ~= main then
|
||||
if p.src == main then
|
||||
last, p.main, p.sub, tbl[#tbl + 1] = p.src, p.src, "", p
|
||||
else
|
||||
last, tbl[#tbl + 1] = main, { src = main, main = main, sub = "" }
|
||||
end
|
||||
end
|
||||
if sub then
|
||||
if tbl[#tbl].sub == "" and tbl[#tbl].main == main then
|
||||
tbl[#tbl].sub = nil
|
||||
end
|
||||
p.main, p.sub, tbl[#tbl + 1] = main, sub, p
|
||||
end
|
||||
end
|
||||
table.sort(M.fillin(tbl), function(a, b)
|
||||
if a.main == b.main then
|
||||
return (a.sub or "") < (b.sub or "")
|
||||
else
|
||||
return a.main > b.main
|
||||
end
|
||||
end)
|
||||
return tbl
|
||||
end
|
||||
|
||||
function M.split(src)
|
||||
local pats = {
|
||||
{ "^/dev/sd[a-z]", "%d+$" }, -- /dev/sda1
|
||||
{ "^/dev/nvme%d+n%d+", "p%d+$" }, -- /dev/nvme0n1p1
|
||||
{ "^/dev/mmcblk%d+", "p%d+$" }, -- /dev/mmcblk0p1
|
||||
{ "^/dev/disk%d+", ".+$" }, -- /dev/disk1s1
|
||||
}
|
||||
for _, p in ipairs(pats) do
|
||||
local main = src:match(p[1])
|
||||
if main then
|
||||
return main, src:sub(#main + 1):match(p[2])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.fillin(tbl)
|
||||
if ya.target_os() ~= "linux" then
|
||||
return tbl
|
||||
end
|
||||
|
||||
local sources, indices = {}, {}
|
||||
for i, p in ipairs(tbl) do
|
||||
if p.sub and not p.fstype then
|
||||
sources[#sources + 1], indices[p.src] = p.src, i
|
||||
end
|
||||
end
|
||||
if #sources == 0 then
|
||||
return tbl
|
||||
end
|
||||
|
||||
local output, err = Command("lsblk"):args({ "-p", "-o", "name,fstype", "-J" }):args(sources):output()
|
||||
if err then
|
||||
ya.dbg("Failed to fetch filesystem types for unmounted partitions: " .. err)
|
||||
return tbl
|
||||
end
|
||||
|
||||
local t = ya.json_decode(output and output.stdout or "")
|
||||
for _, p in ipairs(t and t.blockdevices or {}) do
|
||||
tbl[indices[p.name]].fstype = p.fstype
|
||||
end
|
||||
return tbl
|
||||
end
|
||||
|
||||
function M.operate(type)
|
||||
local active = active_partition()
|
||||
if not active then
|
||||
return
|
||||
elseif not active.sub then
|
||||
return -- TODO: mount/unmount main disk
|
||||
end
|
||||
|
||||
local output, err
|
||||
if ya.target_os() == "macos" then
|
||||
output, err = Command("diskutil"):args({ type, active.src }):output()
|
||||
end
|
||||
if ya.target_os() == "linux" then
|
||||
if type == "eject" then
|
||||
Command("udisksctl"):args({ "unmount", "-b", active.src }):status()
|
||||
output, err = Command("udisksctl"):args({ "power-off", "-b", active.src }):output()
|
||||
else
|
||||
output, err = Command("udisksctl"):args({ type, "-b", active.src }):output()
|
||||
end
|
||||
end
|
||||
|
||||
if not output then
|
||||
M.fail("Failed to %s `%s`: %s", type, active.src, err)
|
||||
elseif not output.status.success then
|
||||
M.fail("Failed to %s `%s`: %s", type, active.src, output.stderr)
|
||||
end
|
||||
end
|
||||
|
||||
function M.fail(s, ...) ya.notify { title = "Mount", content = string.format(s, ...), timeout = 10, level = "error" } end
|
||||
|
||||
function M:click() end
|
||||
|
||||
function M:scroll() end
|
||||
|
||||
function M:touch() end
|
||||
|
||||
return M
|
||||
@ -1,91 +0,0 @@
|
||||
# nbpreview.yazi
|
||||
|
||||
View your Jupyter notebooks beautifully in the preview in Yazi.
|
||||
|
||||
## Requirements
|
||||
|
||||
- [Yazi](https://github.com/sxyazi/yazi) version >=25.4.8
|
||||
- [nbpreview](https://github.com/paw-lu/nbpreview)
|
||||
|
||||
## Previews
|
||||
|
||||
<img width="1416" alt="image" src="https://github.com/AnirudhG07/nbpreview.yazi/assets/146579014/87535dc9-c45a-4eb7-a732-4384460b516d">
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
ya pack -a AnirudhG07/nbpreview
|
||||
|
||||
## For linux and MacOS
|
||||
git clone https://github.com/AnirudhG07/nbpreview.yazi.git ~/.config/yazi/plugins/nbpreview.yazi
|
||||
|
||||
## For Windows
|
||||
git clone https://github.com/AnirudhG07/nbpreview.yazi.git %AppData%\yazi\config\plugins\nbpreview.yazi
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
After installing the plugin, add this to your `yazi.toml` file inside the plugin's section previously present.
|
||||
|
||||
```toml
|
||||
[plugin]
|
||||
prepend_previewers = [
|
||||
{ name = "*.ipynb", run = "nbpreview" },
|
||||
]
|
||||
```
|
||||
|
||||
## Configurations
|
||||
|
||||
You can configure your preview by editing the `init.lua` file present in the plugin directory.
|
||||
<img width="724" alt="image" src="https://github.com/AnirudhG07/nbpreview.yazi/assets/146579014/99405d1f-3de8-4beb-a581-4a41affe8e57">
|
||||
|
||||
All the configurations provided using `nbpreview --help`.
|
||||
By default we have give you some of the flags which you can change according to your needs in the `init.lua` file.
|
||||
|
||||
Please DONOT change the below options(unless you know what you are doing) -
|
||||
|
||||
- `--nerd-font` - Yazi uses nerd-font.
|
||||
- \*`--decorated` - This enables the decorations you see in the preview.
|
||||
- `--no-paging` - To avoid errors.
|
||||
|
||||
The `OPTIONAL CHANGES` flags are by default(recommended) given. You can add more or change as you wish.
|
||||
|
||||
## CUSTOMIZATION
|
||||
|
||||
You can Color customize your previews from the Color schemes and themes provided by `nbpreview`. These are -
|
||||
|
||||
```bash
|
||||
# COLOR SCHEMES
|
||||
--color-system, --cs [standard|256|truecolor|windows|none|auto]
|
||||
The type of color system to use. [env var: NBPREVIEW_COLOR_SYSTEM]
|
||||
|
||||
# THEMES
|
||||
-t, --theme [abap|algol|algol_nu|arduino|autumn|bw|borland|coffee|colorful|default|
|
||||
dracula|emacs|friendly_grayscale|friendly|fruity|github-dark|gruvbox-dark|
|
||||
gruvbox-light|igor|inkpot|lightbulb|lilypond|lovelace|manni|material|monokai|
|
||||
murphy|native|nord-darker|nord|one-dark|paraiso-dark|paraiso-light|pastie|
|
||||
perldoc|rainbow_dash|rrt|sas|solarized-dark|solarized-light|staroffice|stata-dark|
|
||||
stata-light|tango|trac|vim|vs|xcode|zenburn|light|dark|ansi_light|ansi_dark]
|
||||
```
|
||||
|
||||
You can change the default give color scheme and theme to any you like.
|
||||
|
||||
> [!Note]
|
||||
>
|
||||
> The loading of `ipynb` might appear slow. This is due to the lag created by the command itself and not because of the plugin or yazi
|
||||
|
||||
## Using piper.yazi
|
||||
|
||||
[piper.yazi](https://github.com/yazi-rs/plugins/tree/main/piper.yazi) is a general-purpose previewer - you can pass any shell command to piper and it will use the command's output as the preview content.
|
||||
|
||||
To use `nbpreview` with piper, you can add this in your `yazi.toml` file:
|
||||
|
||||
```toml
|
||||
[[plugin.prepend_previewers]]
|
||||
name = "*.ipynb"
|
||||
run = 'piper -- nbpreview --no-paging --nerd-font --decorated --no-files --unicode --color --images --color-system=standard --theme=ansi_dark "$1"'
|
||||
```
|
||||
|
||||
## Explore Yazi
|
||||
|
||||
Yazi is an amazing, blazing fast terminal file manager, with a variety of plugins, flavors and themes. Check them out at [awesome-yazi](https://github.com/AnirudhG07/awesome-yazi) and the official [yazi webpage](https://yazi-rs.github.io/).
|
||||
21
config/yazi/plugins/office.yazi/LICENSE
Normal file
21
config/yazi/plugins/office.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.
|
||||
76
config/yazi/plugins/office.yazi/README.md
Normal file
76
config/yazi/plugins/office.yazi/README.md
Normal file
@ -0,0 +1,76 @@
|
||||
<div align="center">
|
||||
|
||||
# office.yazi
|
||||
### A plugin to preview office documents in <a href="https://github.com/sxyazi/yazi">Yazi <img src="https://github.com/sxyazi/yazi/blob/main/assets/logo.png?raw=true" alt="a duck" width="24px" height="24px"></a>
|
||||
|
||||
<img src="https://github.com/macydnah/office.yazi/blob/assets/preview_test.gif" alt="preview test" width="88%">
|
||||
|
||||
##
|
||||
|
||||
</div>
|
||||
|
||||
## Installation
|
||||
> [!TIP]
|
||||
> Installing this plugin with `ya` will conveniently clone the plugin from GitHub,
|
||||
> copy it to your plugins directory, and update the `package.toml` to lock its version [^1].
|
||||
>
|
||||
> To install it with `ya` run:
|
||||
> ```sh
|
||||
> ya pack -a macydnah/office
|
||||
> ```
|
||||
|
||||
> Or if you prefer a manual approach:
|
||||
> ```sh
|
||||
> ## For linux and MacOS
|
||||
> git clone https://github.com/macydnah/office.yazi.git ~/.config/yazi/plugins/office.yazi
|
||||
>
|
||||
> ## For Windows
|
||||
> git clone https://github.com/macydnah/office.yazi.git %AppData%\yazi\config\plugins\office.yazi
|
||||
> ```
|
||||
|
||||
## Usage
|
||||
In your `yazi.toml` add rules to preloaders[^2] and previewers[^3] to run `office` plugin with office documents.
|
||||
|
||||
> [!NOTE]
|
||||
> Your config may be different depending if you're *appending*, *prepending* or *overriding* default rules.
|
||||
> If unsure, take a look at [Configuration](https://yazi-rs.github.io/docs/configuration/overview)[^4]
|
||||
> and [Configuration mixing](https://yazi-rs.github.io/docs/configuration/overview#mixing)[^5]
|
||||
|
||||
For a general usecase, you may use the following rules
|
||||
```toml
|
||||
[plugin]
|
||||
|
||||
prepend_preloaders = [
|
||||
# Office Documents
|
||||
{ mime = "application/openxmlformats-officedocument.*", run = "office" },
|
||||
{ mime = "application/oasis.opendocument.*", run = "office" },
|
||||
{ mime = "application/ms-*", run = "office" },
|
||||
{ mime = "application/msword", run = "office" },
|
||||
{ name = "*.docx", run = "office" },
|
||||
]
|
||||
|
||||
prepend_previewers = [
|
||||
# Office Documents
|
||||
{ mime = "application/openxmlformats-officedocument.*", run = "office" },
|
||||
{ mime = "application/oasis.opendocument.*", run = "office" },
|
||||
{ mime = "application/ms-*", run = "office" },
|
||||
{ mime = "application/msword", run = "office" },
|
||||
{ name = "*.docx", run = "office" },
|
||||
]
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
> [!IMPORTANT]
|
||||
> Make sure that these commands are installed in your system and can be found in `PATH`:
|
||||
>
|
||||
> - `libreoffice`
|
||||
> - `pdftoppm`
|
||||
|
||||
## License
|
||||
office.yazi is licensed under the terms of the [MIT License](LICENSE)
|
||||
|
||||
[^1]: [The official package manager for Yazi](https://yazi-rs.github.io/docs/cli)
|
||||
[^2]: [Preloaders rules](https://yazi-rs.github.io/docs/configuration/yazi#plugin.preloaders)
|
||||
[^3]: [Previewers rules](https://yazi-rs.github.io/docs/configuration/yazi#plugin.previewers)
|
||||
[^4]: [Configuration](https://yazi-rs.github.io/docs/configuration/overview)
|
||||
[^5]: [Configuration mixing](https://yazi-rs.github.io/docs/configuration/overview#mixing)
|
||||
114
config/yazi/plugins/office.yazi/main.lua
Normal file
114
config/yazi/plugins/office.yazi/main.lua
Normal file
@ -0,0 +1,114 @@
|
||||
--- @since 25.2.7
|
||||
|
||||
local M = {}
|
||||
|
||||
function M:peek(job)
|
||||
local start, cache = os.clock(), ya.file_cache(job)
|
||||
if not cache then
|
||||
return
|
||||
end
|
||||
|
||||
local ok, err = self:preload(job)
|
||||
if not ok or err then
|
||||
return
|
||||
end
|
||||
|
||||
ya.sleep(math.max(0, rt.preview.image_delay / 1000 + start - os.clock()))
|
||||
ya.image_show(cache, job.area)
|
||||
ya.preview_widgets(job, {})
|
||||
end
|
||||
|
||||
function M:seek(job)
|
||||
local h = cx.active.current.hovered
|
||||
if h and h.url == job.file.url then
|
||||
local step = ya.clamp(-1, job.units, 1)
|
||||
ya.manager_emit("peek", { math.max(0, cx.active.preview.skip + step), only_if = job.file.url })
|
||||
end
|
||||
end
|
||||
|
||||
function M:doc2pdf(job)
|
||||
local tmp = "/tmp/yazi-" .. ya.uid() .. "/" .. ya.hash("office.yazi") .. "/"
|
||||
|
||||
--[[ For Future Reference: Regarding `libreoffice` as preconverter
|
||||
1. It prints errors to stdout (always, doesn't matter if it succeeded or it failed)
|
||||
2. Always writes the converted files to the filesystem, so no "Mario|Bros|Piping|Magic" for the data stream (https://ask.libreoffice.org/t/using-convert-to-output-to-stdout/38753)
|
||||
3. The `pdf:draw_pdf_Export` filter needs literal double quotes when defining its options (https://help.libreoffice.org/latest/en-US/text/shared/guide/pdf_params.html?&DbPAR=SHARED&System=UNIX#generaltext/shared/guide/pdf_params.xhp)
|
||||
3.1 Regarding double quotes and Lua strings, see https://www.lua.org/manual/5.1/manual.html#2.1 --]]
|
||||
local libreoffice = Command("libreoffice")
|
||||
:args({
|
||||
"--headless",
|
||||
"--convert-to",
|
||||
"pdf:draw_pdf_Export:{" ..
|
||||
"\"PageRange\":{" ..
|
||||
"\"type\":\"string\"," ..
|
||||
"\"value\":" .. "\"" .. job.skip + 1 .. "\"" ..
|
||||
"}" ..
|
||||
"}",
|
||||
"--outdir",
|
||||
tmp,
|
||||
tostring(job.file.url)
|
||||
})
|
||||
:stdin(Command.NULL)
|
||||
:stdout(Command.PIPED)
|
||||
:stderr(Command.NULL)
|
||||
:output()
|
||||
|
||||
if not libreoffice.status.success then
|
||||
ya.err(libreoffice.stdout:match("LibreOffice .+"):gsub("%\n.*", "") .. " " .. libreoffice.stdout:match("Error .+"):gsub("%\n.*", ""))
|
||||
return nil, Err("Failed to preconvert `%s` to a temporary PDF", job.file.name)
|
||||
end
|
||||
|
||||
local tmp = tmp .. job.file.name:gsub("%.[^%.]+$", ".pdf")
|
||||
local read_permission = io.open(tmp, "r")
|
||||
if not read_permission then
|
||||
return nil, Err("Failed to read `%s`: make sure file exists and have read access", tmp)
|
||||
end
|
||||
read_permission:close()
|
||||
|
||||
return tmp
|
||||
end
|
||||
|
||||
function M:preload(job)
|
||||
local cache = ya.file_cache(job)
|
||||
if not cache or fs.cha(cache) then
|
||||
return true
|
||||
end
|
||||
|
||||
local tmp_pdf, err = self:doc2pdf(job)
|
||||
if not tmp_pdf then
|
||||
return true, Err(" " .. "%s", err)
|
||||
end
|
||||
|
||||
local output, err = Command("pdftoppm")
|
||||
:args({
|
||||
"-singlefile",
|
||||
"-jpeg",
|
||||
"-jpegopt",
|
||||
"quality=" .. rt.preview.image_quality,
|
||||
"-f",
|
||||
1,
|
||||
tostring(tmp_pdf),
|
||||
})
|
||||
:stdout(Command.PIPED)
|
||||
:stderr(Command.PIPED)
|
||||
:output()
|
||||
|
||||
local rm_tmp_pdf, rm_err = fs.remove("file", Url(tmp_pdf))
|
||||
if not rm_tmp_pdf then
|
||||
return true, Err("Failed to remove %s, error: %s", tmp_pdf, rm_err)
|
||||
end
|
||||
|
||||
if not output then
|
||||
return true, Err("Failed to start `pdftoppm`, error: %s", err)
|
||||
elseif not output.status.success then
|
||||
local pages = tonumber(output.stderr:match("the last page %((%d+)%)")) or 0
|
||||
if job.skip > 0 and pages > 0 then
|
||||
ya.mgr_emit("peek", { math.max(0, pages - 1), only_if = job.file.url, upper_bound = true })
|
||||
end
|
||||
return true, Err("Failed to convert %s to image, stderr: %s", tmp_pdf, output.stderr)
|
||||
end
|
||||
|
||||
return fs.write(cache, output.stdout)
|
||||
end
|
||||
|
||||
return M
|
||||
89
config/yazi/plugins/rich-preview.yazi/README.md
Normal file
89
config/yazi/plugins/rich-preview.yazi/README.md
Normal file
@ -0,0 +1,89 @@
|
||||
# rich-preview.yazi
|
||||
|
||||
Preview file types using `rich` command in Yazi. This plugin allows preview for various filetypes including -
|
||||
|
||||
- Markdown
|
||||
- Jupyter notebook
|
||||
- JSON
|
||||
- CSV
|
||||
- RestructuredText
|
||||
|
||||
## Previews/Screenshots
|
||||
|
||||
[rich-preview1.webm](https://github.com/user-attachments/assets/580e36a8-249f-48a8-95fc-8c3d60e6a7d7)
|
||||
|
||||
## Requirements
|
||||
|
||||
- [Yazi](https://github.com/sxyazi/yazi) v0.4 or higher.
|
||||
- [rich-cli](https://github.com/Textualize/rich) v13.7.1 or higher.
|
||||
|
||||
## Installation
|
||||
|
||||
To install this plugin, simply run-
|
||||
|
||||
```bash
|
||||
ya pack -a AnirudhG07/rich-preview
|
||||
## For linux and MacOS
|
||||
git clone https://github.com/AnirudhG07/rich-preview.yazi.git ~/.config/yazi/plugins/rich-preview.yazi
|
||||
|
||||
## For Windows
|
||||
git clone https://github.com/AnirudhG07/rich-preview.yazi.git %AppData%\yazi\config\plugins\rich-preview.yazi
|
||||
```
|
||||
|
||||
## Usages
|
||||
|
||||
The `rich` commands automatically detects if the file is markdown, csv, json, etc. files and accordingly the preview is viewed.
|
||||
|
||||
Add the below to your `yazi.toml` file to allow the respective file to previewed using `rich`.
|
||||
|
||||
```toml
|
||||
[plugin]
|
||||
|
||||
prepend_previewers = [
|
||||
{ name = "*.csv", run = "rich-preview"}, # for csv files
|
||||
{ name = "*.md", run = "rich-preview" }, # for markdown (.md) files
|
||||
{ name = "*.rst", run = "rich-preview"}, # for restructured text (.rst) files
|
||||
{ name = "*.ipynb", run = "rich-preview"}, # for jupyter notebooks (.ipynb)
|
||||
{ name = "*.json", run = "rich-preview"}, # for json (.json) files
|
||||
# { name = "*.lang_type", run = "rich-preview"} # for particular language files eg. .py, .go., .lua, etc.
|
||||
]
|
||||
```
|
||||
|
||||
## Configurations
|
||||
|
||||
If you would like to use `rich` with more configurations, you can go to `init.lua` and edit the arguments in the code with your preferences. You can view the options using `rich --help`.
|
||||
|
||||
```lua
|
||||
-- init.lua
|
||||
"-j",
|
||||
"--left",
|
||||
"--line-numbers",
|
||||
"--force-terminal",
|
||||
"--panel=rounded",
|
||||
"--guides",
|
||||
"--max-width" -- to area of preview
|
||||
```
|
||||
|
||||
You can add more, remove and choose themes as you wish. You can set styles or Themes(as mentioned in `rich --help`) by `--theme=your_theme` and similarly for style.
|
||||
|
||||
## Notes
|
||||
|
||||
Currently the colors maynot be uniformly present, along with weird lines here and there. This is due to `"--force-terminal"` option. You can disable it if you find it annoying. Work is in progress to possibly fix the issue.
|
||||
|
||||
## Using piper.yazi
|
||||
|
||||
[piper.yazi](https://github.com/yazi-rs/plugins/tree/main/piper.yazi) is a general-purpose previewer - you can pass any shell command to piper and it will use the command's output as the preview content.
|
||||
|
||||
To use `rich` with piper, you can add this in your `yazi.toml` file:
|
||||
|
||||
```toml
|
||||
[[plugin.prepend_previewers]]
|
||||
name = "*.md"
|
||||
run = 'piper -- rich -j --left --panel=rounded --guides --line-numbers --force-terminal "$1"'
|
||||
```
|
||||
|
||||
Note you can also add other filetypes as mentioned above in the same format.
|
||||
|
||||
# Explore Yazi
|
||||
|
||||
Yazi is an amazing, blazing fast terminal file manager, with a variety of plugins, flavors and themes. Check them out at [awesome-yazi](https://github.com/AnirudhG07/awesome-yazi) and the official [yazi webpage](https://yazi-rs.github.io/).
|
||||
@ -1,22 +1,16 @@
|
||||
local M = {}
|
||||
|
||||
function M:peek(job)
|
||||
local child = Command("nbpreview")
|
||||
local child = Command("rich")
|
||||
:args({
|
||||
-- DO NOT CHANGE --
|
||||
"--no-paging",
|
||||
"--nerd-font",
|
||||
"--decorated",
|
||||
|
||||
-- OPTIONAL CHANGES --
|
||||
"--no-files",
|
||||
"--unicode",
|
||||
"--color",
|
||||
"--images",
|
||||
|
||||
-- SPECIAL CUSTOMIZATIONS --
|
||||
"--color-system=standard",
|
||||
"--theme=ansi_dark",
|
||||
"-j",
|
||||
"--left",
|
||||
"--line-numbers",
|
||||
"--force-terminal",
|
||||
"--panel=rounded",
|
||||
"--guides",
|
||||
"--max-width",
|
||||
tostring(job.area.w),
|
||||
tostring(job.file.url),
|
||||
})
|
||||
:stdout(Command.PIPED)
|
||||
21
config/yazi/plugins/smart-filter.yazi/LICENSE
Normal file
21
config/yazi/plugins/smart-filter.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/smart-filter.yazi/README.md
Normal file
28
config/yazi/plugins/smart-filter.yazi/README.md
Normal file
@ -0,0 +1,28 @@
|
||||
# smart-filter.yazi
|
||||
|
||||
A Yazi plugin that makes filters smarter: continuous filtering, automatically enter unique directory, open file on submitting.
|
||||
|
||||
https://github.com/yazi-rs/plugins/assets/17523360/72aaf117-1378-4f7e-93ba-d425a79deac5
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
ya pack -a yazi-rs/plugins:smart-filter
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Add this to your `~/.config/yazi/keymap.toml`:
|
||||
|
||||
```toml
|
||||
[[manager.prepend_keymap]]
|
||||
on = "F"
|
||||
run = "plugin smart-filter"
|
||||
desc = "Smart filter"
|
||||
```
|
||||
|
||||
Make sure the <kbd>F</kbd> key is not used elsewhere.
|
||||
|
||||
## License
|
||||
|
||||
This plugin is MIT-licensed. For more information check the [LICENSE](LICENSE) file.
|
||||
49
config/yazi/plugins/smart-filter.yazi/main.lua
Normal file
49
config/yazi/plugins/smart-filter.yazi/main.lua
Normal file
@ -0,0 +1,49 @@
|
||||
--- @since 25.2.26
|
||||
|
||||
local hovered = ya.sync(function()
|
||||
local h = cx.active.current.hovered
|
||||
if not h then
|
||||
return {}
|
||||
end
|
||||
|
||||
return {
|
||||
url = h.url,
|
||||
is_dir = h.cha.is_dir,
|
||||
unique = #cx.active.current.files == 1,
|
||||
}
|
||||
end)
|
||||
|
||||
local function prompt()
|
||||
return ya.input {
|
||||
title = "Smart filter:",
|
||||
position = { "center", w = 50 },
|
||||
realtime = true,
|
||||
debounce = 0.1,
|
||||
}
|
||||
end
|
||||
|
||||
local function entry()
|
||||
local input = prompt()
|
||||
|
||||
while true do
|
||||
local value, event = input:recv()
|
||||
if event ~= 1 and event ~= 3 then
|
||||
ya.mgr_emit("escape", { filter = true })
|
||||
break
|
||||
end
|
||||
|
||||
ya.mgr_emit("filter_do", { value, smart = true })
|
||||
|
||||
local h = hovered()
|
||||
if h.unique and h.is_dir then
|
||||
ya.mgr_emit("escape", { filter = true })
|
||||
ya.mgr_emit("enter", {})
|
||||
input = prompt()
|
||||
elseif event == 1 then
|
||||
ya.mgr_emit("escape", { filter = true })
|
||||
ya.mgr_emit(h.is_dir and "enter" or "open", { h.url })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return { entry = entry }
|
||||
21
config/yazi/plugins/time-travel.yazi/LICENSE
Normal file
21
config/yazi/plugins/time-travel.yazi/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 Xianyi Lin
|
||||
|
||||
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.
|
||||
41
config/yazi/plugins/time-travel.yazi/README.md
Normal file
41
config/yazi/plugins/time-travel.yazi/README.md
Normal file
@ -0,0 +1,41 @@
|
||||
# time-travel.yazi
|
||||
|
||||
A Yazi plugin for browsing backwards and forwards in time via BTRFS / ZFS
|
||||
snapshots.
|
||||
|
||||
https://github.com/user-attachments/assets/6d2fc9e7-f86e-4444-aab6-4e11e51e8b34
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
ya pack -a iynaix/time-travel
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> The minimum required yazi version is 25.2.7.
|
||||
|
||||
## Usage
|
||||
|
||||
Add keymaps similar to the following to your `~/.config/yazi/keymap.toml`:
|
||||
|
||||
```toml
|
||||
[[manager.prepend_keymap]]
|
||||
on = ["z", "h"]
|
||||
run = "plugin time-travel --args=prev"
|
||||
desc = "Go to previous snapshot"
|
||||
|
||||
[[manager.prepend_keymap]]
|
||||
on = ["z", "l"]
|
||||
run = "plugin time-travel --args=next"
|
||||
desc = "Go to next snapshot"
|
||||
|
||||
[[manager.prepend_keymap]]
|
||||
on = ["z", "e"]
|
||||
run = "plugin time-travel --args=exit"
|
||||
desc = "Exit browsing snapshots"
|
||||
```
|
||||
|
||||
#### Note for BTRFS
|
||||
|
||||
`sudo` is required to run btrfs commands such as `btrfs subvolume list`, the
|
||||
plugin will drop into a terminal to prompt for the password.
|
||||
386
config/yazi/plugins/time-travel.yazi/main.lua
Normal file
386
config/yazi/plugins/time-travel.yazi/main.lua
Normal file
@ -0,0 +1,386 @@
|
||||
---@param msg string
|
||||
local notify_warn = function(msg)
|
||||
ya.notify { title = "ZFS", content = msg, level = "warn", timeout = 5 }
|
||||
end
|
||||
|
||||
---@param msg string
|
||||
local notify_error = function(msg)
|
||||
ya.notify { title = "ZFS", content = msg, level = "error", timeout = 5 }
|
||||
end
|
||||
|
||||
---@param arr table
|
||||
---@param predicate fun(value: any): boolean
|
||||
---@return number|nil # index if found, nil if not found
|
||||
local find_index = function(arr, predicate)
|
||||
for i, value in ipairs(arr) do
|
||||
if predicate(value) then
|
||||
return i
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Verify if `sudo` is already authenticated
|
||||
--- @return boolean
|
||||
local function sudo_already()
|
||||
local status = Command("sudo"):args({ "--validate", "--non-interactive" }):status()
|
||||
assert(status, "Failed to run `sudo --validate --non-interactive`")
|
||||
return status.success
|
||||
end
|
||||
|
||||
--- Run a program with `sudo` privilege
|
||||
--- @param program string
|
||||
--- @param args table
|
||||
--- @return Output|nil output
|
||||
--- @return integer|nil err
|
||||
--- nil: no error
|
||||
--- 1: sudo failed
|
||||
local function run_with_sudo(program, args)
|
||||
local cmd = Command("sudo"):args({ program, table.unpack(args) }):stdout(Command.PIPED):stderr(Command.PIPED)
|
||||
if sudo_already() then
|
||||
return cmd:output()
|
||||
end
|
||||
|
||||
local permit = ya.hide()
|
||||
print(string.format("Sudo password required to run: `%s %s`", program, table.concat(args, " ")))
|
||||
local output = cmd:output()
|
||||
permit:drop()
|
||||
|
||||
if output.status.success or sudo_already() then
|
||||
return output
|
||||
end
|
||||
return nil, 1
|
||||
end
|
||||
|
||||
|
||||
---@return string
|
||||
local get_cwd = ya.sync(function()
|
||||
return tostring(cx.active.current.cwd)
|
||||
end)
|
||||
|
||||
---@param s string
|
||||
---@return string
|
||||
local trim = function(s)
|
||||
return s:match("^%s*(.-)%s*$")
|
||||
end
|
||||
|
||||
---@param cwd string
|
||||
---@return string|nil
|
||||
local get_filesystem_type = function(cwd)
|
||||
local stat, _ = Command("stat"):args({ "-f", "-c", "%T", cwd }):output()
|
||||
if not stat.status.success then
|
||||
return nil
|
||||
end
|
||||
return trim(stat.stdout)
|
||||
end
|
||||
|
||||
---@param cwd string
|
||||
---@return string|nil
|
||||
local zfs_dataset = function(cwd)
|
||||
local df, _ = Command("df"):args({ "--output=source", cwd }):output()
|
||||
local dataset = nil
|
||||
for line in df.stdout:gmatch("[^\r\n]+") do
|
||||
-- dataset is last line in output
|
||||
dataset = line
|
||||
end
|
||||
return dataset
|
||||
end
|
||||
|
||||
---@param dataset string
|
||||
---@return string|nil
|
||||
local zfs_mountpoint = function(dataset)
|
||||
local zfs, _ = Command("zfs"):args({ "get", "-H", "-o", "value", "mountpoint", dataset }):output()
|
||||
|
||||
-- not a dataset!
|
||||
if not zfs.status.success then
|
||||
return nil
|
||||
end
|
||||
|
||||
-- legacy mountpoint, search for actual mountpoint using df
|
||||
if zfs.stdout == "legacy\n" then
|
||||
local df, _ = Command("df"):output()
|
||||
if not df.status.success then
|
||||
return nil
|
||||
end
|
||||
|
||||
for line in df.stdout:gmatch("[^\r\n]+") do
|
||||
-- match start of line
|
||||
if string.sub(line, 1, #dataset) == dataset then
|
||||
local mountpoint = nil
|
||||
for field in line:gmatch("%S+") do
|
||||
-- mountpoint is last field in df output
|
||||
mountpoint = field
|
||||
end
|
||||
return mountpoint
|
||||
end
|
||||
end
|
||||
else
|
||||
return zfs.stdout:gsub("\n$", "")
|
||||
end
|
||||
|
||||
-- shouldn't be here
|
||||
return nil
|
||||
end
|
||||
|
||||
-- returns the path relative to the mountpoint / snapshot
|
||||
---@param cwd string
|
||||
---@param mountpoint string
|
||||
local zfs_relative = function(cwd, mountpoint)
|
||||
-- relative path to get mountpoint
|
||||
local relative = (cwd:sub(0, #mountpoint) == mountpoint) and cwd:sub(#mountpoint + 1) or cwd
|
||||
|
||||
-- is a snapshot dir, strip everything after "/snapshot"
|
||||
if cwd:find(".zfs/snapshot") ~= nil then
|
||||
local snapshot_pos = cwd:find("/snapshot")
|
||||
|
||||
-- everything after the "/snapshot/"
|
||||
local after = cwd:sub(snapshot_pos + #"/snapshot" + 1)
|
||||
local first_slash = after:find("/")
|
||||
-- root of snapshot?
|
||||
if first_slash == nil then
|
||||
return "/"
|
||||
else
|
||||
return after:sub(first_slash)
|
||||
end
|
||||
end
|
||||
|
||||
return relative
|
||||
end
|
||||
|
||||
---@class Snapshot
|
||||
---@field name string
|
||||
---@field path string
|
||||
|
||||
---@param dataset string
|
||||
---@param mountpoint string
|
||||
---@param relative string
|
||||
---@return Snapshot[]
|
||||
local zfs_snapshots = function(dataset, mountpoint, relative)
|
||||
-- -S is for reverse order
|
||||
local zfs_snapshots, _ = Command("zfs"):args({ "list", "-H", "-t", "snapshot", "-o", "name", "-S", "creation",
|
||||
dataset })
|
||||
:output()
|
||||
|
||||
if not zfs_snapshots.status.success then
|
||||
return {}
|
||||
end
|
||||
|
||||
---@type Snapshot[]
|
||||
local snapshots = {}
|
||||
for snapshot in zfs_snapshots.stdout:gmatch("[^\r\n]+") do
|
||||
-- in the format dataset@snapshot
|
||||
local sep = snapshot:find("@")
|
||||
local id = snapshot:sub(sep + 1)
|
||||
|
||||
table.insert(snapshots, {
|
||||
id = id,
|
||||
path = mountpoint .. "/.zfs/snapshot/" .. id .. relative,
|
||||
})
|
||||
end
|
||||
return snapshots
|
||||
end
|
||||
|
||||
---@param cwd string
|
||||
---@return string|nil
|
||||
local function btrfs_mountpoint(cwd)
|
||||
local cmd, _ = Command("findmnt"):args({ "-no", "TARGET", "-T", cwd }):output()
|
||||
if not cmd.status.success then
|
||||
return nil
|
||||
end
|
||||
return trim(cmd.stdout)
|
||||
end
|
||||
|
||||
---Returns the current uuid and the parent uuid
|
||||
---@param cwd string
|
||||
---@return string|nil, string|nil
|
||||
local function btrfs_uuids(cwd)
|
||||
local cmd, _ = run_with_sudo("btrfs", { "subvolume", "show", cwd })
|
||||
if not cmd then
|
||||
return nil
|
||||
end
|
||||
|
||||
local parent_uuid = nil
|
||||
local uuid = nil
|
||||
for line in cmd.stdout:gmatch("[^\r\n]+") do
|
||||
local parent_uuid_re = line:match("^%s*Parent UUID:%s*(%S+)")
|
||||
if parent_uuid_re then
|
||||
parent_uuid = trim(parent_uuid_re)
|
||||
end
|
||||
|
||||
local uuid_re = line:match("^%s*UUID:%s*(%S+)")
|
||||
if uuid_re then
|
||||
uuid = trim(uuid_re)
|
||||
end
|
||||
end
|
||||
return parent_uuid, uuid
|
||||
end
|
||||
|
||||
---@param mountpoint string
|
||||
---@param current_uuid string
|
||||
---@param current_parent_uuid string|nil
|
||||
---@return { snapshots: Snapshot[], latest_path: string, current_snapshot_id: string }
|
||||
local function btrfs_snapshots(mountpoint, current_uuid, current_parent_uuid)
|
||||
local snapshots_cmd, _ = run_with_sudo("btrfs", { "subvolume", "list", "-q", "-u", mountpoint })
|
||||
if not snapshots_cmd then
|
||||
return {}
|
||||
end
|
||||
|
||||
local snapshots = {}
|
||||
local latest_path = ""
|
||||
local current_snapshot_id = ""
|
||||
|
||||
for line in snapshots_cmd.stdout:gmatch("[^\r\n]+") do
|
||||
local pattern = "ID (%d+) gen %d+ top level %d+ parent_uuid ([%w-]+)%s+uuid ([%w-]+) path (%S+)"
|
||||
-- Extract the fields
|
||||
local subvol_id, parent_uuid, uuid, name = line:match(pattern)
|
||||
parent_uuid = trim(parent_uuid)
|
||||
|
||||
local path = mountpoint .. "/" .. name
|
||||
local is_parent = false
|
||||
|
||||
if current_parent_uuid == "-" then
|
||||
if parent_uuid == "-" and uuid == current_uuid then
|
||||
is_parent = true
|
||||
end
|
||||
else
|
||||
if uuid == current_parent_uuid then
|
||||
is_parent = true
|
||||
end
|
||||
end
|
||||
|
||||
if is_parent then
|
||||
latest_path = path
|
||||
end
|
||||
|
||||
if uuid == current_uuid and not is_parent then
|
||||
current_snapshot_id = name
|
||||
end
|
||||
|
||||
if not is_parent then
|
||||
table.insert(snapshots, {
|
||||
id = name,
|
||||
subvol_id = subvol_id, -- used only for sorting
|
||||
path = path,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- Sort snapshots by time descending
|
||||
table.sort(snapshots, function(a, b)
|
||||
return a.subvol_id > b.subvol_id
|
||||
end)
|
||||
|
||||
return { snapshots = snapshots, latest_path = latest_path, current_snapshot_id = current_snapshot_id }
|
||||
end
|
||||
|
||||
return {
|
||||
entry = function(_, job)
|
||||
local action = job.args[1]
|
||||
local cwd = get_cwd()
|
||||
|
||||
if action ~= "exit" and action ~= "prev" and action ~= "next" then
|
||||
return notify_error("Invalid action: " .. action)
|
||||
end
|
||||
|
||||
local fs_type = get_filesystem_type(cwd)
|
||||
if fs_type ~= "zfs" and fs_type ~= "btrfs" then
|
||||
return notify_error("Current directory is not on a BTRFS / ZFS filesystem.")
|
||||
end
|
||||
|
||||
local current_snapshot_id = ""
|
||||
local latest_path = ""
|
||||
local snapshots = {}
|
||||
|
||||
if fs_type == "zfs" then
|
||||
local dataset = zfs_dataset(cwd)
|
||||
if dataset == nil then
|
||||
return notify_error("Current directory is not within a ZFS dataset.")
|
||||
end
|
||||
|
||||
if cwd:find(".zfs/snapshot") ~= nil then
|
||||
-- in the format dataset@snapshot
|
||||
local sep = dataset:find("@")
|
||||
current_snapshot_id = dataset:sub(sep + 1)
|
||||
dataset = dataset:sub(1, sep - 1)
|
||||
end
|
||||
|
||||
local mountpoint = zfs_mountpoint(dataset)
|
||||
if mountpoint == nil then
|
||||
return notify_error("Current directory is not within a ZFS dataset.")
|
||||
end
|
||||
|
||||
-- NOTE: relative already has leading "/"
|
||||
local relative = zfs_relative(cwd, mountpoint)
|
||||
|
||||
latest_path = mountpoint .. relative
|
||||
snapshots = zfs_snapshots(dataset, mountpoint, relative)
|
||||
elseif fs_type == "btrfs" then
|
||||
local mountpoint = btrfs_mountpoint(cwd)
|
||||
local parent_uuid, uuid = btrfs_uuids(cwd)
|
||||
|
||||
if mountpoint == nil or uuid == nil then
|
||||
return notify_error("Current directory is not within a BTRFS subvolume.")
|
||||
end
|
||||
|
||||
local ret = btrfs_snapshots(mountpoint, uuid, parent_uuid)
|
||||
snapshots = ret.snapshots
|
||||
latest_path = ret.latest_path
|
||||
current_snapshot_id = ret.current_snapshot_id
|
||||
end
|
||||
|
||||
if action == "exit" then
|
||||
ya.manager_emit("cd", { latest_path })
|
||||
return
|
||||
end
|
||||
|
||||
if #snapshots == 0 then
|
||||
return notify_warn("No snapshots found.")
|
||||
end
|
||||
|
||||
---@param start_idx integer
|
||||
---@param end_idx integer
|
||||
---@param step integer
|
||||
local find_and_goto_snapshot = function(start_idx, end_idx, step)
|
||||
if start_idx == 0 then
|
||||
-- going from newest snapshot to current state
|
||||
return ya.manager_emit("cd", { latest_path })
|
||||
elseif start_idx < 0 then
|
||||
return notify_warn("No earlier snapshots found.")
|
||||
elseif start_idx > #snapshots then
|
||||
return notify_warn("No earlier snapshots found.")
|
||||
end
|
||||
|
||||
for i = start_idx, end_idx, step do
|
||||
local snapshot_dir = snapshots[i].path
|
||||
if io.open(snapshot_dir, "r") then
|
||||
return ya.manager_emit("cd", { snapshot_dir })
|
||||
end
|
||||
end
|
||||
|
||||
local direction = action == "prev" and "earlier" or "later"
|
||||
return notify_warn("No " .. direction .. " snapshots found.")
|
||||
end
|
||||
|
||||
-- NOTE: latest snapshot is first in list
|
||||
if current_snapshot_id == "" then
|
||||
if action == "prev" then
|
||||
-- go to latest snapshot
|
||||
return find_and_goto_snapshot(1, #snapshots, 1)
|
||||
elseif action == "next" then
|
||||
return notify_warn("No later snapshots found.")
|
||||
end
|
||||
end
|
||||
|
||||
-- has current snapshot
|
||||
local idx = find_index(snapshots, function(snapshot) return snapshot.id == current_snapshot_id end)
|
||||
if idx == nil then
|
||||
return notify_error("Snapshot not found.")
|
||||
end
|
||||
|
||||
if action == "prev" then
|
||||
find_and_goto_snapshot(idx + 1, #snapshots, 1)
|
||||
elseif action == "next" then
|
||||
find_and_goto_snapshot(idx - 1, 1, -1)
|
||||
end
|
||||
end,
|
||||
}
|
||||
21
config/yazi/plugins/vidir.yazi/LICENSE
Normal file
21
config/yazi/plugins/vidir.yazi/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 Kristofers Solo
|
||||
|
||||
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.
|
||||
29
config/yazi/plugins/vidir.yazi/README.md
Normal file
29
config/yazi/plugins/vidir.yazi/README.md
Normal file
@ -0,0 +1,29 @@
|
||||
# vidir.yazi
|
||||
|
||||
This plugin is a bulk-rename plugin using [vidir](https://linux.die.net/man/1/vidir).
|
||||
|
||||
## Requirements
|
||||
|
||||
- [yazi >= v25.2.7](https://github.com/sxyazi/yazi)
|
||||
- [vidir](https://linux.die.net/man/1/vidir) (sometimes included in [moreutils](https://man.archlinux.org/listing/extra/moreutils/) package)
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
ya pack -a kristoferssolo/vidir
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Add this to your `~/.config/yazi/keymap.toml`:
|
||||
|
||||
```toml
|
||||
[[manager.prepend_keymap]]
|
||||
on = "B"
|
||||
run = [ "escape --visual", "plugin --sync vidir" ]
|
||||
desc = "Bulk rename with vidir"
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This plugin is MIT-licensed. For more information check the [LICENSE](LICENSE) file.
|
||||
9
config/yazi/plugins/vidir.yazi/main.lua
Normal file
9
config/yazi/plugins/vidir.yazi/main.lua
Normal file
@ -0,0 +1,9 @@
|
||||
--- @sync entry
|
||||
--- @since 25.2.7
|
||||
|
||||
return {
|
||||
entry = function()
|
||||
-- If no selection, use current directory (.)
|
||||
ya.manager_emit("shell", { "vidir .", block = true, confirm = true })
|
||||
end,
|
||||
}
|
||||
@ -56,7 +56,7 @@ play = [
|
||||
rules = [
|
||||
{name = "*/", use = [ "edit", "open", "reveal" ]},
|
||||
{mime = "text/*", use = [ "edit", "reveal" ]},
|
||||
{mime = "image/*", use = [ "open", "reveal" ]},
|
||||
{mime = "image/*", use = [ "reveal" ]},
|
||||
{mime = "{audio,video}/*", use = [ "play", "reveal" ]},
|
||||
{mime = "inode/x-empty", use = [ "edit", "reveal" ]},
|
||||
{mime = "application/*zip", use = [ "extract", "reveal" ]},
|
||||
@ -77,47 +77,65 @@ suppress_preload = false
|
||||
[plugin]
|
||||
|
||||
preloaders = [
|
||||
# Image
|
||||
{mime = "image/*", run = "image"},
|
||||
# Video
|
||||
{mime = "video/*", run = "video"},
|
||||
# PDF
|
||||
{mime = "application/pdf", run = "pdf"},
|
||||
]
|
||||
prepend_preloaders = [
|
||||
# Office Documents
|
||||
{mime = "application/openxmlformats-officedocument.*", run = "office"},
|
||||
{mime = "application/oasis.opendocument.*", run = "office"},
|
||||
{mime = "application/ms-*", run = "office"},
|
||||
{mime = "application/msword", run = "office"},
|
||||
{name = "*.docx", run = "office"},
|
||||
{mime = "{audio,video,image}/*", run = "mediainfo"},
|
||||
{mime = "application/subrip", run = "mediainfo"},
|
||||
]
|
||||
previewers = [
|
||||
{name = "*/", run = "folder", sync = true},
|
||||
# Code
|
||||
{mime = "text/*", run = "code"},
|
||||
{mime = "*/{xml,javascript,x-wine-extension-ini}", run = "code"},
|
||||
# JSON
|
||||
{mime = "application/json", run = "code"},
|
||||
# Image
|
||||
{mime = "image/vnd.djvu", run = "noop"},
|
||||
# {mime = "image/*", run = "image"},
|
||||
# Video
|
||||
# {mime = "video/*", run = "video"},
|
||||
# PDF
|
||||
# {mime = "application/pdf", run = "pdf"},
|
||||
{mime = "application/pdf", run = "pdf"},
|
||||
# Fallback
|
||||
{name = "*", run = "file"},
|
||||
]
|
||||
prepend_previewers = [ ]
|
||||
|
||||
append_previewers = [
|
||||
{name = "*.ipynb", run = "nbpreview"},
|
||||
{mime = "application/x-bittorrent", run = "torrent-preview"},
|
||||
{mime = "audio/*", run = "exifaudio"},
|
||||
prepend_previewers = [
|
||||
{mime = "text/csv", run = "miller"},
|
||||
{name = "*.{md,mdx,markdown}", run = "glow"},
|
||||
# mediainfo
|
||||
{mime = "{audio,video,image}/*", run = "mediainfo"},
|
||||
{mime = "application/subrip", run = "mediainfo"},
|
||||
# rich preview
|
||||
{name = "*.csv", run = "rich-preview"}, # for csv files
|
||||
{name = "*.{md,mdx,markdown}", run = "rich-preview"}, # for markdown (.md) files
|
||||
{name = "*.rst", run = "rich-preview"}, # for restructured text (.rst) files
|
||||
{name = "*.ipynb", run = "rich-preview"}, # for jupyter notebooks (.ipynb)
|
||||
{name = "*.json", run = "rich-preview"}, # for json (.json) files
|
||||
{mime = "application/bittorrent", run = "torrent-preview"},
|
||||
# Archive previewer
|
||||
{mime = "application/*zip", run = "ouch"},
|
||||
{mime = "application/x-{tar,bzip*,7z-compressed,xz,rar}", run = "ouch"},
|
||||
{mime = "application/tar", run = "ouch"},
|
||||
{mime = "application/bzip2", run = "ouch"},
|
||||
{mime = "application/7z-compressed", run = "ouch"},
|
||||
{mime = "application/rar", run = "ouch"},
|
||||
{mime = "application/xz", run = "ouch"},
|
||||
# Office Documents
|
||||
{mime = "application/openxmlformats-officedocument.*", run = "office"},
|
||||
{mime = "application/oasis.opendocument.*", run = "office"},
|
||||
{mime = "application/ms-*", run = "office"},
|
||||
{mime = "application/msword", run = "office"},
|
||||
{name = "*.docx", run = "office"},
|
||||
]
|
||||
|
||||
append_previewers = [
|
||||
{name = "*", run = "hexyl"},
|
||||
]
|
||||
|
||||
prepend_fetchers = [
|
||||
{id = "git", name = "*", run = "git"},
|
||||
{id = "git", name = "*/", run = "git"},
|
||||
{id = "mime", name = "*", run = "mime-ext", prio = "high"},
|
||||
]
|
||||
|
||||
[input]
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=File Manager
|
||||
Exec=/usr/bin/alacritty -e yazi %u
|
||||
Exec=/usr/bin/{{terminal}} -e yazi %u
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Text editor
|
||||
Exec=/usr/bin/alacritty -e nvim %u
|
||||
Exec=/usr/bin/{{terminal}} -e nvim %u
|
||||
|
||||
Loading…
Reference in New Issue
Block a user