mirror of
https://github.com/sxyazi/yazi.git
synced 2024-11-23 17:32:50 +03:00
Compare commits
6 Commits
541314fb8f
...
de23243473
Author | SHA1 | Date | |
---|---|---|---|
|
de23243473 | ||
|
428c922703 | ||
|
2f65ec961b | ||
|
ce8013c97e | ||
|
b1104860bf | ||
|
22e7d579d2 |
@ -1,4 +1,4 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
# Code of Conduct
|
||||
|
||||
## Goal
|
||||
|
||||
@ -21,7 +21,7 @@ Our standards are as follows:
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
- Trolling, insulting or derogatory comments, and personal attacks
|
||||
- Harasing or bullying another person
|
||||
- Harassing or bullying another person
|
||||
- Publishing others' private information without their explicit permission
|
||||
- Posting things unrelated to the topic being discussed
|
||||
- Other conduct that could reasonably be considered inappropriate in a professional setting
|
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -3550,6 +3550,7 @@ dependencies = [
|
||||
"mlua",
|
||||
"parking_lot",
|
||||
"ratatui",
|
||||
"serde_json",
|
||||
"shell-words",
|
||||
"syntect",
|
||||
"tokio",
|
||||
|
@ -1 +1 @@
|
||||
{"flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","ffmpegthumbnailer","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek","cwds","tcsi","Hyprland","Wayfire","SWAYSOCK","btime","nsec","codegen","gethostname","fchmod","fdfind","Rustc","rustc","Sysinfo"],"language":"en","version":"0.2"}
|
||||
{"language":"en","flagWords":[],"words":["Punct","KEYMAP","splitn","crossterm","YAZI","unar","peekable","ratatui","syntect","pbpaste","pbcopy","oneshot","Posix","Lsar","XADDOS","zoxide","cands","Deque","precache","imageops","IFBLK","IFCHR","IFDIR","IFIFO","IFLNK","IFMT","IFSOCK","IRGRP","IROTH","IRUSR","ISGID","ISUID","ISVTX","IWGRP","IWOTH","IWUSR","IXGRP","IXOTH","IXUSR","libc","winsize","TIOCGWINSZ","xpixel","ypixel","ioerr","appender","Catppuccin","macchiato","gitmodules","Dotfiles","bashprofile","vimrc","flac","webp","exiftool","mediainfo","ripgrep","nvim","indexmap","indexmap","unwatch","canonicalize","serde","fsevent","Ueberzug","iterm","wezterm","sixel","chafa","ueberzugpp","️ Überzug","️ Überzug","Konsole","Alacritty","Überzug","pkgs","paru","unarchiver","pdftoppm","poppler","prebuild","singlefile","jpegopt","EXIF","rustfmt","mktemp","nanos","xclip","xsel","natord","Mintty","nixos","nixpkgs","SIGTSTP","SIGCONT","SIGCONT","mlua","nonstatic","userdata","metatable","natsort","backstack","luajit","Succ","Succ","cand","fileencoding","foldmethod","lightgreen","darkgray","lightred","lightyellow","lightcyan","nushell","msvc","aarch","linemode","sxyazi","rsplit","ZELLIJ","bitflags","bitflags","USERPROFILE","Neovim","vergen","gitcl","Renderable","preloaders","prec","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime","magick","magick","prefetcher","Prework","prefetchers","PREWORKERS","conds","translit","rxvt","Urxvt","realpath","realname","REPARSE","hardlink","hardlinking","nlink","nlink","linemodes","SIGSTOP","sevenzip","rsplitn","replacen","DECSET","DECRQM","repeek","cwds","tcsi","Hyprland","Wayfire","SWAYSOCK","btime","nsec","codegen","gethostname","fchmod","fdfind","Rustc","rustc","Sysinfo","ffprobe","vframes"],"version":"0.2"}
|
@ -76,20 +76,21 @@ impl Actions {
|
||||
|
||||
writeln!(s, "\nDependencies")?;
|
||||
#[rustfmt::skip]
|
||||
writeln!(s, " file : {}", Self::process_output(env::var_os("YAZI_FILE_ONE").unwrap_or("file".into()), "--version"))?;
|
||||
writeln!(s, " ueberzugpp : {}", Self::process_output("ueberzugpp", "--version"))?;
|
||||
writeln!(s, " ffmpegthumbnailer: {}", Self::process_output("ffmpegthumbnailer", "-v"))?;
|
||||
writeln!(s, " pdftoppm : {}", Self::process_output("pdftoppm", "--help"))?;
|
||||
writeln!(s, " magick : {}", Self::process_output("magick", "--version"))?;
|
||||
writeln!(s, " fzf : {}", Self::process_output("fzf", "--version"))?;
|
||||
writeln!(s, " fd : {}", Self::process_output("fd", "--version"))?;
|
||||
writeln!(s, " fdfind : {}", Self::process_output("fdfind", "--version"))?;
|
||||
writeln!(s, " rg : {}", Self::process_output("rg", "--version"))?;
|
||||
writeln!(s, " chafa : {}", Self::process_output("chafa", "--version"))?;
|
||||
writeln!(s, " zoxide : {}", Self::process_output("zoxide", "--version"))?;
|
||||
writeln!(s, " 7z : {}", Self::process_output("7z", "i"))?;
|
||||
writeln!(s, " 7zz : {}", Self::process_output("7zz", "i"))?;
|
||||
writeln!(s, " jq : {}", Self::process_output("jq", "--version"))?;
|
||||
writeln!(s, " file : {}", Self::process_output(env::var_os("YAZI_FILE_ONE").unwrap_or("file".into()), "--version"))?;
|
||||
writeln!(s, " ueberzugpp : {}", Self::process_output("ueberzugpp", "--version"))?;
|
||||
#[rustfmt::skip]
|
||||
writeln!(s, " ffmpeg/ffprobe: {} / {}", Self::process_output("ffmpeg", "-version"), Self::process_output("ffprobe", "-version"))?;
|
||||
writeln!(s, " pdftoppm : {}", Self::process_output("pdftoppm", "--help"))?;
|
||||
writeln!(s, " magick : {}", Self::process_output("magick", "--version"))?;
|
||||
writeln!(s, " fzf : {}", Self::process_output("fzf", "--version"))?;
|
||||
#[rustfmt::skip]
|
||||
writeln!(s, " fd/fdfind : {} / {}", Self::process_output("fd", "--version"), Self::process_output("fdfind", "--version"))?;
|
||||
writeln!(s, " rg : {}", Self::process_output("rg", "--version"))?;
|
||||
writeln!(s, " chafa : {}", Self::process_output("chafa", "--version"))?;
|
||||
writeln!(s, " zoxide : {}", Self::process_output("zoxide", "--version"))?;
|
||||
#[rustfmt::skip]
|
||||
writeln!(s, " 7z/7zz : {} / {}", Self::process_output("7z", "i"), Self::process_output("7zz", "i"))?;
|
||||
writeln!(s, " jq : {}", Self::process_output("jq", "--version"))?;
|
||||
|
||||
writeln!(s, "\nClipboard")?;
|
||||
#[rustfmt::skip]
|
||||
|
@ -190,14 +190,15 @@ rules = [
|
||||
{ mime = "{audio,video}/*", fg = "magenta" },
|
||||
|
||||
# Archives
|
||||
{ mime = "application/{,g}zip", fg = "red" },
|
||||
{ mime = "application/x-{tar,bzip*,7z-compressed,xz,rar}", fg = "red" },
|
||||
{ mime = "application/{zip,rar,tar,gzip,xz,zstd,bzip*,zlib,lzma,compress,compressed,archive,cpio,arj,deflate,xar}", fg = "red" },
|
||||
{ mime = "application/{zip,rar,7z,gzip,arj}-compressed", fg = "red" },
|
||||
{ mime = "application/vnd.ms-cab-compressed", fg = "red" },
|
||||
|
||||
# Documents
|
||||
{ mime = "application/{pdf,doc,rtf,vnd.*}", fg = "cyan" },
|
||||
|
||||
# Empty files
|
||||
# { mime = "inode/x-empty", fg = "red" },
|
||||
# { mime = "inode/empty", fg = "red" },
|
||||
|
||||
# Special files
|
||||
{ name = "*", is = "orphan", bg = "red" },
|
||||
|
@ -67,13 +67,18 @@ rules = [
|
||||
# Media
|
||||
{ mime = "{audio,video}/*", use = [ "play", "reveal" ] },
|
||||
# Archive
|
||||
{ mime = "application/{,g}zip", use = [ "extract", "reveal" ] },
|
||||
{ mime = "application/x-{tar,bzip*,7z-compressed,xz,rar}", use = [ "extract", "reveal" ] },
|
||||
{ mime = "application/{zip,rar,tar,gzip,xz,zstd,bzip*,zlib,lzma,compress,compressed,archive,cpio,arj,deflate,xar}", use = [ "extract", "reveal" ] },
|
||||
{ mime = "application/{zip,rar,7z,gzip,arj}-compressed", use = [ "extract", "reveal" ] },
|
||||
{ mime = "application/{debian-package,redhat-package-manager,rpm}", use = [ "extract", "reveal" ] },
|
||||
{ mime = "application/vnd.debian.binary-package", use = [ "extract", "reveal" ] },
|
||||
{ mime = "application/vnd.android.package-archive", use = [ "extract", "reveal" ] },
|
||||
{ mime = "application/vnd.ms-cab-compressed", use = [ "extract", "reveal" ] },
|
||||
{ name = "*.{AppImage,appimage}", use = [ "extract", "reveal" ] },
|
||||
# JSON
|
||||
{ mime = "application/{json,x-ndjson}", use = [ "edit", "reveal" ] },
|
||||
{ mime = "application/{json,ndjson}", use = [ "edit", "reveal" ] },
|
||||
{ mime = "*/javascript", use = [ "edit", "reveal" ] },
|
||||
# Empty file
|
||||
{ mime = "inode/x-empty", use = [ "edit", "reveal" ] },
|
||||
{ mime = "inode/empty", use = [ "edit", "reveal" ] },
|
||||
# Fallback
|
||||
{ name = "*", use = [ "open", "reveal" ] },
|
||||
]
|
||||
@ -96,7 +101,7 @@ spotters = [
|
||||
{ name = "*/", run = "folder" },
|
||||
# Code
|
||||
{ mime = "text/*", run = "code" },
|
||||
{ mime = "*/{xml,javascript,x-wine-extension-ini}", run = "code" },
|
||||
{ mime = "*/{xml,javascript,wine-extension-ini}", run = "code" },
|
||||
# Image
|
||||
{ mime = "image/{avif,hei?,jxl,svg+xml}", run = "magick" },
|
||||
{ mime = "image/*", run = "image" },
|
||||
@ -121,9 +126,9 @@ previewers = [
|
||||
{ name = "*/", run = "folder", sync = true },
|
||||
# Code
|
||||
{ mime = "text/*", run = "code" },
|
||||
{ mime = "*/{xml,javascript,x-wine-extension-ini}", run = "code" },
|
||||
{ mime = "*/{xml,javascript,wine-extension-ini}", run = "code" },
|
||||
# JSON
|
||||
{ mime = "application/{json,x-ndjson}", run = "json" },
|
||||
{ mime = "application/{json,ndjson}", run = "json" },
|
||||
# Image
|
||||
{ mime = "image/{avif,hei?,jxl,svg+xml}", run = "magick" },
|
||||
{ mime = "image/*", run = "image" },
|
||||
@ -132,13 +137,25 @@ previewers = [
|
||||
# PDF
|
||||
{ mime = "application/pdf", run = "pdf" },
|
||||
# Archive
|
||||
{ mime = "application/{,g}zip", run = "archive" },
|
||||
{ mime = "application/x-{tar,bzip*,7z-compressed,xz,rar,iso9660-image}", run = "archive" },
|
||||
{ mime = "application/{zip,rar,tar,gzip,xz,zstd,bzip*,zlib,lzma,compress,compressed,archive,cpio,arj,deflate,xar}", run = "archive" },
|
||||
{ mime = "application/{zip,rar,7z,gzip,arj}-compressed", run = "archive" },
|
||||
{ mime = "application/{debian-package,redhat-package-manager,rpm}", run = "archive" },
|
||||
{ mime = "application/vnd.debian.binary-package", run = "archive" },
|
||||
{ mime = "application/vnd.android.package-archive", run = "archive" },
|
||||
{ mime = "application/vnd.ms-cab-compressed", run = "archive" },
|
||||
{ name = "*.{AppImage,appimage}", run = "archive" },
|
||||
# Virtual Disk / Disk Image
|
||||
{ mime = "application/iso9660-image", run = "archive" },
|
||||
{ mime = "application/{qemu,vhd,vhdx,vdi,vmdk}-disk", run = "archive" },
|
||||
{ mime = "application/{vhd,vmdk}", run = "archive" },
|
||||
{ mime = "application/virtualbox-{vdi,vhd,vhdx,vmdk}", run = "archive" },
|
||||
{ mime = "application/{ms-wim,apple-diskimage}", run = "archive" },
|
||||
{ name = "*.{fat,ext,ext2,ext3,ext4,squashfs,ntfs,hfs,hfsx,img}", run = "archive" },
|
||||
# Font
|
||||
{ mime = "font/*", run = "font" },
|
||||
{ mime = "application/vnd.ms-opentype", run = "font" },
|
||||
# Empty file
|
||||
{ mime = "inode/x-empty", run = "empty" },
|
||||
{ mime = "inode/empty", run = "empty" },
|
||||
# Fallback
|
||||
{ name = "*", run = "file" },
|
||||
]
|
||||
|
@ -32,6 +32,7 @@ md-5 = { workspace = true }
|
||||
mlua = { workspace = true }
|
||||
parking_lot = { workspace = true }
|
||||
ratatui = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
shell-words = { workspace = true }
|
||||
syntect = { version = "5.2.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] }
|
||||
tokio = { workspace = true }
|
||||
|
@ -26,6 +26,6 @@ function M:seek(units)
|
||||
})
|
||||
end
|
||||
|
||||
function M:spot(args) require("file"):spot(args) end
|
||||
function M:spot(job) require("file"):spot(job) end
|
||||
|
||||
return M
|
||||
|
@ -16,56 +16,10 @@ end
|
||||
|
||||
function M:seek() end
|
||||
|
||||
-- TODO: remove this
|
||||
local hovered_mime = ya.sync(function()
|
||||
local h = cx.active.current.hovered
|
||||
if not h then
|
||||
return nil
|
||||
elseif h.cha.is_dir then
|
||||
return "inode/directory"
|
||||
else
|
||||
return h:mime()
|
||||
end
|
||||
end)
|
||||
|
||||
function M:spot(args)
|
||||
local mime = hovered_mime()
|
||||
if not mime then
|
||||
return
|
||||
end
|
||||
|
||||
local file = args.file
|
||||
local spotter = PLUGIN.spotter(file.url, mime)
|
||||
local previewer = PLUGIN.previewer(file.url, mime)
|
||||
local fetchers = PLUGIN.fetchers(file.url, mime)
|
||||
local preloaders = PLUGIN.preloaders(file.url, mime)
|
||||
|
||||
for i, v in ipairs(fetchers) do
|
||||
fetchers[i] = v.cmd
|
||||
end
|
||||
for i, v in ipairs(preloaders) do
|
||||
preloaders[i] = v.cmd
|
||||
end
|
||||
|
||||
local rows = {}
|
||||
local row = function(key, value)
|
||||
local h = type(value) == "table" and #value or 1
|
||||
rows[#rows + 1] = ui.Row({ key, value }):height(h)
|
||||
end
|
||||
|
||||
rows[#rows + 1] = ui.Row({ "Metadata", "" }):style(ui.Style():fg("red"))
|
||||
row(" Created:", file.cha.btime and os.date("%y/%m/%d %H:%M", math.floor(file.cha.btime)) or "-")
|
||||
row(" Modified:", file.cha.mtime and os.date("%y/%m/%d %H:%M", math.floor(file.cha.mtime)) or "-")
|
||||
row(" Mimetype:", mime)
|
||||
rows[#rows + 1] = ui.Row({ { "", "Plugins" }, "" }):height(2):style(ui.Style():fg("red"))
|
||||
row(" Spotter:", spotter and spotter.cmd or "-")
|
||||
row(" Previewer:", previewer and previewer.cmd or "-")
|
||||
row(" Fetchers:", #fetchers ~= 0 and fetchers or "-")
|
||||
row(" Preloaders:", #preloaders ~= 0 and preloaders or "-")
|
||||
|
||||
function M:spot(job)
|
||||
ya.spot_table(
|
||||
args,
|
||||
ui.Table(rows)
|
||||
job,
|
||||
ui.Table(self:spot_base(job))
|
||||
:area(ui.Pos { "center", w = 60, h = 20 })
|
||||
:row(1)
|
||||
:col(1)
|
||||
@ -75,4 +29,33 @@ function M:spot(args)
|
||||
)
|
||||
end
|
||||
|
||||
function M:spot_base(job)
|
||||
local url, cha = job.file.url, job.file.cha
|
||||
local spotter = PLUGIN.spotter(url, job.mime)
|
||||
local previewer = PLUGIN.previewer(url, job.mime)
|
||||
local fetchers = PLUGIN.fetchers(url, job.mime)
|
||||
local preloaders = PLUGIN.preloaders(url, job.mime)
|
||||
|
||||
for i, v in ipairs(fetchers) do
|
||||
fetchers[i] = v.cmd
|
||||
end
|
||||
for i, v in ipairs(preloaders) do
|
||||
preloaders[i] = v.cmd
|
||||
end
|
||||
|
||||
return {
|
||||
ui.Row({ "Base" }):style(ui.Style():fg("green")),
|
||||
ui.Row { " Created:", cha.btime and os.date("%y/%m/%d %H:%M", math.floor(cha.btime)) or "-" },
|
||||
ui.Row { " Modified:", cha.mtime and os.date("%y/%m/%d %H:%M", math.floor(cha.mtime)) or "-" },
|
||||
ui.Row { " Mimetype:", job.mime },
|
||||
ui.Row {},
|
||||
|
||||
ui.Row({ "Plugins" }):style(ui.Style():fg("green")),
|
||||
ui.Row { " Spotter:", spotter and spotter.cmd or "-" },
|
||||
ui.Row { " Previewer:", previewer and previewer.cmd or "-" },
|
||||
ui.Row { " Fetchers:", #fetchers ~= 0 and fetchers or "-" },
|
||||
ui.Row { " Preloaders:", #preloaders ~= 0 and preloaders or "-" },
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
|
@ -40,6 +40,6 @@ function M:seek(units)
|
||||
end
|
||||
end
|
||||
|
||||
function M:spot(args) require("file"):spot(args) end
|
||||
function M:spot(job) require("file"):spot(job) end
|
||||
|
||||
return M
|
||||
|
@ -22,30 +22,31 @@ function M:preload()
|
||||
return ya.image_precache(self.file.url, cache) and 1 or 2
|
||||
end
|
||||
|
||||
function M:spot(args)
|
||||
local info = ya.image_info(args.file.url)
|
||||
|
||||
local rows = {}
|
||||
local row = function(key, value)
|
||||
local h = type(value) == "table" and #value or 1
|
||||
rows[#rows + 1] = ui.Row({ key, value }):height(h)
|
||||
end
|
||||
|
||||
row("Format:", tostring(info.format))
|
||||
row("Width:", string.format("%dpx", info.w))
|
||||
row("Height:", string.format("%dpx", info.h))
|
||||
row("Color:", tostring(info.color))
|
||||
function M:spot(job)
|
||||
local rows = self:spot_base(job)
|
||||
rows[#rows + 1] = ui.Row {}
|
||||
|
||||
ya.spot_table(
|
||||
args,
|
||||
ui.Table(rows)
|
||||
job,
|
||||
ui.Table(ya.list_merge(rows, require("file"):spot_base(job)))
|
||||
:area(ui.Pos { "center", w = 60, h = 20 })
|
||||
:row(args.skip)
|
||||
:row(job.skip)
|
||||
:row(1)
|
||||
:col(1)
|
||||
:col_style(ui.Style():fg("blue"))
|
||||
:cell_style(ui.Style():fg("yellow"):reverse())
|
||||
:widths { ui.Constraint.Length(12), ui.Constraint.Fill(1) }
|
||||
:widths { ui.Constraint.Length(14), ui.Constraint.Fill(1) }
|
||||
)
|
||||
end
|
||||
|
||||
function M:spot_base(job)
|
||||
local info = ya.image_info(job.file.url)
|
||||
return {
|
||||
ui.Row({ "Image" }):style(ui.Style():fg("green")),
|
||||
ui.Row { " Format:", tostring(info.format) },
|
||||
ui.Row { " Size:", string.format("%dx%d", info.w, info.h) },
|
||||
ui.Row { " Color:", tostring(info.color) },
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
||||
|
@ -41,6 +41,6 @@ function M:preload()
|
||||
return status and status.success and 1 or 2
|
||||
end
|
||||
|
||||
function M:spot(args) require("file"):spot(args) end
|
||||
function M:spot(job) require("file"):spot(job) end
|
||||
|
||||
return M
|
||||
|
@ -3,15 +3,15 @@ local SUPPORTED_TYPES = "application/audio/biosig/chemical/font/image/inode/mess
|
||||
local M = {}
|
||||
|
||||
local function match_mimetype(s)
|
||||
local type, sub = s:match("([-a-z]+/)([+-.a-zA-Z0-9]+)%s*$")
|
||||
if type and sub and SUPPORTED_TYPES:find(type, 1, true) then
|
||||
return type .. sub
|
||||
local type, sub = s:match("^([-a-z]+/)([+-.a-zA-Z0-9]+)%s*$")
|
||||
if type and sub and SUPPORTED_TYPES:find(type, 1, true) then
|
||||
return type:gsub("^x%-", "", 1) .. sub:gsub("^x%-", "", 1)
|
||||
end
|
||||
end
|
||||
|
||||
function M:fetch(args)
|
||||
function M:fetch(job)
|
||||
local urls = {}
|
||||
for _, file in ipairs(args.files) do
|
||||
for _, file in ipairs(job.files) do
|
||||
urls[#urls + 1] = tostring(file.url)
|
||||
end
|
||||
|
||||
@ -44,9 +44,7 @@ function M:fetch(args)
|
||||
end
|
||||
|
||||
valid = match_mimetype(line)
|
||||
if valid and line:find(valid, 1, true) ~= 1 then
|
||||
goto continue
|
||||
elseif valid then
|
||||
if valid then
|
||||
j, updates[urls[i]] = j + 1, valid
|
||||
flush(false)
|
||||
end
|
||||
|
@ -38,23 +38,29 @@ function M:preload()
|
||||
return 1
|
||||
end
|
||||
|
||||
local child, code = Command("ffmpegthumbnailer"):args({
|
||||
"-q",
|
||||
"6",
|
||||
"-c",
|
||||
"jpeg",
|
||||
"-i",
|
||||
tostring(self.file.url),
|
||||
"-o",
|
||||
tostring(cache),
|
||||
"-t",
|
||||
tostring(percent),
|
||||
"-s",
|
||||
tostring(PREVIEW.max_width),
|
||||
local meta, err = self.list_meta(self.file.url, "format=duration")
|
||||
if not meta then
|
||||
ya.err(tostring(err))
|
||||
return 0
|
||||
end
|
||||
|
||||
local ss = math.floor(meta.format.duration * percent / 100)
|
||||
local qv = 31 - math.floor(PREVIEW.image_quality * 0.3)
|
||||
-- stylua: ignore
|
||||
local child, code = Command("ffmpeg"):args({
|
||||
"-v", "quiet",
|
||||
"-skip_frame", "nokey", "-ss", ss,
|
||||
"-an", "-sn", "-dn",
|
||||
"-i", tostring(self.file.url),
|
||||
"-vframes", 1,
|
||||
"-q:v", qv,
|
||||
"-vf", string.format("scale=%d:-2:flags=fast_bilinear", PREVIEW.max_width),
|
||||
"-f", "image2",
|
||||
"-y", tostring(cache),
|
||||
}):spawn()
|
||||
|
||||
if not child then
|
||||
ya.err("spawn `ffmpegthumbnailer` command returns " .. tostring(code))
|
||||
ya.err("Spawn `ffmpeg` process returns " .. tostring(code))
|
||||
return 0
|
||||
end
|
||||
|
||||
@ -62,6 +68,66 @@ function M:preload()
|
||||
return status and status.success and 1 or 2
|
||||
end
|
||||
|
||||
function M:spot(args) require("file"):spot(args) end
|
||||
function M:spot(job)
|
||||
local rows = self:spot_base(job)
|
||||
rows[#rows + 1] = ui.Row {}
|
||||
|
||||
ya.spot_table(
|
||||
job,
|
||||
ui.Table(ya.list_merge(rows, require("file"):spot_base(job)))
|
||||
:area(ui.Pos { "center", w = 60, h = 20 })
|
||||
:row(1)
|
||||
:col(1)
|
||||
:col_style(ui.Style():fg("blue"))
|
||||
:cell_style(ui.Style():fg("yellow"):reverse())
|
||||
:widths { ui.Constraint.Length(14), ui.Constraint.Fill(1) }
|
||||
)
|
||||
end
|
||||
|
||||
function M:spot_base(job)
|
||||
local meta, err = self.list_meta(job.file.url, "format=duration:stream=codec_name,codec_type,width,height")
|
||||
if not meta then
|
||||
ya.err(tostring(err))
|
||||
return {}
|
||||
end
|
||||
|
||||
local dur = meta.format.duration
|
||||
local rows = {
|
||||
ui.Row({ "Video" }):style(ui.Style():fg("green")),
|
||||
ui.Row { " Codec:", meta.streams[1].codec_name },
|
||||
ui.Row { " Duration:", string.format("%d:%02d", math.floor(dur / 60), math.floor(dur % 60)) },
|
||||
}
|
||||
|
||||
for i, s in ipairs(meta.streams) do
|
||||
if s.codec_type == "video" then
|
||||
rows[#rows + 1] = ui.Row { string.format(" Stream %d:", i), "video" }
|
||||
rows[#rows + 1] = ui.Row { " Codec:", s.codec_name }
|
||||
rows[#rows + 1] = ui.Row { " Size:", string.format("%dx%d", s.width, s.height) }
|
||||
elseif s.codec_type == "audio" then
|
||||
rows[#rows + 1] = ui.Row { string.format(" Stream %d:", i), "audio" }
|
||||
rows[#rows + 1] = ui.Row { " Codec:", s.codec_name }
|
||||
end
|
||||
end
|
||||
return rows
|
||||
end
|
||||
|
||||
function M.list_meta(url, entries)
|
||||
local output, err =
|
||||
Command("ffprobe"):args({ "-v", "quiet", "-show_entries", entries, "-of", "json=c=1", tostring(url) }):output()
|
||||
if not output then
|
||||
return nil, Err("Spawn `ffprobe` process returns %s", err)
|
||||
end
|
||||
|
||||
local t = ya.json_decode(output.stdout)
|
||||
if not t then
|
||||
return nil, Err("Failed to decode `ffprobe` output: %s", output.stdout)
|
||||
elseif type(t) ~= "table" then
|
||||
return nil, Err("Invalid `ffprobe` output: %s", output.stdout)
|
||||
end
|
||||
|
||||
t.format = t.format or {}
|
||||
t.streams = t.streams or {}
|
||||
return t
|
||||
end
|
||||
|
||||
return M
|
||||
|
@ -1,5 +1,4 @@
|
||||
os.setlocale("")
|
||||
package.path = BOOT.plugin_dir .. "/?.yazi/init.lua;" .. package.path
|
||||
|
||||
require("dds"):setup()
|
||||
require("extract"):setup()
|
||||
|
@ -1,4 +1,5 @@
|
||||
table.unpack = table.unpack or unpack
|
||||
function Err(s, ...) return Error.custom(string.format(s, ...)) end
|
||||
|
||||
function ya.clamp(min, x, max)
|
||||
if x < min then
|
||||
|
25
yazi-plugin/src/error.rs
Normal file
25
yazi-plugin/src/error.rs
Normal file
@ -0,0 +1,25 @@
|
||||
use mlua::{Lua, MetaMethod, UserData, UserDataMethods};
|
||||
|
||||
pub enum Error {
|
||||
Serde(serde_json::Error),
|
||||
Custom(String),
|
||||
}
|
||||
|
||||
impl Error {
|
||||
pub fn install(lua: &Lua) -> mlua::Result<()> {
|
||||
let new = lua.create_function(|_, msg: String| Ok(Error::Custom(msg)))?;
|
||||
|
||||
lua.globals().raw_set("Error", lua.create_table_from([("custom", new)])?)
|
||||
}
|
||||
}
|
||||
|
||||
impl UserData for Error {
|
||||
fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
|
||||
methods.add_meta_method(MetaMethod::ToString, |_, me, ()| {
|
||||
Ok(match me {
|
||||
Error::Serde(e) => e.to_string(),
|
||||
Error::Custom(s) => s.clone(),
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@ pub fn slim_lua(name: &str) -> mlua::Result<Lua> {
|
||||
crate::file::pour(&lua)?;
|
||||
crate::url::pour(&lua)?;
|
||||
|
||||
crate::Error::install(&lua)?;
|
||||
crate::loader::install_isolate(&lua)?;
|
||||
crate::process::install(&lua)?;
|
||||
|
||||
|
@ -62,7 +62,7 @@ pub fn peek(
|
||||
|
||||
if let Err(e) = result {
|
||||
if !e.to_string().contains("Peek task cancelled") {
|
||||
error!("{e:?}");
|
||||
error!("{e}");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -58,7 +58,7 @@ pub fn spot(
|
||||
|
||||
if let Err(e) = result {
|
||||
if !e.to_string().contains("Spot task cancelled") {
|
||||
error!("{e:?}");
|
||||
error!("{e}");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -6,7 +6,7 @@ yazi_macro::mod_pub!(
|
||||
bindings, elements, external, file, fs, isolate, loader, process, pubsub, url, utils
|
||||
);
|
||||
|
||||
yazi_macro::mod_flat!(clipboard config lua runtime);
|
||||
yazi_macro::mod_flat!(clipboard config error lua runtime);
|
||||
|
||||
pub fn init() -> anyhow::Result<()> {
|
||||
CLIPBOARD.with(<_>::default);
|
||||
|
@ -26,6 +26,7 @@ fn stage_1(lua: &'static Lua) -> Result<()> {
|
||||
globals.raw_set("ya", crate::utils::compose(lua, false)?)?;
|
||||
globals.raw_set("ps", crate::pubsub::compose(lua)?)?;
|
||||
|
||||
crate::Error::install(lua)?;
|
||||
crate::bindings::Cha::install(lua)?;
|
||||
crate::loader::install(lua)?;
|
||||
crate::file::pour(lua)?;
|
||||
|
24
yazi-plugin/src/utils/json.rs
Normal file
24
yazi-plugin/src/utils/json.rs
Normal file
@ -0,0 +1,24 @@
|
||||
use mlua::{Function, IntoLuaMulti, Lua, LuaSerdeExt, Value};
|
||||
|
||||
use super::Utils;
|
||||
use crate::Error;
|
||||
|
||||
impl Utils {
|
||||
pub(super) fn json_encode(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_async_function(|lua, value: Value| async move {
|
||||
match serde_json::to_string(&value) {
|
||||
Ok(s) => (s, Value::Nil).into_lua_multi(&lua),
|
||||
Err(e) => (Value::Nil, Error::Serde(e)).into_lua_multi(&lua),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn json_decode(lua: &Lua) -> mlua::Result<Function> {
|
||||
lua.create_async_function(|lua, s: mlua::String| async move {
|
||||
match serde_json::from_slice::<serde_json::Value>(&s.as_bytes()) {
|
||||
Ok(v) => (lua.to_value(&v)?, Value::Nil).into_lua_multi(&lua),
|
||||
Err(e) => (Value::Nil, Error::Serde(e)).into_lua_multi(&lua),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
#![allow(clippy::module_inception)]
|
||||
|
||||
yazi_macro::mod_flat!(
|
||||
app cache call image layer log preview spot sync target text time user utils
|
||||
app cache call image json layer log preview spot sync target text time user utils
|
||||
);
|
||||
|
@ -23,6 +23,10 @@ pub fn compose(lua: &Lua, isolate: bool) -> mlua::Result<Table> {
|
||||
b"image_show" => Utils::image_show(lua)?,
|
||||
b"image_precache" => Utils::image_precache(lua)?,
|
||||
|
||||
// JSON
|
||||
b"json_encode" => Utils::json_encode(lua)?,
|
||||
b"json_decode" => Utils::json_decode(lua)?,
|
||||
|
||||
// Layout
|
||||
b"which" => Utils::which(lua)?,
|
||||
b"input" => Utils::input(lua)?,
|
||||
|
Loading…
Reference in New Issue
Block a user