diff options
Diffstat (limited to 'fedora/.config/yazi/plugins/compress.yazi')
| -rw-r--r-- | fedora/.config/yazi/plugins/compress.yazi/LICENSE | 21 | ||||
| -rw-r--r-- | fedora/.config/yazi/plugins/compress.yazi/README.md | 173 | ||||
| -rw-r--r-- | fedora/.config/yazi/plugins/compress.yazi/main.lua | 496 |
3 files changed, 0 insertions, 690 deletions
diff --git a/fedora/.config/yazi/plugins/compress.yazi/LICENSE b/fedora/.config/yazi/plugins/compress.yazi/LICENSE deleted file mode 100644 index 7ce7a2f..0000000 --- a/fedora/.config/yazi/plugins/compress.yazi/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 CiarΓ‘n O'Brien - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/fedora/.config/yazi/plugins/compress.yazi/README.md b/fedora/.config/yazi/plugins/compress.yazi/README.md deleted file mode 100644 index ae1f329..0000000 --- a/fedora/.config/yazi/plugins/compress.yazi/README.md +++ /dev/null @@ -1,173 +0,0 @@ -<h1 align="center">ποΈ compress.yazi</h1> -<p align="center"> - <b>A blazing fast, flexible archive plugin for <a href="https://github.com/sxyazi/yazi">Yazi</a></b><br> - <i>Effortlessly compress your files and folders with style!</i> -</p> - ---- - -## π Table of Contents - -- [Features](#-features) -- [Supported File Types](#-supported-file-types) -- [Installation](#%EF%B8%8F-installation) -- [Keymap Example](#-keymap-example) -- [Usage](#%EF%B8%8F-usage) -- [Flags](#%EF%B8%8F-flags) -- [Tips](#-tips) -- [Credits](#-credits) - ---- - -## π Features - -- ποΈ **Multi-format support:** zip, 7z, rar, tar, tar.gz, tar.xz, tar.bz2, tar.zst, tar.lz4, tar.lha -- π **Cross-platform:** Works on Unix & Windows -- π **Password protection:** Secure your archives (zip/7z/rar) -- π‘οΈ **Header encryption:** Hide file lists (7z/rar) -- β‘ **Compression level:** Choose your balance of speed vs. size -- π **Overwrite safety:** Never lose files by accident -- π― **Seamless Yazi integration:** Fast, native-like UX - ---- - -## π¦ Supported File Types - -| Extension | Default Command | 7z Command | Bsdtar Command (Win10+ & Unix) | -| ------------- | ----------------- | -------------- | ------------------------------ | -| `.zip` | `zip -r` | `7z a -tzip` | `tar -caf` | -| `.7z` | `7z a` | `7z a` | | -| `.rar` | `rar a` | | | -| `.tar` | `tar rpf` | | `tar rpf` | -| `.tar.gz` | `tar rpf + gzip` | `7z a -tgzip` | `tar -czf` | -| `.tar.xz` | `tar rpf + xz` | `7z a -txz` | `tar -cJf` | -| `.tar.bz2` | `tar rpf + bzip2` | `7z a -tbzip2` | `tar -cjf` | -| `.tar.zst` | `tar rpf + zstd` | | `tar --zstd -cf` | -| `.tar.lz4` | `tar rpf + lz4` | | | -| `.tar.lha` | `tar rpf + lha` | | | - ---- - -## β‘οΈ Installation - -```bash -# Unix -git clone https://github.com/KKV9/compress.yazi.git ~/.config/yazi/plugins/compress.yazi - -# Windows (CMD, not PowerShell!) -git clone https://github.com/KKV9/compress.yazi.git %AppData%\yazi\config\plugins\compress.yazi - -# Or with yazi plugin manager -ya pkg add KKV9/compress -``` - ---- - -### π§ Extras (Windows) - -To enable additional compression formats and features on Windows, follow these steps: - -1. **Install [7-Zip](https://www.7-zip.org/):** - Add `C:\Program Files\7-Zip` to your `PATH`. - This enables support for `.7z` archives and password-protected `.zip` files. - -2. **Alternative: Install [Nanazip](https://github.com/M2Team/NanaZip):** - A modern alternative to 7-Zip with similar functionality and extra features. - -3. **Install [WinRAR](https://www.win-rar.com/download.html):** - Add `C:\Program Files\WinRAR` to your `PATH`. - This enables support for `.rar` archives. - -4. **Install Additional Tools:** - To use formats like `lha`, `lz4`, `gzip`, etc., install their respective tools and ensure they are added to your `PATH`. - ---- - -## πΉ Keymap Example - -Add this to your `keymap.toml`: - - -```toml -[[mgr.prepend_keymap]] -on = [ "c", "a", "a" ] -run = "plugin compress" -desc = "Archive selected files" - -[[mgr.prepend_keymap]] -on = [ "c", "a", "p" ] -run = "plugin compress -p" -desc = "Archive selected files (password)" - -[[mgr.prepend_keymap]] -on = [ "c", "a", "h" ] -run = "plugin compress -ph" -desc = "Archive selected files (password+header)" - -[[mgr.prepend_keymap]] -on = [ "c", "a", "l" ] -run = "plugin compress -l" -desc = "Archive selected files (compression level)" - -[[mgr.prepend_keymap]] -on = [ "c", "a", "u" ] -run = "plugin compress -phl" -desc = "Archive selected files (password+header+level)" -``` - ---- - -## π οΈ Usage - -1. **Select files/folders** in Yazi. -2. Press <kbd>c</kbd> <kbd>a</kbd> to open the archive dialog. -3. Choose: - - <kbd>a</kbd> for a standard archive - - <kbd>p</kbd> for password protection (zip/7z/rar) - - <kbd>h</kbd> to encrypt header (7z/rar) - - <kbd>l</kbd> to set compression level (all compression algorithims) - - <kbd>u</kbd> for all options together -4. **Type a name** for your archive (or leave blank for suggested name). -5. **Enter password** and/or **compression level** if prompted. -6. **Overwrite protect** if a file already exists, the new file will be given a suffix _#. -7. Enjoy your shiny new archive! - ---- - -## π³οΈβπ Flags - -- Combine flags for more power! -- when separating flags with spaces, make sure to single quote them (eg., `'-ph rar'`) -- `-p` Password protect (zip/7z/rar) -- `-h` Encrypt header (7z/rar) -- `-l` Set compression level (all compression algorithims) -- `<extention>` Specify a default extention (eg., `7z`, `tar.gz`) - -#### Combining multiple flags: -```toml -[[mgr.prepend_keymap]] -on = [ "c", "a", "7" ] -run = "plugin compress '-ph 7z'" -desc = "Archive selected files to 7z (password+header)" -[[mgr.prepend_keymap]] -on = [ "c", "a", "r" ] -run = "plugin compress '-p -l rar'" -desc = "Archive selected files to rar (password+level)" -``` - ---- - -## π‘ Tips - -- The file extension **must** match a supported type. -- The required compression tool **must** be installed and in your `PATH` (7zip/rar etc.). -- If no extention is provided, the default extention (zip) will be appended automatically. - ---- - -## π£ Credits - -Made with β€οΈ for [Yazi](https://github.com/sxyazi/yazi) by [KKV9](https://github.com/KKV9). -Contributions are welcome! Feel free to submit a pull request. - ---- diff --git a/fedora/.config/yazi/plugins/compress.yazi/main.lua b/fedora/.config/yazi/plugins/compress.yazi/main.lua deleted file mode 100644 index b695b3f..0000000 --- a/fedora/.config/yazi/plugins/compress.yazi/main.lua +++ /dev/null @@ -1,496 +0,0 @@ --- Check for windows -local is_windows = ya.target_family() == "windows" --- Define flags and strings -local is_password, is_encrypted, is_level, cmd_password, cmd_level, default_extension = false, false, false, "", "", "zip" - --- Function to check valid filename -local function is_valid_filename(name) - -- Trim whitespace from both ends - name = name:match("^%s*(.-)%s*$") - if name == "" then - return false - end - if is_windows then - -- Windows forbidden chars and reserved names - if name:find('[<>:"/\\|%?%*]') then - return false - end - else - -- Unix forbidden chars - if name:find("/") or name:find("%z") then - return false - end - end - return true -end - --- Function to send notifications -local function notify_error(message, urgency) - ya.notify( - { - title = "Archive", - content = message, - level = urgency, - timeout = 5 - } - ) -end - --- Function to check if command is available -local function is_command_available(cmd) - local stat_cmd - if is_windows then - stat_cmd = string.format("where %s > nul 2>&1", cmd) - else - stat_cmd = string.format("command -v %s >/dev/null 2>&1", cmd) - end - local cmd_exists = os.execute(stat_cmd) - if cmd_exists then - return true - else - return false - end -end - --- Function to change command arrays --> string -- Use first command available or first command -local function find_command_name(cmd_list) - for _, cmd in ipairs(cmd_list) do - if is_command_available(cmd) then - return cmd - end - end - return cmd_list[1] -- Return first command as fallback -end - --- Function to append filename to it's parent directory url -local function combine_url(path, file) - path, file = Url(path), Url(file) - return tostring(path:join(file)) -end - --- Function to make a table of selected or hovered files: path = filenames -local selected_or_hovered = - ya.sync( - function() - local tab, paths, names, path_fnames = cx.active, {}, {}, {} - for _, u in pairs(tab.selected) do - paths[#paths + 1] = tostring(u.parent) - names[#names + 1] = tostring(u.name) - end - if #paths == 0 and tab.current.hovered then - paths[1] = tostring(tab.current.hovered.url.parent) - names[1] = tostring(tab.current.hovered.name) - end - for idx, name in ipairs(names) do - if not path_fnames[paths[idx]] then - path_fnames[paths[idx]] = {} - end - table.insert(path_fnames[paths[idx]], name) - end - return path_fnames, names, tostring(tab.current.cwd) - end -) - --- Table of archive commands -local archive_commands = { - ["%.zip$"] = { - {command = "zip", args = {"-r"}, level_arg = "-", level_min = 0, level_max = 9, passwordable = true}, - { - command = {"7z", "7zz", "7za"}, - args = {"a", "-tzip"}, - level_arg = "-mx=", - level_min = 0, - level_max = 9, - passwordable = true - }, - { - command = {"tar", "bsdtar"}, - args = {"-caf"}, - level_arg = {"--option", "compression-level="}, - level_min = 1, - level_max = 9 - } - }, - ["%.7z$"] = { - { - command = {"7z", "7zz", "7za"}, - args = {"a"}, - level_arg = "-mx=", - level_min = 0, - level_max = 9, - header_arg = "-mhe=on", - passwordable = true - } - }, - ["%.rar$"] = { - { - command = "rar", - args = {"a"}, - level_arg = "-m", - level_min = 0, - level_max = 5, - header_arg = "-hp", - passwordable = true - } - }, - ["%.tar.gz$"] = { - {command = {"tar", "bsdtar"}, args = {"rpf"}, level_arg = "-", level_min = 1, level_max = 9, compress = "gzip"}, - { - command = {"tar", "bsdtar"}, - args = {"rpf"}, - level_arg = "-mx=", - level_min = 1, - level_max = 9, - compress = "7z", - compress_args = {"a", "-tgzip"} - }, - { - command = {"tar", "bsdtar"}, - args = {"-czf"}, - level_arg = {"--option", "gzip:compression-level="}, - level_min = 1, - level_max = 9 - } - }, - ["%.tar.xz$"] = { - {command = {"tar", "bsdtar"}, args = {"rpf"}, level_arg = "-", level_min = 1, level_max = 9, compress = "xz"}, - { - command = {"tar", "bsdtar"}, - args = {"rpf"}, - level_arg = "-mx=", - level_min = 1, - level_max = 9, - compress = "7z", - compress_args = {"a", "-txz"} - }, - { - command = {"tar", "bsdtar"}, - args = {"-cJf"}, - level_arg = {"--option", "xz:compression-level="}, - level_min = 1, - level_max = 9 - } - }, - ["%.tar.bz2$"] = { - {command = {"tar", "bsdtar"}, args = {"rpf"}, level_arg = "-", level_min = 1, level_max = 9, compress = "bzip2"}, - { - command = {"tar", "bsdtar"}, - args = {"rpf"}, - level_arg = "-mx=", - level_min = 1, - level_max = 9, - compress = "7z", - compress_args = {"a", "-tbzip2"} - }, - { - command = {"tar", "bsdtar"}, - args = {"-cjf"}, - level_arg = {"--option", "bzip2:compression-level="}, - level_min = 1, - level_max = 9 - } - }, - ["%.tar.zst$"] = { - { - command = {"tar", "bsdtar"}, - args = {"rpf"}, - level_arg = "-", - level_min = 1, - level_max = 22, - compress = "zstd", - compress_args = {"--ultra"} - } - }, - ["%.tar.lz4$"] = { - { - command = {"tar", "bsdtar"}, - args = {"rpf"}, - level_arg = "-", - level_min = 1, - level_max = 12, - compress = "lz4" - } - }, - ["%.tar.lha$"] = { - { - command = {"tar", "bsdtar"}, - args = {"rpf"}, - level_arg = "-o", - level_min = 5, - level_max = 7, - compress = "lha", - compress_args = {"-a"} - } - }, - ["%.tar$"] = { - {command = {"tar", "bsdtar"}, args = {"rpf"}} - } -} - -return { - entry = function(_, job) - -- Parse flags and default extension - if job.args ~= nil then - for _, arg in ipairs(job.args) do - if arg:match("^%-(%w+)$") then - -- Handle combined flags (e.g., -phl) - for flag in arg:sub(2):gmatch(".") do - if flag == "p" then - is_password = true - elseif flag == "h" then - is_encrypted = true - elseif flag == "l" then - is_level = true - end - end - elseif arg:match("^%w[%w\\.]*$") then - -- Handle default extension (e.g., 7z, zip) - if archive_commands["%." .. arg .. "$"] then - default_extension = arg - else - notify_error(string.format("Unsupported extension: %s", arg), "warn") - end - else - notify_error(string.format("Unknown argument: %s", arg), "warn") - end - end - end - - -- Exit visual mode - ya.emit("escape", {visual = true}) - -- Define file table and output_dir (pwd) - local path_fnames, fnames, output_dir = selected_or_hovered() - -- Get archive filename - local output_name, event = - ya.input( - { - title = "Create archive:", - position = {"top-center", y = 3, w = 40} - } - ) - if event ~= 1 then - return - end - - -- Determine the default name for the archive - local default_name = #fnames == 1 and fnames[1] or Url(output_dir).name - output_name = output_name == "" and string.format("%s.%s", default_name, default_extension) or output_name - - -- Add default extension if none is specified - if not output_name:match("%.%w+$") then - output_name = string.format("%s.%s", output_name, default_extension) - end - - -- Validate the final archive filename - if not is_valid_filename(output_name) then - notify_error("Invalid archive filename", "error") - return - end - - -- Match user input to archive command - local archive_cmd, - archive_args, - archive_compress, - archive_level_arg, - archive_level_min, - archive_level_max, - archive_header_arg, - archive_passwordable, - archive_compress_args - local matched_pattern = false - for pattern, cmd_list in pairs(archive_commands) do - if output_name:match(pattern) then - matched_pattern = true -- Mark that file extension is correct - for _, cmd in ipairs(cmd_list) do - -- Check if archive_cmd is available - local find_command = type(cmd.command) == "table" and find_command_name(cmd.command) or cmd.command - if is_command_available(find_command) then - -- Check if compress_cmd (if listed) is available - if cmd.compress == nil or is_command_available(cmd.compress) then - archive_cmd = find_command - archive_args = cmd.args - archive_compress = cmd.compress or "" - archive_level_arg = is_level and cmd.level_arg or "" - archive_level_min = cmd.level_min - archive_level_max = cmd.level_max - archive_header_arg = is_encrypted and cmd.header_arg or "" - archive_passwordable = cmd.passwordable or false - archive_compress_args = cmd.compress_args or {} - break - end - end - end - if archive_cmd then - break - end - end - end - - -- Check if no archive command is available for the extension - if not matched_pattern then - notify_error("Unsupported file extension", "error") - return - end - - -- Check if no suitable archive program was found - if not archive_cmd then - notify_error("Could not find a suitable archive program for the selected file extension", "error") - return - end - - -- Check if archive command has multiple names - if type(archive_cmd) == "table" then - archive_cmd = find_command_name(archive_cmd) - end - - -- Exit if archive command is not available - if not is_command_available(archive_cmd) then - notify_error(string.format("%s not available", archive_cmd), "error") - return - end - - -- Exit if compress command is not available - if archive_compress ~= "" and not is_command_available(archive_compress) then - notify_error(string.format("%s compression not available", archive_compress), "error") - return - end - - -- Add password arg if selected - if archive_passwordable and is_password then - local output_password, event = - ya.input( - { - title = "Enter password:", - obscure = true, - position = {"top-center", y = 3, w = 40} - } - ) - if event ~= 1 then - return - end - if output_password ~= "" then - cmd_password = "-P" .. output_password - if archive_cmd == "rar" and is_encrypted then - cmd_password = archive_header_arg .. output_password -- Add archive arg for rar - end - table.insert(archive_args, cmd_password) - end - end - - -- Add header arg if selected for 7z - if is_encrypted and archive_header_arg ~= "" and archive_cmd ~= "rar" then - table.insert(archive_args, archive_header_arg) - end - - -- Add level arg if selected - if archive_level_arg ~= "" and is_level then - local output_level, event = - ya.input( - { - title = string.format("Enter compression level (%s - %s)", archive_level_min, archive_level_max), - position = {"top-center", y = 3, w = 40} - } - ) - if event ~= 1 then - return - end - -- Validate user input for compression level - if - output_level ~= "" and tonumber(output_level) ~= nil and tonumber(output_level) >= archive_level_min and - tonumber(output_level) <= archive_level_max - then - cmd_level = - type(archive_level_arg) == "table" and archive_level_arg[#archive_level_arg] .. output_level or - archive_level_arg .. output_level - local target_args = archive_compress == "" and archive_args or archive_compress_args - if type(archive_level_arg) == "table" then - -- Insert each element of archive_level_arg (except last) into target_args at the correct position - for i = 1, #archive_level_arg - 1 do - table.insert(target_args, i, archive_level_arg[i]) - end - table.insert(target_args, #archive_level_arg, cmd_level) -- Add level at the end - else - -- Insert the compression level argument at the start if not a table - table.insert(target_args, 1, cmd_level) - end - else - notify_error("Invalid level specified. Using defaults.", "warn") - end - end - - -- Store the original output name for later use - local original_name = output_name - - -- If compression is needed, adjust the output name to exclude extensions like ".tar" - if archive_compress ~= "" then - output_name = output_name:match("(.*%.tar)") or output_name - end - - -- Create a temporary directory for intermediate files - local temp_dir_name = ".tmp_compress" - local temp_dir = combine_url(output_dir, temp_dir_name) - local temp_dir, _ = tostring(fs.unique_name(Url(temp_dir))) - - -- Attempt to create the temporary directory - local temp_dir_status, temp_dir_err = fs.create("dir_all", Url(temp_dir)) - if not temp_dir_status then - -- Notify the user if the temporary directory creation fails - notify_error(string.format("Failed to create temp directory, error code: %s", temp_dir_err), "error") - return - end - - -- Define the temporary output file path within the temporary directory - local temp_output_url = combine_url(temp_dir, output_name) - - -- Add files to the output archive - for filepath, filenames in pairs(path_fnames) do - -- Execute the archive command for each path and its respective files - local archive_status, archive_err = - Command(archive_cmd):arg(archive_args):arg(temp_output_url):arg(filenames):cwd(filepath):spawn():wait() - if not archive_status or not archive_status.success then - -- Notify the user if the archiving process fails and clean up the temporary directory - notify_error(string.format("Failed to create archive %s with '%s', error: %s", output_name, archive_cmd, archive_err), "error") - local cleanup_status, cleanup_err = fs.remove("dir_all", Url(temp_dir)) - if not cleanup_status then - notify_error(string.format("Failed to clean up temporary directory %s, error: %s", temp_dir, cleanup_err), "error") - end - return - end - end - - -- If compression is required, execute the compression command - if archive_compress ~= "" then - local compress_status, compress_err = - Command(archive_compress):arg(archive_compress_args):arg(temp_output_url):spawn():wait() - if not compress_status or not compress_status.success then - -- Notify the user if the compression process fails and clean up the temporary directory - notify_error(string.format("Failed to compress archive %s with '%s', error: %s", output_name, archive_compress, compress_err), "error") - local cleanup_status, cleanup_err = fs.remove("dir_all", Url(temp_dir)) - if not cleanup_status then - notify_error(string.format("Failed to clean up temporary directory %s, error: %s", temp_dir, cleanup_err), "error") - end - return - end - end - - -- Move the final file from the temporary directory to the output directory - local final_output_url, temp_url_processed = combine_url(output_dir, original_name), combine_url(temp_dir, original_name) - final_output_url, _ = tostring(fs.unique_name(Url(final_output_url))) - local move_status, move_err = os.rename(temp_url_processed, final_output_url) - if not move_status then - -- Notify the user if the move operation fails and clean up the temporary directory - notify_error(string.format("Failed to move %s to %s, error: %s", temp_url_processed, final_output_url, move_err), "error") - local cleanup_status, cleanup_err = fs.remove("dir_all", Url(temp_dir)) - if not cleanup_status then - notify_error(string.format("Failed to clean up temporary directory %s, error: %s", temp_dir, cleanup_err), "error") - end - return - end - - -- Cleanup the temporary directory after successful operation - local cleanup_status, cleanup_err = fs.remove("dir_all", Url(temp_dir)) - if not cleanup_status then - notify_error(string.format("Failed to clean up temporary directory %s, error: %s", temp_dir, cleanup_err), "error") - end - end -} |
