include plugins

This commit is contained in:
Simon Belmont 2025-05-08 20:48:25 -04:00
parent ae61234858
commit cd81d7b2b4
21 changed files with 1201 additions and 0 deletions

View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 ndtoan96
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -0,0 +1,79 @@
# ouch.yazi
[ouch](https://github.com/ouch-org/ouch) plugin for [Yazi](https://github.com/sxyazi/yazi).
![ouch.yazi](https://github.com/ndtoan96/ouch.yazi/assets/33489972/946397ec-b37b-4bf4-93f1-c676fc8e59f2)
## Features
- Archive preview
- Compression
## Installation
### Yazi package manager
```bash
ya pack -a ndtoan96/ouch
```
### Git
```bash
# Linux/macOS
git clone https://github.com/ndtoan96/ouch.yazi.git ~/.config/yazi/plugins/ouch.yazi
# Windows with cmd
git clone https://github.com/ndtoan96/ouch.yazi.git %AppData%\yazi\config\plugins\ouch.yazi
# Windows with powershell
git clone https://github.com/ndtoan96/ouch.yazi.git "$($env:APPDATA)\yazi\config\plugins\ouch.yazi"
```
Make sure you have [ouch](https://github.com/ouch-org/ouch) installed and in your `PATH`.
## Usage
### Preview
For archive preview, add this to your `yazi.toml`:
```toml
[plugin]
prepend_previewers = [
# Archive previewer
{ mime = "application/*zip", run = "ouch" },
{ mime = "application/x-tar", run = "ouch" },
{ mime = "application/x-bzip2", run = "ouch" },
{ mime = "application/x-7z-compressed", run = "ouch" },
{ mime = "application/x-rar", run = "ouch" },
{ mime = "application/x-xz", run = "ouch" },
{ mime = "application/xz", run = "ouch" },
]
```
Now go to an archive on Yazi, you should see the archive's content in the preview pane. You can use `J` and `K` to roll up and down the preview.
If you want to change the icon or the style of text, you can modify the `peek` function in `init.lua` file (all of them are stored in the `lines` variable).
### Compression
For compession, add this to your `keymap.toml`:
```toml
[[manager.prepend_keymap]]
on = ["C"]
run = "plugin ouch"
desc = "Compress with ouch"
```
The plugin uses `zip` format by default. You can change the format when you name the output file, `ouch` will detect format based on file extension.
And, for example, if you would like to set `7z` as default format, you can use `plugin ouch 7z`.
### Decompression
This plugin does not provide a decompression feature because it already is supported by Yazi.
To decompress with `ouch`, configure the opener in `yazi.toml`.
```toml
[opener]
extract = [
{ run = 'ouch d -y "%*"', desc = "Extract here with ouch", for = "windows" },
{ run = 'ouch d -y "$@"', desc = "Extract here with ouch", for = "unix" },
]
```

View file

@ -0,0 +1,148 @@
local M = {}
function M:peek(job)
local child = Command("ouch")
:args({ "l", "-t", "-y", tostring(job.file.url) })
:stdout(Command.PIPED)
:stderr(Command.PIPED)
:spawn()
local limit = job.area.h
local file_name = string.match(tostring(job.file.url), ".*[/\\](.*)")
local lines = string.format("📁 \x1b[2m%s\x1b[0m\n", file_name)
local num_lines = 1
local num_skip = 0
repeat
local line, event = child:read_line()
if event == 1 then
ya.err(tostring(event))
elseif event ~= 0 then
break
end
if line:find('Archive', 1, true) ~= 1 and line:find('[INFO]', 1, true) ~= 1 then
if num_skip >= job.skip then
lines = lines .. line
num_lines = num_lines + 1
else
num_skip = num_skip + 1
end
end
until num_lines >= limit
child:start_kill()
if job.skip > 0 and num_lines < limit then
ya.manager_emit(
"peek",
{ tostring(math.max(0, job.skip - (limit - num_lines))), only_if = tostring(job.file.url), upper_bound = "" }
)
else
ya.preview_widgets(job, { ui.Text(lines):area(job.area) })
end
end
function M:seek(job)
local h = cx.active.current.hovered
if h and h.url == job.file.url then
local step = math.floor(job.units * job.area.h / 10)
ya.manager_emit("peek", {
math.max(0, cx.active.preview.skip + step),
only_if = tostring(job.file.url),
})
end
end
-- Check if file exists
local function file_exists(name)
local f = io.open(name, "r")
if f ~= nil then
io.close(f)
return true
else
return false
end
end
-- Get the files that need to be compressed and infer a default archive name
local get_compression_target = ya.sync(function()
local tab = cx.active
local default_name
local paths = {}
if #tab.selected == 0 then
if tab.current.hovered then
local name = tab.current.hovered.name
default_name = name
table.insert(paths, name)
else
return
end
else
default_name = tab.current.cwd.name
for _, url in pairs(tab.selected) do
table.insert(paths, tostring(url))
end
-- The compression targets are aquired, now unselect them
ya.manager_emit("escape", {})
end
return paths, default_name
end)
local function invoke_compress_command(paths, name)
local cmd_output, err_code = Command("ouch")
:args({ "c", "-y" })
:args(paths)
:arg(name)
:stderr(Command.PIPED)
:output()
if err_code ~= nil then
ya.notify({
title = "Failed to run ouch command",
content = "Status: " .. err_code,
timeout = 5.0,
level = "error",
})
elseif not cmd_output.status.success then
ya.notify({
title = "Compression failed: status code " .. cmd_output.status.code,
content = cmd_output.stderr,
timeout = 5.0,
level = "error",
})
end
end
function M:entry(job)
local default_fmt = job.args[1]
if default_fmt == nil then
default_fmt = "zip"
end
ya.manager_emit("escape", { visual = true })
-- Get the files that need to be compressed and infer a default archive name
local paths, default_name = get_compression_target()
-- Get archive name from user
local output_name, name_event = ya.input({
title = "Create archive:",
value = default_name .. "." .. default_fmt,
position = { "top-center", y = 3, w = 40 },
})
if name_event ~= 1 then
return
end
-- Get confirmation if file exists
if file_exists(output_name) then
local confirm, confirm_event = ya.input({
title = "Overwrite " .. output_name .. "? (y/N)",
position = { "top-center", y = 3, w = 40 },
})
if not (confirm_event == 1 and confirm:lower() == "y") then
return
end
end
invoke_compress_command(paths, output_name)
end
return M