diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml
index 5d47b605..a33878ad 100644
--- a/.github/ISSUE_TEMPLATE/bug.yml
+++ b/.github/ISSUE_TEMPLATE/bug.yml
@@ -13,6 +13,8 @@ body:
- macOS
- Windows
- Windows WSL
+ - FreeBSD X11
+ - FreeBSD Wayland
validations:
required: true
- type: input
@@ -22,31 +24,32 @@ body:
placeholder: "ex: kitty v0.32.2"
validations:
required: true
- - type: dropdown
- id: tried_main
- attributes:
- label: Did you try the latest code to see if this problem got fixed?
- options:
- - Tried, but the problem still
- - Not tried, and I'll explain why below
- validations:
- required: true
- type: textarea
id: debug
attributes:
label: "`yazi --debug` output"
- description: Please do a `yazi --debug` and paste the output here.
+ description: Please run `yazi --debug` and paste the debug information here.
value: |
-
```sh
+ ##### ↓↓↓ Paste the output here: ↓↓↓ #####
+
```
validations:
required: true
+ - type: dropdown
+ id: tried_main
+ attributes:
+ label: Did you try the latest nightly build to see if the problem got fixed?
+ options:
+ - Yes, and I updated the debug information above (`yazi --debug`) to the nightly that I tried
+ - No, and I'll explain why below
+ validations:
+ required: true
- type: textarea
id: description
attributes:
diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index ce034802..0e7b1d54 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -39,3 +39,13 @@ jobs:
- name: Rustfmt
run: cargo +nightly fmt --all -- --check
+
+ stylua:
+ runs-on: ubuntu-22.04
+ steps:
+ - uses: actions/checkout@v4
+ - uses: JohnnyMorganz/stylua-action@v4
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ version: latest
+ args: --color always --check .
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 5130261e..29eee19e 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -24,7 +24,10 @@ jobs:
- name: Install gcc-aarch64-linux-gnu
if: matrix.target == 'aarch64-unknown-linux-gnu'
- run: sudo apt-get update && sudo apt-get install -yq gcc-aarch64-linux-gnu
+ run: |
+ sudo apt-get update && sudo apt-get install -yq gcc-aarch64-linux-gnu
+ echo "JEMALLOC_SYS_WITH_LG_PAGE=16" >> $GITHUB_ENV
+ echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=/usr/bin/aarch64-linux-gnu-gcc" >> $GITHUB_ENV
- name: Build
run: ./scripts/build.sh ${{ matrix.target }}
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 857897cc..c7296246 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -28,4 +28,4 @@ jobs:
run: cargo build --verbose
- name: Test
- run: cargo test --verbose
+ run: cargo test --all --verbose
diff --git a/.styluaignore b/.styluaignore
new file mode 100644
index 00000000..d8e2f141
--- /dev/null
+++ b/.styluaignore
@@ -0,0 +1,2 @@
+# this file caused some issues with the build system
+yazi-plugin/preset/plugins/mime.lua
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..cb99aa35
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,146 @@
+# Contributing to Yazi
+
+Thank you for your interest in contributing to Yazi! We welcome contributions in the form of bug reports, feature requests, documentation improvements, and code changes.
+
+This guide will help you understand how to contribute to the project.
+
+## Table of Contents
+
+1. [Getting Started](#getting-started)
+2. [Project Structure](#project-structure)
+3. [Development Setup](#development-setup)
+4. [How to Contribute](#how-to-contribute)
+5. [Pull Request Process](#pull-request-process)
+
+## Getting Started
+
+### Prerequisites
+
+Before you begin, ensure you have met the following requirements:
+
+- Rust installed on your machine. You can download it from [rustup.rs](https://rustup.rs).
+- Familiarity with Git and GitHub.
+
+### Fork the Repository
+
+1. Fork the [Yazi repository](https://github.com/sxyazi/yazi) to your GitHub account.
+2. Clone your fork to your local machine:
+
+ ```sh
+ git clone https://github.com//yazi.git
+ ```
+
+3. Set up the upstream remote:
+ ```sh
+ git remote add upstream https://github.com/sxyazi/yazi.git
+ ```
+
+## Project Structure
+
+A brief overview of the project's structure:
+
+```sh
+.
+├── assets/ # Assets like images and fonts
+├── nix/ # Nix-related configurations
+├── scripts/ # Helper scripts used by CI/CD
+├── snap/ # Snapcraft configuration
+├── yazi-adapter/ # Yazi image adapter
+├── yazi-boot/ # Yazi bootstrapper
+├── yazi-cli/ # Yazi command-line interface
+├── yazi-config/ # Yazi configuration file parser
+├── yazi-core/ # Yazi core logic
+├── yazi-dds/ # Yazi data distribution service
+├── yazi-fm/ # Yazi file manager
+├── yazi-plugin/ # Yazi plugin system
+├── yazi-proxy/ # Yazi event proxy
+├── yazi-scheduler/ # Yazi task scheduler
+├── yazi-shared/ # Yazi shared library
+├── .github/ # GitHub-specific files and workflows
+├── Cargo.toml # Rust workflow configuration
+└── README.md # Project overview
+```
+
+## Development Setup
+
+1. Ensure the latest stable Rust is installed:
+
+ ```sh
+ rustc --version
+ cargo --version
+ ```
+
+2. Build the project:
+
+ ```sh
+ cargo build
+ ```
+
+3. Run the tests:
+
+ ```sh
+ cargo test
+ ```
+
+4. Format the code (requires `rustfmt` nightly):
+
+ ```sh
+ rustup component add rustfmt --toolchain nightly
+ rustfmt +nightly **/*.rs
+ ```
+
+## How to Contribute
+
+### Reporting Bugs
+
+If you find a bug, please file an issue.
+
+### Suggesting Features
+
+If you have a feature request, please file an issue.
+
+### Improving Documentation
+
+Yazi's documentation placed at [yazi-rs/yazi-rs.github.io](https://github.com/yazi-rs/yazi-rs.github.io), contributions related to documentation need to be made within this repository.
+
+### Submitting Code Changes
+
+1. Create a new branch for your changes:
+
+ ```sh
+ git checkout -b your-branch-name
+ ```
+
+2. Make your changes. Ensure that your code follows the project's [coding style](https://github.com/sxyazi/yazi/blob/main/rustfmt.toml) and passes all tests.
+3. Commit your changes with a descriptive commit message:
+
+ ```sh
+ git commit -m "feat: an awesome feature"
+ ```
+
+4. Push your changes to your fork:
+ ```sh
+ git push origin your-branch-name
+ ```
+
+## Pull Request Process
+
+1. Ensure your fork is up-to-date with the upstream repository:
+
+ ```sh
+ git fetch upstream
+ git checkout main
+ git merge upstream/main
+ ```
+
+2. Rebase your feature branch onto the main branch:
+
+ ```sh
+ git checkout your-branch-name
+ git rebase main
+ ```
+
+3. Create a pull request to the `main` branch of the upstream repository. Follow the pull request template and ensure that:
+ - Your code passes all tests and lints.
+ - Your pull request description clearly explains the changes and why they are needed.
+4. Address any review comments. Make sure to push updates to the same branch on your fork.
diff --git a/Cargo.lock b/Cargo.lock
index 64898c5f..e1233811 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4,9 +4,9 @@ version = 3
[[package]]
name = "addr2line"
-version = "0.21.0"
+version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb"
+checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
dependencies = [
"gimli",
]
@@ -72,47 +72,48 @@ dependencies = [
[[package]]
name = "anstream"
-version = "0.6.13"
+version = "0.6.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb"
+checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
+ "is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
-version = "1.0.6"
+version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc"
+checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
[[package]]
name = "anstyle-parse"
-version = "0.2.3"
+version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
+checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
-version = "1.0.2"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
+checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391"
dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "anstyle-wincon"
-version = "3.0.2"
+version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
+checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19"
dependencies = [
"anstyle",
"windows-sys 0.52.0",
@@ -120,9 +121,9 @@ dependencies = [
[[package]]
name = "anyhow"
-version = "1.0.82"
+version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519"
+checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
[[package]]
name = "arc-swap"
@@ -141,15 +142,15 @@ dependencies = [
[[package]]
name = "autocfg"
-version = "1.2.0"
+version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
+checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "backtrace"
-version = "0.3.71"
+version = "0.3.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d"
+checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a"
dependencies = [
"addr2line",
"cc",
@@ -168,9 +169,9 @@ checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64"
-version = "0.22.0"
+version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "better-panic"
@@ -218,6 +219,15 @@ dependencies = [
"generic-array",
]
+[[package]]
+name = "block2"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f"
+dependencies = [
+ "objc2",
+]
+
[[package]]
name = "bstr"
version = "1.9.1"
@@ -236,9 +246,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "bytemuck"
-version = "1.15.0"
+version = "1.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15"
+checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e"
[[package]]
name = "byteorder"
@@ -269,9 +279,9 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.0.95"
+version = "1.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b"
+checksum = "c891175c3fb232128f48de6590095e59198bbeb8620c310be349bfc3afd12c7b"
[[package]]
name = "cfg-if"
@@ -293,9 +303,9 @@ dependencies = [
[[package]]
name = "clap"
-version = "4.5.4"
+version = "4.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0"
+checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f"
dependencies = [
"clap_builder",
"clap_derive",
@@ -303,30 +313,30 @@ dependencies = [
[[package]]
name = "clap_builder"
-version = "4.5.2"
+version = "4.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4"
+checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
- "strsim 0.11.1",
+ "strsim",
]
[[package]]
name = "clap_complete"
-version = "4.5.2"
+version = "4.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dd79504325bf38b10165b02e89b4347300f855f273c4cb30c4a3209e6583275e"
+checksum = "fbca90c87c2a04da41e95d1856e8bcd22f159bdbfa147314d2ce5218057b0e58"
dependencies = [
"clap",
]
[[package]]
name = "clap_complete_fig"
-version = "4.5.0"
+version = "4.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54b3e65f91fabdd23cac3d57d39d5d938b4daabd070c335c006dccb866a61110"
+checksum = "fb4bc503cddc1cd320736fb555d6598309ad07c2ddeaa23891a10ffb759ee612"
dependencies = [
"clap",
"clap_complete",
@@ -334,9 +344,9 @@ dependencies = [
[[package]]
name = "clap_complete_nushell"
-version = "4.5.1"
+version = "4.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80d0e48e026ce7df2040239117d25e4e79714907420c70294a5ce4b6bbe6a7b6"
+checksum = "1accf1b463dee0d3ab2be72591dccdab8bef314958340447c882c4c72acfe2a3"
dependencies = [
"clap",
"clap_complete",
@@ -344,21 +354,21 @@ dependencies = [
[[package]]
name = "clap_derive"
-version = "4.5.4"
+version = "4.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64"
+checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6"
dependencies = [
- "heck 0.5.0",
+ "heck",
"proc-macro2",
"quote",
- "syn 2.0.60",
+ "syn 2.0.67",
]
[[package]]
name = "clap_lex"
-version = "0.7.0"
+version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce"
+checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70"
[[package]]
name = "clipboard-win"
@@ -377,9 +387,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "colorchoice"
-version = "1.0.0"
+version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
+checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
[[package]]
name = "compact_str"
@@ -396,9 +406,9 @@ dependencies = [
[[package]]
name = "concurrent-queue"
-version = "2.4.0"
+version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363"
+checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
dependencies = [
"crossbeam-utils",
]
@@ -423,18 +433,18 @@ checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
[[package]]
name = "crc32fast"
-version = "1.4.0"
+version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa"
+checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam-channel"
-version = "0.5.12"
+version = "0.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95"
+checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
dependencies = [
"crossbeam-utils",
]
@@ -460,9 +470,9 @@ dependencies = [
[[package]]
name = "crossbeam-utils"
-version = "0.8.19"
+version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345"
+checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80"
[[package]]
name = "crossterm"
@@ -508,9 +518,9 @@ dependencies = [
[[package]]
name = "darling"
-version = "0.20.8"
+version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391"
+checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1"
dependencies = [
"darling_core",
"darling_macro",
@@ -518,27 +528,27 @@ dependencies = [
[[package]]
name = "darling_core"
-version = "0.20.8"
+version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f"
+checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
- "strsim 0.10.0",
- "syn 2.0.60",
+ "strsim",
+ "syn 2.0.67",
]
[[package]]
name = "darling_macro"
-version = "0.20.8"
+version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f"
+checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178"
dependencies = [
"darling_core",
"quote",
- "syn 2.0.60",
+ "syn 2.0.67",
]
[[package]]
@@ -583,9 +593,9 @@ dependencies = [
[[package]]
name = "either"
-version = "1.11.0"
+version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2"
+checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b"
[[package]]
name = "encode_unicode"
@@ -601,18 +611,19 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "erased-serde"
-version = "0.4.4"
+version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b73807008a3c7f171cc40312f37d95ef0396e048b5848d775f54b1a4dd4a0d3"
+checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d"
dependencies = [
"serde",
+ "typeid",
]
[[package]]
name = "errno"
-version = "0.3.8"
+version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
+checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
dependencies = [
"libc",
"windows-sys 0.52.0",
@@ -678,15 +689,15 @@ checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd"
dependencies = [
"cfg-if",
"libc",
- "redox_syscall",
+ "redox_syscall 0.4.1",
"windows-sys 0.52.0",
]
[[package]]
name = "flate2"
-version = "1.0.28"
+version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e"
+checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae"
dependencies = [
"crc32fast",
"miniz_oxide",
@@ -781,7 +792,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.60",
+ "syn 2.0.67",
]
[[package]]
@@ -826,9 +837,9 @@ dependencies = [
[[package]]
name = "getrandom"
-version = "0.2.14"
+version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c"
+checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
@@ -847,9 +858,9 @@ dependencies = [
[[package]]
name = "gimli"
-version = "0.28.1"
+version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253"
+checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
[[package]]
name = "globset"
@@ -876,20 +887,14 @@ dependencies = [
[[package]]
name = "hashbrown"
-version = "0.14.3"
+version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
+checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [
"ahash",
"allocator-api2",
]
-[[package]]
-name = "heck"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
-
[[package]]
name = "heck"
version = "0.5.0"
@@ -922,7 +927,7 @@ dependencies = [
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
- "windows-core",
+ "windows-core 0.52.0",
]
[[package]]
@@ -970,9 +975,9 @@ dependencies = [
[[package]]
name = "imagesize"
-version = "0.12.0"
+version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284"
+checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285"
[[package]]
name = "indexmap"
@@ -984,12 +989,6 @@ dependencies = [
"hashbrown",
]
-[[package]]
-name = "indoc"
-version = "2.0.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
-
[[package]]
name = "inotify"
version = "0.9.6"
@@ -1010,6 +1009,12 @@ dependencies = [
"libc",
]
+[[package]]
+name = "is_terminal_polyfill"
+version = "1.70.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
+
[[package]]
name = "itertools"
version = "0.12.1"
@@ -1019,6 +1024,15 @@ dependencies = [
"either",
]
+[[package]]
+name = "itertools"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
+dependencies = [
+ "either",
+]
+
[[package]]
name = "itoa"
version = "1.0.11"
@@ -1074,9 +1088,9 @@ dependencies = [
[[package]]
name = "lazy_static"
-version = "1.4.0"
+version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "lebe"
@@ -1086,9 +1100,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
[[package]]
name = "libc"
-version = "0.2.153"
+version = "0.2.155"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
+checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
[[package]]
name = "libredox"
@@ -1108,15 +1122,15 @@ checksum = "dd1bc4d24ad230d21fb898d1116b1801d7adfc449d42026475862ab48b11e70e"
[[package]]
name = "linux-raw-sys"
-version = "0.4.13"
+version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
+checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
[[package]]
name = "lock_api"
-version = "0.4.11"
+version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45"
+checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
dependencies = [
"autocfg",
"scopeguard",
@@ -1148,23 +1162,14 @@ dependencies = [
[[package]]
name = "luajit-src"
-version = "210.5.7+d06beb0"
+version = "210.5.8+5790d25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d251fdacdabbf87704cf48ac1f8b1eb23d6e10855c3ee08e5beb25b4be2e9e4"
+checksum = "441f18d9ad792e871fc2f7f2cb8902c386f6f56fdbddef3b835b61475e375346"
dependencies = [
"cc",
"which",
]
-[[package]]
-name = "malloc_buf"
-version = "0.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
-dependencies = [
- "libc",
-]
-
[[package]]
name = "md-5"
version = "0.10.6"
@@ -1177,9 +1182,9 @@ dependencies = [
[[package]]
name = "memchr"
-version = "2.7.2"
+version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "minimal-lexical"
@@ -1189,9 +1194,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "miniz_oxide"
-version = "0.7.2"
+version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7"
+checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
dependencies = [
"adler",
"simd-adler32",
@@ -1211,9 +1216,9 @@ dependencies = [
[[package]]
name = "mlua"
-version = "0.9.7"
+version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d9bed6bce296397a9d6a86f995dd10a547a4e6949825d45225906bdcbfe7367"
+checksum = "d111deb18a9c9bd33e1541309f4742523bfab01d276bfa9a27519f6de9c11dc7"
dependencies = [
"bstr",
"erased-serde",
@@ -1229,9 +1234,9 @@ dependencies = [
[[package]]
name = "mlua-sys"
-version = "0.5.2"
+version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d16a9ba1dd2c6ac971b204262d434c24d65067038598f0638b64e5dca28d52b8"
+checksum = "a088ed0723df7567f569ba018c5d48c23c501f3878b190b04144dfa5ebfa8abc"
dependencies = [
"cc",
"cfg-if",
@@ -1242,17 +1247,17 @@ dependencies = [
[[package]]
name = "mlua_derive"
-version = "0.9.2"
+version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aaade5f94e5829db58791664ba98f35fea6a3ffebc783becb51dc97c7a21abee"
+checksum = "09697a6cec88e7f58a02c7ab5c18c611c6907c8654613df9cc0192658a4fb859"
dependencies = [
- "itertools",
+ "itertools 0.12.1",
"once_cell",
"proc-macro-error",
"proc-macro2",
"quote",
"regex",
- "syn 2.0.60",
+ "syn 2.0.67",
]
[[package]]
@@ -1307,9 +1312,9 @@ checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]]
name = "num-traits"
-version = "0.2.18"
+version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
@@ -1334,19 +1339,44 @@ dependencies = [
]
[[package]]
-name = "objc"
-version = "0.2.7"
+name = "objc-sys"
+version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
+checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310"
+
+[[package]]
+name = "objc2"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804"
dependencies = [
- "malloc_buf",
+ "objc-sys",
+ "objc2-encode",
+]
+
+[[package]]
+name = "objc2-encode"
+version = "4.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7891e71393cd1f227313c9379a26a584ff3d7e6e7159e988851f0934c993f0f8"
+
+[[package]]
+name = "objc2-foundation"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
+dependencies = [
+ "bitflags 2.5.0",
+ "block2",
+ "libc",
+ "objc2",
]
[[package]]
name = "object"
-version = "0.32.2"
+version = "0.36.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441"
+checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434"
dependencies = [
"memchr",
]
@@ -1408,9 +1438,9 @@ checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae"
[[package]]
name = "parking_lot"
-version = "0.12.1"
+version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
dependencies = [
"lock_api",
"parking_lot_core",
@@ -1418,22 +1448,22 @@ dependencies = [
[[package]]
name = "parking_lot_core"
-version = "0.9.9"
+version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e"
+checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [
"cfg-if",
"libc",
- "redox_syscall",
+ "redox_syscall 0.5.2",
"smallvec",
- "windows-targets 0.48.5",
+ "windows-targets 0.52.5",
]
[[package]]
name = "paste"
-version = "1.0.14"
+version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
+checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "percent-encoding"
@@ -1518,9 +1548,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.81"
+version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba"
+checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
dependencies = [
"unicode-ident",
]
@@ -1554,21 +1584,22 @@ dependencies = [
[[package]]
name = "ratatui"
-version = "0.26.1"
+version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bcb12f8fbf6c62614b0d56eb352af54f6a22410c3b079eb53ee93c7b97dd31d8"
+checksum = "d16546c5b5962abf8ce6e2881e722b4e0ae3b6f1a08a26ae3573c55853ca68d3"
dependencies = [
"bitflags 2.5.0",
"cassowary",
"compact_str",
"crossterm",
- "indoc",
- "itertools",
+ "itertools 0.13.0",
"lru",
"paste",
"stability",
"strum",
+ "strum_macros",
"unicode-segmentation",
+ "unicode-truncate",
"unicode-width",
]
@@ -1601,6 +1632,15 @@ dependencies = [
"bitflags 1.3.2",
]
+[[package]]
+name = "redox_syscall"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd"
+dependencies = [
+ "bitflags 2.5.0",
+]
+
[[package]]
name = "redox_users"
version = "0.4.5"
@@ -1614,9 +1654,9 @@ dependencies = [
[[package]]
name = "regex"
-version = "1.10.4"
+version = "1.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
+checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
dependencies = [
"aho-corasick",
"memchr",
@@ -1626,9 +1666,9 @@ dependencies = [
[[package]]
name = "regex-automata"
-version = "0.4.6"
+version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea"
+checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
dependencies = [
"aho-corasick",
"memchr",
@@ -1637,21 +1677,21 @@ dependencies = [
[[package]]
name = "regex-syntax"
-version = "0.8.3"
+version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
+checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
[[package]]
name = "rustc-demangle"
-version = "0.1.23"
+version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
+checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
name = "rustc-hash"
-version = "1.1.0"
+version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
[[package]]
name = "rustix"
@@ -1668,15 +1708,15 @@ dependencies = [
[[package]]
name = "rustversion"
-version = "1.0.15"
+version = "1.0.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47"
+checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6"
[[package]]
name = "ryu"
-version = "1.0.17"
+version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
+checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "same-file"
@@ -1695,9 +1735,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
-version = "1.0.198"
+version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc"
+checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
dependencies = [
"serde_derive",
]
@@ -1714,20 +1754,20 @@ dependencies = [
[[package]]
name = "serde_derive"
-version = "1.0.198"
+version = "1.0.203"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9"
+checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.60",
+ "syn 2.0.67",
]
[[package]]
name = "serde_json"
-version = "1.0.116"
+version = "1.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
+checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3"
dependencies = [
"itoa",
"ryu",
@@ -1736,9 +1776,9 @@ dependencies = [
[[package]]
name = "serde_spanned"
-version = "0.6.5"
+version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
+checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0"
dependencies = [
"serde",
]
@@ -1829,9 +1869,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "socket2"
-version = "0.5.6"
+version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871"
+checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
dependencies = [
"libc",
"windows-sys 0.52.0",
@@ -1848,12 +1888,12 @@ dependencies = [
[[package]]
name = "stability"
-version = "0.1.1"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebd1b177894da2a2d9120208c3386066af06a488255caabc5de8ddca22dbc3ce"
+checksum = "2ff9eaf853dec4c8802325d8b6d3dffa86cc707fd7a1a4cdbf416e13b061787a"
dependencies = [
"quote",
- "syn 1.0.109",
+ "syn 2.0.67",
]
[[package]]
@@ -1862,12 +1902,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
-[[package]]
-name = "strsim"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
-
[[package]]
name = "strsim"
version = "0.11.1"
@@ -1885,15 +1919,15 @@ dependencies = [
[[package]]
name = "strum_macros"
-version = "0.26.2"
+version = "0.26.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946"
+checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be"
dependencies = [
- "heck 0.4.1",
+ "heck",
"proc-macro2",
"quote",
"rustversion",
- "syn 2.0.60",
+ "syn 2.0.67",
]
[[package]]
@@ -1903,15 +1937,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
- "quote",
"unicode-ident",
]
[[package]]
name = "syn"
-version = "2.0.60"
+version = "2.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3"
+checksum = "ff8655ed1d86f3af4ee3fd3263786bc14245ad17c4c7e85ba7187fb3ae028c90"
dependencies = [
"proc-macro2",
"quote",
@@ -1941,22 +1974,22 @@ dependencies = [
[[package]]
name = "thiserror"
-version = "1.0.59"
+version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa"
+checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
-version = "1.0.59"
+version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66"
+checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.60",
+ "syn 2.0.67",
]
[[package]]
@@ -2050,9 +2083,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.37.0"
+version = "1.38.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787"
+checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a"
dependencies = [
"backtrace",
"bytes",
@@ -2069,13 +2102,13 @@ dependencies = [
[[package]]
name = "tokio-macros"
-version = "2.2.0"
+version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
+checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.60",
+ "syn 2.0.67",
]
[[package]]
@@ -2091,9 +2124,9 @@ dependencies = [
[[package]]
name = "tokio-util"
-version = "0.7.10"
+version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
+checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
dependencies = [
"bytes",
"futures-core",
@@ -2104,9 +2137,9 @@ dependencies = [
[[package]]
name = "toml"
-version = "0.8.12"
+version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3"
+checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335"
dependencies = [
"indexmap",
"serde",
@@ -2117,18 +2150,18 @@ dependencies = [
[[package]]
name = "toml_datetime"
-version = "0.6.5"
+version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
+checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
-version = "0.22.12"
+version = "0.22.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef"
+checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38"
dependencies = [
"indexmap",
"serde",
@@ -2168,7 +2201,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.60",
+ "syn 2.0.67",
]
[[package]]
@@ -2208,20 +2241,27 @@ dependencies = [
[[package]]
name = "trash"
-version = "4.1.0"
+version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a1a7a9a17d3b004898be42be29a4c18d5a4cf008b5cdf72d69b1945dfcb158a"
+checksum = "8d8fbfb70b1fad5c0b788f9b2e1bf4d04e5ac6efa828f1ed9ee462c50ff9cf05"
dependencies = [
"chrono",
"libc",
"log",
- "objc",
+ "objc2",
+ "objc2-foundation",
"once_cell",
"scopeguard",
- "url",
+ "urlencoding",
"windows",
]
+[[package]]
+name = "typeid"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "059d83cc991e7a42fc37bd50941885db0888e34209f8cfd9aab07ddec03bc9cf"
+
[[package]]
name = "typenum"
version = "1.17.0"
@@ -2256,16 +2296,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
[[package]]
-name = "unicode-width"
-version = "0.1.11"
+name = "unicode-truncate"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
+checksum = "5a5fbabedabe362c618c714dbefda9927b5afc8e2a8102f47f081089a9019226"
+dependencies = [
+ "itertools 0.12.1",
+ "unicode-width",
+]
+
+[[package]]
+name = "unicode-width"
+version = "0.1.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d"
[[package]]
name = "url"
-version = "2.5.0"
+version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
+checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
dependencies = [
"form_urlencoded",
"idna",
@@ -2273,16 +2323,22 @@ dependencies = [
]
[[package]]
-name = "utf8parse"
-version = "0.2.1"
+name = "urlencoding"
+version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
+checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
+
+[[package]]
+name = "utf8parse"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uzers"
-version = "0.11.3"
+version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "76d283dc7e8c901e79e32d077866eaf599156cbf427fffa8289aecc52c5c3f63"
+checksum = "7d85875e16d59b3b1549efce83ff8251a64923b03bef94add0a1862847448de4"
dependencies = [
"libc",
"log",
@@ -2315,7 +2371,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
- "syn 2.0.60",
+ "syn 2.0.67",
]
[[package]]
@@ -2379,7 +2435,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
- "syn 2.0.60",
+ "syn 2.0.67",
"wasm-bindgen-shared",
]
@@ -2401,7 +2457,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.60",
+ "syn 2.0.67",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -2448,11 +2504,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
-version = "0.1.6"
+version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
+checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b"
dependencies = [
- "winapi",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -2463,11 +2519,12 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
-version = "0.44.0"
+version = "0.56.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b"
+checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132"
dependencies = [
- "windows-targets 0.42.2",
+ "windows-core 0.56.0",
+ "windows-targets 0.52.5",
]
[[package]]
@@ -2479,6 +2536,49 @@ dependencies = [
"windows-targets 0.52.5",
]
+[[package]]
+name = "windows-core"
+version = "0.56.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4698e52ed2d08f8658ab0c39512a7c00ee5fe2688c65f8c0a4f06750d729f2a6"
+dependencies = [
+ "windows-implement",
+ "windows-interface",
+ "windows-result",
+ "windows-targets 0.52.5",
+]
+
+[[package]]
+name = "windows-implement"
+version = "0.56.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.67",
+]
+
+[[package]]
+name = "windows-interface"
+version = "0.56.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.67",
+]
+
+[[package]]
+name = "windows-result"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8"
+dependencies = [
+ "windows-targets 0.52.5",
+]
+
[[package]]
name = "windows-sys"
version = "0.48.0"
@@ -2497,21 +2597,6 @@ dependencies = [
"windows-targets 0.52.5",
]
-[[package]]
-name = "windows-targets"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
-dependencies = [
- "windows_aarch64_gnullvm 0.42.2",
- "windows_aarch64_msvc 0.42.2",
- "windows_i686_gnu 0.42.2",
- "windows_i686_msvc 0.42.2",
- "windows_x86_64_gnu 0.42.2",
- "windows_x86_64_gnullvm 0.42.2",
- "windows_x86_64_msvc 0.42.2",
-]
-
[[package]]
name = "windows-targets"
version = "0.48.5"
@@ -2543,12 +2628,6 @@ dependencies = [
"windows_x86_64_msvc 0.52.5",
]
-[[package]]
-name = "windows_aarch64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
-
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
@@ -2561,12 +2640,6 @@ version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
-[[package]]
-name = "windows_aarch64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
-
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
@@ -2579,12 +2652,6 @@ version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
-[[package]]
-name = "windows_i686_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
-
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
@@ -2603,12 +2670,6 @@ version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
-[[package]]
-name = "windows_i686_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
-
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
@@ -2621,12 +2682,6 @@ version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
-[[package]]
-name = "windows_x86_64_gnu"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
-
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
@@ -2639,12 +2694,6 @@ version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
-[[package]]
-name = "windows_x86_64_gnullvm"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
-
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
@@ -2657,12 +2706,6 @@ version = "0.52.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
-[[package]]
-name = "windows_x86_64_msvc"
-version = "0.42.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
-
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
@@ -2677,9 +2720,9 @@ checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
[[package]]
name = "winnow"
-version = "0.6.6"
+version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0c976aaaa0e1f90dbb21e9587cdaf1d9679a1cde8875c0d6bd83ab96a208352"
+checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1"
dependencies = [
"memchr",
]
@@ -2691,12 +2734,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904"
[[package]]
-name = "yazi-adaptor"
+name = "yazi-adapter"
version = "0.2.5"
dependencies = [
+ "ansi-to-tui",
"anyhow",
"arc-swap",
- "base64 0.22.0",
+ "base64 0.22.1",
"color_quant",
"crossterm",
"futures",
@@ -2704,6 +2748,7 @@ dependencies = [
"imagesize",
"kamadak-exif",
"ratatui",
+ "scopeguard",
"tokio",
"tracing",
"yazi-config",
@@ -2718,9 +2763,10 @@ dependencies = [
"clap_complete",
"clap_complete_fig",
"clap_complete_nushell",
+ "regex",
"serde",
"vergen",
- "yazi-adaptor",
+ "yazi-adapter",
"yazi-config",
"yazi-shared",
]
@@ -2734,9 +2780,14 @@ dependencies = [
"clap_complete",
"clap_complete_fig",
"clap_complete_nushell",
+ "crossterm",
+ "md-5",
"serde_json",
"tokio",
+ "toml_edit",
+ "vergen",
"yazi-dds",
+ "yazi-shared",
]
[[package]]
@@ -2745,12 +2796,12 @@ version = "0.2.5"
dependencies = [
"anyhow",
"arc-swap",
+ "bitflags 2.5.0",
"crossterm",
"globset",
"indexmap",
"ratatui",
"serde",
- "shell-words",
"toml",
"validator",
"yazi-shared",
@@ -2761,10 +2812,9 @@ name = "yazi-core"
version = "0.2.5"
dependencies = [
"anyhow",
- "base64 0.22.0",
"bitflags 2.5.0",
- "clipboard-win",
"crossterm",
+ "dirs",
"futures",
"libc",
"notify",
@@ -2773,12 +2823,13 @@ dependencies = [
"regex",
"scopeguard",
"serde",
+ "shell-words",
"tokio",
"tokio-stream",
"tokio-util",
"tracing",
"unicode-width",
- "yazi-adaptor",
+ "yazi-adapter",
"yazi-boot",
"yazi-config",
"yazi-dds",
@@ -2801,6 +2852,7 @@ dependencies = [
"tokio-stream",
"tokio-util",
"uzers",
+ "vergen",
"yazi-boot",
"yazi-shared",
]
@@ -2826,7 +2878,7 @@ dependencies = [
"tracing",
"tracing-appender",
"tracing-subscriber",
- "yazi-adaptor",
+ "yazi-adapter",
"yazi-boot",
"yazi-config",
"yazi-core",
@@ -2842,22 +2894,24 @@ version = "0.2.5"
dependencies = [
"ansi-to-tui",
"anyhow",
+ "base64 0.22.1",
+ "clipboard-win",
+ "crossterm",
"futures",
"md-5",
"mlua",
"parking_lot",
"ratatui",
- "serde",
- "serde_json",
"shell-escape",
"shell-words",
"syntect",
"tokio",
+ "tokio-stream",
"tokio-util",
"tracing",
"unicode-width",
"uzers",
- "yazi-adaptor",
+ "yazi-adapter",
"yazi-boot",
"yazi-config",
"yazi-dds",
@@ -2911,7 +2965,6 @@ dependencies = [
"bitflags 2.5.0",
"crossterm",
"dirs",
- "filetime",
"futures",
"libc",
"parking_lot",
@@ -2919,28 +2972,29 @@ dependencies = [
"ratatui",
"regex",
"serde",
+ "shell-words",
"tokio",
- "tracing",
+ "windows-sys 0.52.0",
]
[[package]]
name = "zerocopy"
-version = "0.7.32"
+version = "0.7.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
+checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
-version = "0.7.32"
+version = "0.7.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
+checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.60",
+ "syn 2.0.67",
]
[[package]]
diff --git a/LICENSE-ICONS b/LICENSE-ICONS
new file mode 100644
index 00000000..df4391dd
--- /dev/null
+++ b/LICENSE-ICONS
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 nvim-tree
+
+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/README.md b/README.md
index 617e74b7..3c6ab241 100644
--- a/README.md
+++ b/README.md
@@ -12,13 +12,14 @@ Yazi (means "duck") is a terminal file manager written in Rust, based on non-blo
- 💪 **Powerful Async Task Scheduling and Management**: Provides real-time progress updates, task cancellation, and internal task priority assignment.
- 🖼️ **Built-in Support for Multiple Image Protocols**: Also integrated with Überzug++, covering almost all terminals.
- 🌟 **Built-in Code Highlighting and Image Decoding**: Combined with the pre-loading mechanism, greatly accelerates image and normal file loading.
-- 🔌 **Concurrent Plugin System**: UI plugins (rewriting most of the UI), functional plugins, custom previewer, and custom preloader; Just some pieces of Lua.
+- 🔌 **Concurrent Plugin System**: UI plugins (rewriting most of the UI), functional plugins, custom previewer/preloader/fetcher; Just some pieces of Lua.
- 📡 **Data Distribution Service**: Built on a client-server architecture (no additional server process required), integrated with a Lua-based publish-subscribe model, achieving cross-instance communication and state persistence.
+- 📦 **Package Manager**: Install plugins and themes with one command, keeping them always up to date, or pin them to a specific version.
- 🧰 Integration with fd, rg, fzf, zoxide
- 💫 Vim-like input/select/which/notify component, auto-completion for cd paths
- 🏷️ Multi-Tab Support, Cross-directory selection, Scrollable Preview (for videos, PDFs, archives, directories, code, etc.)
- 🔄 Bulk Renaming, Visual Mode, File Chooser
-- 🎨 Theme System, Custom Layouts, Trash Bin, CSI u
+- 🎨 Theme System, Mouse Support, Trash Bin, Custom Layouts, CSI u
- ... and more!
https://github.com/sxyazi/yazi/assets/17523360/92ff23fa-0cd5-4f04-b387-894c12265cc7
@@ -37,21 +38,21 @@ https://github.com/sxyazi/yazi/assets/17523360/92ff23fa-0cd5-4f04-b387-894c12265
## Image Preview
-| Platform | Protocol | Support |
-| ----------------- | ----------------------------------------------------------------------------------------------------- | --------------------- |
-| kitty | [Kitty unicode placeholders](https://sw.kovidgoyal.net/kitty/graphics-protocol/#unicode-placeholders) | ✅ Built-in |
-| Konsole | [Kitty old protocol](https://github.com/sxyazi/yazi/blob/main/yazi-adaptor/src/kitty_old.rs) | ✅ Built-in |
-| iTerm2 | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
-| WezTerm | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
-| Mintty (Git Bash) | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
-| foot | [Sixel graphics format](https://www.vt100.net/docs/vt3xx-gp/chapter14.html) | ✅ Built-in |
-| Ghostty | [Kitty old protocol](https://github.com/sxyazi/yazi/blob/main/yazi-adaptor/src/kitty_old.rs) | ✅ Built-in |
-| Black Box | [Sixel graphics format](https://www.vt100.net/docs/vt3xx-gp/chapter14.html) | ✅ Built-in |
-| VSCode | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
-| Tabby | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
-| Hyper | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
-| X11 / Wayland | Window system protocol | ☑️ Überzug++ required |
-| Fallback | [Chafa](https://hpjansson.org/chafa/) | ☑️ Überzug++ required |
+| Platform | Protocol | Support |
+| ----------------- | ----------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
+| kitty | [Kitty unicode placeholders](https://sw.kovidgoyal.net/kitty/graphics-protocol/#unicode-placeholders) | ✅ Built-in |
+| Konsole | [Kitty old protocol](https://github.com/sxyazi/yazi/blob/main/yazi-adapter/src/kitty_old.rs) | ✅ Built-in |
+| iTerm2 | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
+| WezTerm | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
+| Mintty (Git Bash) | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
+| foot | [Sixel graphics format](https://www.vt100.net/docs/vt3xx-gp/chapter14.html) | ✅ Built-in |
+| Ghostty | [Kitty old protocol](https://github.com/sxyazi/yazi/blob/main/yazi-adapter/src/kitty_old.rs) | ✅ Built-in |
+| Black Box | [Sixel graphics format](https://www.vt100.net/docs/vt3xx-gp/chapter14.html) | ✅ Built-in |
+| VSCode | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
+| Tabby | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
+| Hyper | [Inline images protocol](https://iterm2.com/documentation-images.html) | ✅ Built-in |
+| X11 / Wayland | Window system protocol | ☑️ [Überzug++](https://github.com/jstkdng/ueberzugpp) required |
+| Fallback | [ASCII art (Unicode block)](https://en.wikipedia.org/wiki/ASCII_art) | ☑️ [Chafa](https://hpjansson.org/chafa/) required |
See https://yazi-rs.github.io/docs/image-preview for details.
diff --git a/cspell.json b/cspell.json
index e69845bf..cc37ffa4 100644
--- a/cspell.json
+++ b/cspell.json
@@ -1 +1 @@
-{"version":"0.2","flagWords":[],"language":"en","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","imagesize","Upserting","prio","Ghostty","Catmull","Lanczos","cmds","unyank","scrolloff","headsup","unsub","uzers","scopeguard","SPDLOG","globset","filetime"]}
\ No newline at end of file
+{"flagWords":[],"language":"en","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","imagesize","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"],"version":"0.2"}
\ No newline at end of file
diff --git a/flake.lock b/flake.lock
index 25404c6f..f0a731ee 100644
--- a/flake.lock
+++ b/flake.lock
@@ -20,11 +20,11 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1713805509,
- "narHash": "sha256-YgSEan4CcrjivCNO5ZNzhg7/8ViLkZ4CB/GrGBVSudo=",
+ "lastModified": 1716097317,
+ "narHash": "sha256-1UMrLtgzielG/Sop6gl6oTSM4pDt7rF9j9VuxhDWDlY=",
"owner": "NixOS",
"repo": "nixpkgs",
- "rev": "1e1dc66fe68972a76679644a5577828b6a7e8be4",
+ "rev": "8535fb92661f37ff9f0da3007fbc942f7d134b41",
"type": "github"
},
"original": {
@@ -51,11 +51,11 @@
]
},
"locked": {
- "lastModified": 1713924823,
- "narHash": "sha256-kOeyS3GFwgnKvzuBMmFqEAX0xwZ7Nj4/5tXuvpZ0d4U=",
+ "lastModified": 1716085073,
+ "narHash": "sha256-3+9gI93XxszWA2+9S2xZfws1QArPX/MC6nahOGpcMB4=",
"owner": "oxalica",
"repo": "rust-overlay",
- "rev": "8a2edac3ae926a2a6ce60f4595dcc4540fc8cad4",
+ "rev": "cfc8776011bd83508324115d353222475e1601c0",
"type": "github"
},
"original": {
diff --git a/nix/yazi-unwrapped.nix b/nix/yazi-unwrapped.nix
index c212de1f..507cdca5 100644
--- a/nix/yazi-unwrapped.nix
+++ b/nix/yazi-unwrapped.nix
@@ -34,7 +34,7 @@
# Resize logo
for RES in 16 24 32 48 64 128 256; do
mkdir -p $out/share/icons/hicolor/"$RES"x"$RES"/apps
- convert assets/logo.png -resize "$RES"x"$RES" $out/share/icons/hicolor/"$RES"x"$RES"/apps/yazi.png
+ magick assets/logo.png -resize "$RES"x"$RES" $out/share/icons/hicolor/"$RES"x"$RES"/apps/yazi.png
done
mkdir -p $out/share/applications
diff --git a/scripts/build.sh b/scripts/build.sh
index 73b92c47..b694a4ab 100755
--- a/scripts/build.sh
+++ b/scripts/build.sh
@@ -3,7 +3,6 @@ set -euo pipefail
export ARTIFACT_NAME="yazi-$1"
export YAZI_GEN_COMPLETIONS=1
-export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=/usr/bin/aarch64-linux-gnu-gcc
# Setup Rust toolchain
if [[ "$1" == *-musl ]]; then
diff --git a/scripts/icons/generate.lua b/scripts/icons/generate.lua
new file mode 100644
index 00000000..1997f9cf
--- /dev/null
+++ b/scripts/icons/generate.lua
@@ -0,0 +1,36 @@
+local dark = require("icons-default")
+local light = require("icons-light")
+
+function rearrange(by)
+ local map = {}
+ local source = by == "exts" and "icons_by_file_extension" or "icons_by_filename"
+ for k, v in pairs(dark[source]) do
+ map[k] = map[k] or {}
+ map[k].icon = v.icon
+ map[k].fg_dark = v.color:lower()
+ end
+ for k, v in pairs(light[source]) do
+ map[k].fg_light = v.color:lower()
+ end
+ return map
+end
+
+function dump(map)
+ local list = {}
+ for k, v in pairs(map) do
+ list[#list + 1] = { name = k, text = v.icon, fg_dark = v.fg_dark, fg_light = v.fg_light }
+ end
+ table.sort(list, function(a, b) return a.name:lower() < b.name:lower() end)
+ for _, v in ipairs(list) do
+ -- stylua: ignore
+ print(string.format('\t{ name = "%s", text = "%s", fg_dark = "%s", fg_light = "%s" },', v.name, v.text, v.fg_dark, v.fg_light))
+ end
+end
+
+print("files = [")
+dump(rearrange("files"))
+print("]")
+
+print("exts = [")
+dump(rearrange("exts"))
+print("]")
diff --git a/scripts/publish.sh b/scripts/publish.sh
index e35ba6d2..84b17ead 100755
--- a/scripts/publish.sh
+++ b/scripts/publish.sh
@@ -1,9 +1,11 @@
cargo publish -p yazi-shared
cargo publish -p yazi-config
cargo publish -p yazi-proxy
-cargo publish -p yazi-adaptor
+cargo publish -p yazi-adapter
cargo publish -p yazi-boot
+cargo publish -p yazi-dds
cargo publish -p yazi-scheduler
cargo publish -p yazi-plugin
cargo publish -p yazi-core
cargo publish -p yazi-fm
+cargo publish -p yazi-cli
diff --git a/stylua.toml b/stylua.toml
new file mode 100644
index 00000000..ffaa2031
--- /dev/null
+++ b/stylua.toml
@@ -0,0 +1,6 @@
+indent_width = 2
+call_parentheses = "NoSingleTable"
+collapse_simple_statement = "FunctionOnly"
+
+[sort_requires]
+enabled = true
diff --git a/yazi-adaptor/Cargo.toml b/yazi-adapter/Cargo.toml
similarity index 66%
rename from yazi-adaptor/Cargo.toml
rename to yazi-adapter/Cargo.toml
index 39e06d07..7b6b21bf 100644
--- a/yazi-adaptor/Cargo.toml
+++ b/yazi-adapter/Cargo.toml
@@ -1,10 +1,10 @@
[package]
-name = "yazi-adaptor"
+name = "yazi-adapter"
version = "0.2.5"
edition = "2021"
license = "MIT"
authors = [ "sxyazi " ]
-description = "Yazi image adaptor"
+description = "Yazi image adapter"
homepage = "https://yazi-rs.github.io"
repository = "https://github.com/sxyazi/yazi"
@@ -13,17 +13,19 @@ yazi-config = { path = "../yazi-config", version = "0.2.5" }
yazi-shared = { path = "../yazi-shared", version = "0.2.5" }
# External dependencies
-anyhow = "1.0.82"
+ansi-to-tui = "=3.1.0"
+anyhow = "1.0.86"
arc-swap = "1.7.1"
-base64 = "0.22.0"
+base64 = "0.22.1"
color_quant = "1.1.0"
crossterm = "0.27.0"
futures = "0.3.30"
-image = "0.24.9"
-imagesize = "0.12.0"
+image = "=0.24.9"
+imagesize = "0.13.0"
kamadak-exif = "0.5.5"
-ratatui = "=0.26.1"
-tokio = { version = "1.37.0", features = [ "full" ] }
+ratatui = "0.27.0"
+scopeguard = "1.2.0"
+tokio = { version = "1.38.0", features = [ "full" ] }
# Logging
tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] }
diff --git a/yazi-adaptor/src/adaptor.rs b/yazi-adapter/src/adapter.rs
similarity index 57%
rename from yazi-adaptor/src/adaptor.rs
rename to yazi-adapter/src/adapter.rs
index 0cece50a..1a2e49bb 100644
--- a/yazi-adaptor/src/adaptor.rs
+++ b/yazi-adapter/src/adapter.rs
@@ -3,13 +3,13 @@ use std::{env, fmt::Display, path::Path, sync::Arc};
use anyhow::Result;
use ratatui::layout::Rect;
use tracing::warn;
-use yazi_shared::{env_exists, term::Term};
+use yazi_shared::env_exists;
use super::{Iterm2, Kitty, KittyOld};
-use crate::{ueberzug::Ueberzug, Emulator, Sixel, SHOWN, TMUX};
+use crate::{Chafa, Emulator, Sixel, Ueberzug, SHOWN, TMUX};
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub enum Adaptor {
+pub enum Adapter {
Kitty,
KittyOld,
Iterm2,
@@ -21,7 +21,7 @@ pub enum Adaptor {
Chafa,
}
-impl Display for Adaptor {
+impl Display for Adapter {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Kitty => write!(f, "kitty"),
@@ -35,49 +35,44 @@ impl Display for Adaptor {
}
}
-impl Adaptor {
- pub async fn image_show(self, path: &Path, rect: Rect) -> Result<(u32, u32)> {
+impl Adapter {
+ pub async fn image_show(self, path: &Path, max: Rect) -> Result {
+ if max.is_empty() {
+ return Ok(Rect::default());
+ }
+
match self {
- Self::Kitty => Kitty::image_show(path, rect).await,
- Self::KittyOld => KittyOld::image_show(path, rect).await,
- Self::Iterm2 => Iterm2::image_show(path, rect).await,
- Self::Sixel => Sixel::image_show(path, rect).await,
- _ => Ueberzug::image_show(path, rect).await,
+ Self::Kitty => Kitty::image_show(path, max).await,
+ Self::KittyOld => KittyOld::image_show(path, max).await,
+ Self::Iterm2 => Iterm2::image_show(path, max).await,
+ Self::Sixel => Sixel::image_show(path, max).await,
+ Self::X11 | Self::Wayland => Ueberzug::image_show(path, max).await,
+ Self::Chafa => Chafa::image_show(path, max).await,
}
}
pub fn image_hide(self) -> Result<()> {
- if let Some(rect) = SHOWN.swap(None) { self.image_erase(*rect) } else { Ok(()) }
+ if let Some(area) = SHOWN.swap(None) { self.image_erase(*area) } else { Ok(()) }
}
- pub fn image_erase(self, rect: Rect) -> Result<()> {
+ pub fn image_erase(self, area: Rect) -> Result<()> {
match self {
- Self::Kitty => Kitty::image_erase(rect),
- Self::Iterm2 => Iterm2::image_erase(rect),
- Self::KittyOld => KittyOld::image_erase(),
- Self::Sixel => Sixel::image_erase(rect),
- _ => Ueberzug::image_erase(rect),
+ Self::Kitty => Kitty::image_erase(area),
+ Self::Iterm2 => Iterm2::image_erase(area),
+ Self::KittyOld => KittyOld::image_erase(area),
+ Self::Sixel => Sixel::image_erase(area),
+ Self::X11 | Self::Wayland => Ueberzug::image_erase(area),
+ Self::Chafa => Chafa::image_erase(area),
}
}
#[inline]
pub fn shown_load(self) -> Option { SHOWN.load_full().map(|r| *r) }
- pub(super) fn start(self) { Ueberzug::start(self); }
-
#[inline]
- pub(super) fn shown_store(rect: Rect, size: (u32, u32)) {
- SHOWN.store(Some(Arc::new(
- Term::ratio()
- .map(|(r1, r2)| Rect {
- x: rect.x,
- y: rect.y,
- width: (size.0 as f64 / r1).ceil() as u16,
- height: (size.1 as f64 / r2).ceil() as u16,
- })
- .unwrap_or(rect),
- )));
- }
+ pub(super) fn shown_store(area: Rect) { SHOWN.store(Some(Arc::new(area))); }
+
+ pub(super) fn start(self) { Ueberzug::start(self); }
#[inline]
pub(super) fn needs_ueberzug(self) -> bool {
@@ -85,7 +80,7 @@ impl Adaptor {
}
}
-impl Adaptor {
+impl Adapter {
pub fn matches() -> Self {
let mut protocols = Emulator::detect().adapters();
@@ -93,8 +88,7 @@ impl Adaptor {
protocols.retain(|p| *p == Self::Iterm2);
if env_exists("ZELLIJ_SESSION_NAME") {
protocols.retain(|p| *p == Self::Sixel);
- }
- if *TMUX && protocols.len() > 1 {
+ } else if *TMUX {
protocols.retain(|p| *p != Self::KittyOld);
}
if let Some(p) = protocols.first() {
@@ -104,7 +98,7 @@ impl Adaptor {
match env::var("XDG_SESSION_TYPE").unwrap_or_default().as_str() {
"x11" => return Self::X11,
"wayland" => return Self::Wayland,
- _ => warn!("[Adaptor] Could not identify XDG_SESSION_TYPE"),
+ _ => warn!("[Adapter] Could not identify XDG_SESSION_TYPE"),
}
if env_exists("WAYLAND_DISPLAY") {
return Self::Wayland;
@@ -116,7 +110,7 @@ impl Adaptor {
return Self::KittyOld;
}
- warn!("[Adaptor] Falling back to chafa");
+ warn!("[Adapter] Falling back to chafa");
Self::Chafa
}
}
diff --git a/yazi-adapter/src/chafa.rs b/yazi-adapter/src/chafa.rs
new file mode 100644
index 00000000..c48a3420
--- /dev/null
+++ b/yazi-adapter/src/chafa.rs
@@ -0,0 +1,77 @@
+use std::{io::Write, path::Path, process::Stdio};
+
+use ansi_to_tui::IntoText;
+use anyhow::{bail, Result};
+use crossterm::{cursor::MoveTo, queue};
+use ratatui::layout::Rect;
+use tokio::process::Command;
+
+use crate::{Adapter, Emulator};
+
+pub(super) struct Chafa;
+
+impl Chafa {
+ pub(super) async fn image_show(path: &Path, max: Rect) -> Result {
+ let output = Command::new("chafa")
+ .args([
+ "-f",
+ "symbols",
+ "--relative",
+ "off",
+ "--polite",
+ "on",
+ "--passthrough",
+ "none",
+ "--animate",
+ "off",
+ "--view-size",
+ ])
+ .arg(format!("{}x{}", max.width, max.height))
+ .arg(path)
+ .stdin(Stdio::null())
+ .stdout(Stdio::piped())
+ .stderr(Stdio::null())
+ .kill_on_drop(true)
+ .output()
+ .await?;
+
+ if !output.status.success() {
+ bail!("chafa failed with status: {}", output.status);
+ } else if output.stdout.is_empty() {
+ bail!("chafa returned no output");
+ }
+
+ let lines: Vec<_> = output.stdout.split(|&b| b == b'\n').collect();
+ let Ok(Some(first)) = lines[0].into_text().map(|mut t| t.lines.pop()) else {
+ bail!("failed to parse chafa output");
+ };
+
+ let area = Rect {
+ x: max.x,
+ y: max.y,
+ width: first.spans.into_iter().map(|s| s.content.chars().count() as u16).sum(),
+ height: lines.len() as u16,
+ };
+
+ Adapter::Chafa.image_hide()?;
+ Adapter::shown_store(area);
+ Emulator::move_lock((max.x, max.y), |stderr| {
+ for (i, line) in lines.into_iter().enumerate() {
+ stderr.write_all(line)?;
+ queue!(stderr, MoveTo(max.x, max.y + i as u16 + 1))?;
+ }
+ Ok(area)
+ })
+ }
+
+ pub(super) fn image_erase(area: Rect) -> Result<()> {
+ let s = " ".repeat(area.width as usize);
+ Emulator::move_lock((0, 0), |stderr| {
+ for y in area.top()..area.bottom() {
+ queue!(stderr, MoveTo(area.x, y))?;
+ write!(stderr, "{s}")?;
+ }
+ Ok(())
+ })
+ }
+}
diff --git a/yazi-adapter/src/dimension.rs b/yazi-adapter/src/dimension.rs
new file mode 100644
index 00000000..dfa0f464
--- /dev/null
+++ b/yazi-adapter/src/dimension.rs
@@ -0,0 +1,35 @@
+use std::mem;
+
+use crossterm::terminal::WindowSize;
+
+pub struct Dimension;
+
+impl Dimension {
+ pub fn available() -> WindowSize {
+ let mut size = WindowSize { rows: 0, columns: 0, width: 0, height: 0 };
+ if let Ok(s) = crossterm::terminal::window_size() {
+ _ = mem::replace(&mut size, s);
+ }
+
+ if size.rows == 0 || size.columns == 0 {
+ if let Ok(s) = crossterm::terminal::size() {
+ size.columns = s.0;
+ size.rows = s.1;
+ }
+ }
+
+ // TODO: Use `CSI 14 t` to get the actual size of the terminal
+ // if size.width == 0 || size.height == 0 {}
+
+ size
+ }
+
+ #[inline]
+ pub fn ratio() -> Option<(f64, f64)> {
+ let s = Self::available();
+ if s.width == 0 || s.height == 0 {
+ return None;
+ }
+ Some((f64::from(s.width) / f64::from(s.columns), f64::from(s.height) / f64::from(s.rows)))
+ }
+}
diff --git a/yazi-adapter/src/emulator.rs b/yazi-adapter/src/emulator.rs
new file mode 100644
index 00000000..32c04cbd
--- /dev/null
+++ b/yazi-adapter/src/emulator.rs
@@ -0,0 +1,216 @@
+use std::{env, io::{stderr, LineWriter}, time::Duration};
+
+use anyhow::{anyhow, bail, Result};
+use crossterm::{cursor::{RestorePosition, SavePosition}, execute, style::Print, terminal::{disable_raw_mode, enable_raw_mode}};
+use scopeguard::defer;
+use tokio::{io::{AsyncReadExt, BufReader}, time::timeout};
+use tracing::{error, warn};
+use yazi_shared::env_exists;
+
+use crate::{Adapter, CLOSE, ESCAPE, START, TMUX};
+
+#[derive(Clone, Debug)]
+pub enum Emulator {
+ Unknown(Vec),
+ Kitty,
+ Konsole,
+ Iterm2,
+ WezTerm,
+ Foot,
+ Ghostty,
+ BlackBox,
+ VSCode,
+ Tabby,
+ Hyper,
+ Mintty,
+ Neovim,
+ Apple,
+ Urxvt,
+}
+
+impl Emulator {
+ pub fn adapters(self) -> Vec {
+ match self {
+ Self::Unknown(adapters) => adapters,
+ Self::Kitty => vec![Adapter::Kitty],
+ Self::Konsole => vec![Adapter::KittyOld],
+ Self::Iterm2 => vec![Adapter::Iterm2, Adapter::Sixel],
+ Self::WezTerm => vec![Adapter::Iterm2, Adapter::Sixel],
+ Self::Foot => vec![Adapter::Sixel],
+ Self::Ghostty => vec![Adapter::KittyOld],
+ Self::BlackBox => vec![Adapter::Sixel],
+ Self::VSCode => vec![Adapter::Iterm2, Adapter::Sixel],
+ Self::Tabby => vec![Adapter::Iterm2, Adapter::Sixel],
+ Self::Hyper => vec![Adapter::Iterm2, Adapter::Sixel],
+ Self::Mintty => vec![Adapter::Iterm2],
+ Self::Neovim => vec![],
+ Self::Apple => vec![],
+ Self::Urxvt => vec![],
+ }
+ }
+}
+
+impl Emulator {
+ pub fn detect() -> Self {
+ if env_exists("NVIM_LOG_FILE") && env_exists("NVIM") {
+ return Self::Neovim;
+ }
+
+ let vars = [
+ ("KITTY_WINDOW_ID", Self::Kitty),
+ ("KONSOLE_VERSION", Self::Konsole),
+ ("ITERM_SESSION_ID", Self::Iterm2),
+ ("WEZTERM_EXECUTABLE", Self::WezTerm),
+ ("GHOSTTY_RESOURCES_DIR", Self::Ghostty),
+ ("VSCODE_INJECTION", Self::VSCode),
+ ("TABBY_CONFIG_DIRECTORY", Self::Tabby),
+ ];
+ match vars.into_iter().find(|v| env_exists(v.0)) {
+ Some(var) => return var.1,
+ None => warn!("[Adapter] No special environment variables detected"),
+ }
+
+ let (term, program) = Self::via_env();
+ match program.as_str() {
+ "iTerm.app" => return Self::Iterm2,
+ "WezTerm" => return Self::WezTerm,
+ "ghostty" => return Self::Ghostty,
+ "BlackBox" => return Self::BlackBox,
+ "vscode" => return Self::VSCode,
+ "Tabby" => return Self::Tabby,
+ "Hyper" => return Self::Hyper,
+ "mintty" => return Self::Mintty,
+ "Apple_Terminal" => return Self::Apple,
+ _ => warn!("[Adapter] Unknown TERM_PROGRAM: {program}"),
+ }
+ match term.as_str() {
+ "xterm-kitty" => return Self::Kitty,
+ "foot" => return Self::Foot,
+ "foot-extra" => return Self::Foot,
+ "xterm-ghostty" => return Self::Ghostty,
+ "rxvt-unicode-256color" => return Self::Urxvt,
+ _ => warn!("[Adapter] Unknown TERM: {term}"),
+ }
+
+ Self::via_csi().unwrap_or(Self::Unknown(vec![]))
+ }
+
+ pub fn via_env() -> (String, String) {
+ fn tmux_env(name: &str) -> Result {
+ let output = std::process::Command::new("tmux").args(["show-environment", name]).output()?;
+
+ String::from_utf8(output.stdout)?
+ .trim()
+ .strip_prefix(&format!("{name}="))
+ .map_or_else(|| Err(anyhow!("")), |s| Ok(s.to_string()))
+ }
+
+ let mut term = env::var("TERM").unwrap_or_default();
+ let mut program = env::var("TERM_PROGRAM").unwrap_or_default();
+
+ if *TMUX {
+ term = tmux_env("TERM").unwrap_or(term);
+ program = tmux_env("TERM_PROGRAM").unwrap_or(program);
+ }
+
+ (term, program)
+ }
+
+ pub fn via_csi() -> Result {
+ defer! { disable_raw_mode().ok(); }
+ enable_raw_mode()?;
+
+ execute!(
+ LineWriter::new(stderr()),
+ SavePosition,
+ Print(format!(
+ "{}[>q{}_Gi=31,s=1,v=1,a=q,t=d,f=24;AAAA{}\\{}[c{}",
+ START, ESCAPE, ESCAPE, ESCAPE, CLOSE
+ )),
+ RestorePosition
+ )?;
+
+ let resp = futures::executor::block_on(Self::read_until_da1())?;
+ let names = [
+ ("kitty", Self::Kitty),
+ ("Konsole", Self::Konsole),
+ ("iTerm2", Self::Iterm2),
+ ("WezTerm", Self::WezTerm),
+ ("foot", Self::Foot),
+ ("ghostty", Self::Ghostty),
+ ];
+
+ for (name, emulator) in names.iter() {
+ if resp.contains(name) {
+ return Ok(emulator.clone());
+ }
+ }
+
+ let mut adapters = Vec::with_capacity(2);
+ if resp.contains("\x1b_Gi=31;OK") {
+ adapters.push(Adapter::KittyOld);
+ }
+ if ["?4;", "?4c", ";4;", ";4c"].iter().any(|s| resp.contains(s)) {
+ adapters.push(Adapter::Sixel);
+ }
+
+ Ok(Self::Unknown(adapters))
+ }
+
+ pub fn move_lock((x, y): (u16, u16), cb: F) -> Result
+ where
+ F: FnOnce(&mut std::io::BufWriter) -> Result,
+ {
+ use std::{io::Write, thread, time::Duration};
+
+ use crossterm::{cursor::{Hide, MoveTo, RestorePosition, SavePosition, Show}, queue};
+
+ let mut buf = std::io::BufWriter::new(stderr().lock());
+
+ // I really don't want to add this,
+ // But tmux and ConPTY sometimes cause the cursor position to get out of sync.
+ if *TMUX || cfg!(windows) {
+ execute!(buf, SavePosition, MoveTo(x, y), Show)?;
+ execute!(buf, MoveTo(x, y), Show)?;
+ execute!(buf, MoveTo(x, y), Show)?;
+ thread::sleep(Duration::from_millis(1));
+ } else {
+ queue!(buf, SavePosition, MoveTo(x, y))?;
+ }
+
+ let result = cb(&mut buf);
+ if *TMUX || cfg!(windows) {
+ queue!(buf, Hide, RestorePosition)?;
+ } else {
+ queue!(buf, RestorePosition)?;
+ }
+
+ buf.flush()?;
+ result
+ }
+
+ pub async fn read_until_da1() -> Result {
+ let read = async {
+ let mut stdin = BufReader::new(tokio::io::stdin());
+ let mut buf = String::with_capacity(200);
+ loop {
+ let mut c = [0; 1];
+ if stdin.read(&mut c).await? == 0 {
+ bail!("unexpected EOF");
+ }
+ buf.push(c[0] as char);
+ if c[0] == b'c' && buf.contains("\x1b[?") {
+ break;
+ }
+ }
+ Ok(buf)
+ };
+
+ let timeout = timeout(Duration::from_secs(10), read).await;
+ if let Err(ref e) = timeout {
+ error!("read_until_da1: {e:?}");
+ }
+
+ timeout?
+ }
+}
diff --git a/yazi-adaptor/src/image.rs b/yazi-adapter/src/image.rs
similarity index 91%
rename from yazi-adaptor/src/image.rs
rename to yazi-adapter/src/image.rs
index 3fbb3b9f..d5d39ca3 100644
--- a/yazi-adaptor/src/image.rs
+++ b/yazi-adapter/src/image.rs
@@ -5,7 +5,8 @@ use exif::{In, Tag};
use image::{codecs::jpeg::JpegEncoder, imageops::{self, FilterType}, io::Limits, DynamicImage};
use ratatui::layout::Rect;
use yazi_config::{PREVIEW, TASKS};
-use yazi_shared::term::Term;
+
+use crate::Dimension;
pub struct Image;
@@ -57,7 +58,7 @@ impl Image {
})
.await??;
- let (mut w, mut h) = Self::max_size(rect);
+ let (mut w, mut h) = Self::max_pixel(rect);
if (5..=8).contains(&orientation) {
(w, h) = (h, w);
}
@@ -76,8 +77,8 @@ impl Image {
.await?
}
- pub(super) fn max_size(rect: Rect) -> (u32, u32) {
- Term::ratio()
+ pub(super) fn max_pixel(rect: Rect) -> (u32, u32) {
+ Dimension::ratio()
.map(|(r1, r2)| {
let (w, h) = ((rect.width as f64 * r1) as u32, (rect.height as f64 * r2) as u32);
(w.min(PREVIEW.max_width), h.min(PREVIEW.max_height))
@@ -85,6 +86,17 @@ impl Image {
.unwrap_or((PREVIEW.max_width, PREVIEW.max_height))
}
+ pub(super) fn pixel_area(size: (u32, u32), rect: Rect) -> Rect {
+ Dimension::ratio()
+ .map(|(r1, r2)| Rect {
+ x: rect.x,
+ y: rect.y,
+ width: (size.0 as f64 / r1).ceil() as u16,
+ height: (size.1 as f64 / r2).ceil() as u16,
+ })
+ .unwrap_or(rect)
+ }
+
#[inline]
fn filter() -> FilterType {
match PREVIEW.image_filter.as_str() {
diff --git a/yazi-adapter/src/iterm2.rs b/yazi-adapter/src/iterm2.rs
new file mode 100644
index 00000000..d71cbf93
--- /dev/null
+++ b/yazi-adapter/src/iterm2.rs
@@ -0,0 +1,61 @@
+use std::{io::Write, path::Path};
+
+use anyhow::Result;
+use base64::{engine::{general_purpose::STANDARD, Config}, Engine};
+use crossterm::{cursor::MoveTo, queue};
+use image::{codecs::jpeg::JpegEncoder, DynamicImage};
+use ratatui::layout::Rect;
+
+use super::image::Image;
+use crate::{adapter::Adapter, Emulator, CLOSE, START};
+
+pub(super) struct Iterm2;
+
+impl Iterm2 {
+ pub(super) async fn image_show(path: &Path, max: Rect) -> Result {
+ let img = Image::downscale(path, max).await?;
+ let area = Image::pixel_area((img.width(), img.height()), max);
+ let b = Self::encode(img).await?;
+
+ Adapter::Iterm2.image_hide()?;
+ Adapter::shown_store(area);
+ Emulator::move_lock((max.x, max.y), |stderr| {
+ stderr.write_all(&b)?;
+ Ok(area)
+ })
+ }
+
+ pub(super) fn image_erase(area: Rect) -> Result<()> {
+ let s = " ".repeat(area.width as usize);
+ Emulator::move_lock((0, 0), |stderr| {
+ for y in area.top()..area.bottom() {
+ queue!(stderr, MoveTo(area.x, y))?;
+ write!(stderr, "{s}")?;
+ }
+ Ok(())
+ })
+ }
+
+ async fn encode(img: DynamicImage) -> Result> {
+ tokio::task::spawn_blocking(move || {
+ let mut jpg = vec![];
+ JpegEncoder::new_with_quality(&mut jpg, 75).encode_image(&img)?;
+
+ let len = base64::encoded_len(jpg.len(), STANDARD.config().encode_padding());
+ let mut buf = Vec::with_capacity(200 + len.unwrap_or(1 << 16));
+
+ write!(
+ buf,
+ "{}]1337;File=inline=1;size={};width={}px;height={}px;doNotMoveCursor=1:{}\x07{}",
+ START,
+ jpg.len(),
+ img.width(),
+ img.height(),
+ STANDARD.encode(&jpg),
+ CLOSE
+ )?;
+ Ok(buf)
+ })
+ .await?
+ }
+}
diff --git a/yazi-adaptor/src/kitty.rs b/yazi-adapter/src/kitty.rs
similarity index 84%
rename from yazi-adaptor/src/kitty.rs
rename to yazi-adapter/src/kitty.rs
index cdc46cb4..b75bbb07 100644
--- a/yazi-adaptor/src/kitty.rs
+++ b/yazi-adapter/src/kitty.rs
@@ -3,12 +3,12 @@ use std::{io::Write, path::Path};
use anyhow::Result;
use base64::{engine::general_purpose, Engine};
+use crossterm::{cursor::MoveTo, queue};
use image::DynamicImage;
use ratatui::layout::Rect;
-use yazi_shared::term::Term;
use super::image::Image;
-use crate::{adaptor::Adaptor, CLOSE, ESCAPE, START};
+use crate::{adapter::Adapter, Emulator, CLOSE, ESCAPE, START};
static DIACRITICS: [char; 297] = [
'\u{0305}',
@@ -313,31 +313,31 @@ static DIACRITICS: [char; 297] = [
pub(super) struct Kitty;
impl Kitty {
- pub(super) async fn image_show(path: &Path, rect: Rect) -> Result<(u32, u32)> {
- let img = Image::downscale(path, rect).await?;
- let size = (img.width(), img.height());
+ pub(super) async fn image_show(path: &Path, max: Rect) -> Result {
+ let img = Image::downscale(path, max).await?;
+ let area = Image::pixel_area((img.width(), img.height()), max);
let b1 = Self::encode(img).await?;
- let b2 = Self::place(&rect)?;
+ let b2 = Self::place(&area)?;
- Adaptor::Kitty.image_hide()?;
- Adaptor::shown_store(rect, size);
- Term::move_lock((rect.x, rect.y), |stderr| {
+ Adapter::Kitty.image_hide()?;
+ Adapter::shown_store(area);
+ Emulator::move_lock((area.x, area.y), |stderr| {
stderr.write_all(&b1)?;
stderr.write_all(&b2)?;
- Ok(size)
+ Ok(area)
})
}
- pub(super) fn image_erase(rect: Rect) -> Result<()> {
- let s = " ".repeat(rect.width as usize);
- Term::move_lock((0, 0), |stderr| {
- for y in rect.top()..rect.bottom() {
- Term::move_to(stderr, rect.x, y)?;
+ pub(super) fn image_erase(area: Rect) -> Result<()> {
+ let s = " ".repeat(area.width as usize);
+ Emulator::move_lock((0, 0), |stderr| {
+ for y in area.top()..area.bottom() {
+ queue!(stderr, MoveTo(area.x, y))?;
write!(stderr, "{s}")?;
}
- write!(stderr, "{}_Gq=1,a=d,d=A{}\\{}", START, ESCAPE, CLOSE)?;
+ write!(stderr, "{}_Gq=2,a=d,d=A{}\\{}", START, ESCAPE, CLOSE)?;
Ok(())
})
}
@@ -351,7 +351,7 @@ impl Kitty {
if let Some(first) = it.next() {
write!(
buf,
- "{}_Gq=1,a=T,i=1,C=1,U=1,f={},s={},v={},m={};{}{}\\{}",
+ "{}_Gq=2,a=T,i=1,C=1,U=1,f={},s={},v={},m={};{}{}\\{}",
START,
format,
size.0,
@@ -388,11 +388,11 @@ impl Kitty {
.await?
}
- fn place(rect: &Rect) -> Result> {
- let mut buf = Vec::with_capacity(rect.width as usize * rect.height as usize * 3 + 50);
- for y in 0..rect.height {
- write!(buf, "\x1b[{};{}H\x1b[38;5;1m", rect.y + y + 1, rect.x + 1)?;
- for x in 0..rect.width {
+ fn place(area: &Rect) -> Result> {
+ let mut buf = Vec::with_capacity(area.width as usize * area.height as usize * 3 + 50);
+ for y in 0..area.height {
+ write!(buf, "\x1b[{};{}H\x1b[38;5;1m", area.y + y + 1, area.x + 1)?;
+ for x in 0..area.width {
write!(buf, "\u{10EEEE}")?;
write!(buf, "{}", *DIACRITICS.get(y as usize).unwrap_or(&DIACRITICS[0]))?;
write!(buf, "{}", *DIACRITICS.get(x as usize).unwrap_or(&DIACRITICS[0]))?;
diff --git a/yazi-adaptor/src/kitty_old.rs b/yazi-adapter/src/kitty_old.rs
similarity index 73%
rename from yazi-adaptor/src/kitty_old.rs
rename to yazi-adapter/src/kitty_old.rs
index cf0a2df9..0de07533 100644
--- a/yazi-adaptor/src/kitty_old.rs
+++ b/yazi-adapter/src/kitty_old.rs
@@ -5,31 +5,30 @@ use anyhow::Result;
use base64::{engine::general_purpose, Engine};
use image::DynamicImage;
use ratatui::layout::Rect;
-use yazi_shared::term::Term;
use super::image::Image;
-use crate::{adaptor::Adaptor, CLOSE, ESCAPE, START};
+use crate::{adapter::Adapter, Emulator, CLOSE, ESCAPE, START};
pub(super) struct KittyOld;
impl KittyOld {
- pub(super) async fn image_show(path: &Path, rect: Rect) -> Result<(u32, u32)> {
- let img = Image::downscale(path, rect).await?;
- let size = (img.width(), img.height());
+ pub(super) async fn image_show(path: &Path, max: Rect) -> Result {
+ let img = Image::downscale(path, max).await?;
+ let area = Image::pixel_area((img.width(), img.height()), max);
let b = Self::encode(img).await?;
- Adaptor::KittyOld.image_hide()?;
- Adaptor::shown_store(rect, size);
- Term::move_lock((rect.x, rect.y), |stderr| {
+ Adapter::KittyOld.image_hide()?;
+ Adapter::shown_store(area);
+ Emulator::move_lock((area.x, area.y), |stderr| {
stderr.write_all(&b)?;
- Ok(size)
+ Ok(area)
})
}
#[inline]
- pub(super) fn image_erase() -> Result<()> {
+ pub(super) fn image_erase(_: Rect) -> Result<()> {
let mut stderr = LineWriter::new(stderr());
- write!(stderr, "{}_Gq=1,a=d,d=A{}\\{}", START, ESCAPE, CLOSE)?;
+ write!(stderr, "{}_Gq=2,a=d,d=A{}\\{}", START, ESCAPE, CLOSE)?;
stderr.flush()?;
Ok(())
}
@@ -43,7 +42,7 @@ impl KittyOld {
if let Some(first) = it.next() {
write!(
buf,
- "{}_Gq=1,a=T,z=-1,C=1,f={},s={},v={},m={};{}{}\\{}",
+ "{}_Gq=2,a=T,z=-1,C=1,f={},s={},v={},m={};{}{}\\{}",
START,
format,
size.0,
diff --git a/yazi-adaptor/src/lib.rs b/yazi-adapter/src/lib.rs
similarity index 79%
rename from yazi-adaptor/src/lib.rs
rename to yazi-adapter/src/lib.rs
index 700e944e..0dfe8f9c 100644
--- a/yazi-adaptor/src/lib.rs
+++ b/yazi-adapter/src/lib.rs
@@ -1,6 +1,8 @@
#![allow(clippy::unit_arg)]
-mod adaptor;
+mod adapter;
+mod chafa;
+mod dimension;
mod emulator;
mod image;
mod iterm2;
@@ -9,17 +11,20 @@ mod kitty_old;
mod sixel;
mod ueberzug;
-pub use adaptor::*;
+pub use adapter::*;
+use chafa::*;
+pub use dimension::*;
pub use emulator::*;
use iterm2::*;
use kitty::*;
use kitty_old::*;
use sixel::*;
+use ueberzug::*;
use yazi_shared::{env_exists, RoCell};
pub use crate::image::*;
-pub static ADAPTOR: RoCell = RoCell::new();
+pub static ADAPTOR: RoCell = RoCell::new();
// Tmux support
pub static TMUX: RoCell = RoCell::new();
@@ -31,22 +36,22 @@ static CLOSE: RoCell<&'static str> = RoCell::new();
static SHOWN: RoCell> = RoCell::new();
pub fn init() {
- TMUX.init(env_exists("TMUX"));
+ TMUX.init(env_exists("TMUX") && env_exists("TMUX_PANE"));
START.init(if *TMUX { "\x1bPtmux;\x1b\x1b" } else { "\x1b" });
CLOSE.init(if *TMUX { "\x1b\\" } else { "" });
ESCAPE.init(if *TMUX { "\x1b\x1b" } else { "\x1b" });
- SHOWN.with(Default::default);
-
- ADAPTOR.init(Adaptor::matches());
- ADAPTOR.start();
-
if *TMUX {
_ = std::process::Command::new("tmux")
.args(["set", "-p", "allow-passthrough", "on"])
.stdin(std::process::Stdio::null())
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::null())
- .spawn();
+ .status();
}
+
+ SHOWN.with(Default::default);
+
+ ADAPTOR.init(Adapter::matches());
+ ADAPTOR.start();
}
diff --git a/yazi-adaptor/src/sixel.rs b/yazi-adapter/src/sixel.rs
similarity index 74%
rename from yazi-adaptor/src/sixel.rs
rename to yazi-adapter/src/sixel.rs
index eb4b22ab..b8e48fce 100644
--- a/yazi-adaptor/src/sixel.rs
+++ b/yazi-adapter/src/sixel.rs
@@ -2,34 +2,34 @@ use std::{io::Write, path::Path};
use anyhow::{bail, Result};
use color_quant::NeuQuant;
+use crossterm::{cursor::MoveTo, queue};
use image::DynamicImage;
use ratatui::layout::Rect;
use yazi_config::PREVIEW;
-use yazi_shared::term::Term;
-use crate::{adaptor::Adaptor, Image, CLOSE, ESCAPE, START};
+use crate::{adapter::Adapter, Emulator, Image, CLOSE, ESCAPE, START};
pub(super) struct Sixel;
impl Sixel {
- pub(super) async fn image_show(path: &Path, rect: Rect) -> Result<(u32, u32)> {
- let img = Image::downscale(path, rect).await?;
- let size = (img.width(), img.height());
+ pub(super) async fn image_show(path: &Path, max: Rect) -> Result {
+ let img = Image::downscale(path, max).await?;
+ let area = Image::pixel_area((img.width(), img.height()), max);
let b = Self::encode(img).await?;
- Adaptor::Sixel.image_hide()?;
- Adaptor::shown_store(rect, size);
- Term::move_lock((rect.x, rect.y), |stderr| {
+ Adapter::Sixel.image_hide()?;
+ Adapter::shown_store(area);
+ Emulator::move_lock((area.x, area.y), |stderr| {
stderr.write_all(&b)?;
- Ok(size)
+ Ok(area)
})
}
- pub(super) fn image_erase(rect: Rect) -> Result<()> {
- let s = " ".repeat(rect.width as usize);
- Term::move_lock((0, 0), |stderr| {
- for y in rect.top()..rect.bottom() {
- Term::move_to(stderr, rect.x, y)?;
+ pub(super) fn image_erase(area: Rect) -> Result<()> {
+ let s = " ".repeat(area.width as usize);
+ Emulator::move_lock((0, 0), |stderr| {
+ for y in area.top()..area.bottom() {
+ queue!(stderr, MoveTo(area.x, y))?;
write!(stderr, "{s}")?;
}
Ok(())
diff --git a/yazi-adaptor/src/ueberzug.rs b/yazi-adapter/src/ueberzug.rs
similarity index 74%
rename from yazi-adaptor/src/ueberzug.rs
rename to yazi-adapter/src/ueberzug.rs
index 1e3a0106..7072f544 100644
--- a/yazi-adaptor/src/ueberzug.rs
+++ b/yazi-adapter/src/ueberzug.rs
@@ -8,7 +8,7 @@ use tracing::{debug, warn};
use yazi_config::PREVIEW;
use yazi_shared::RoCell;
-use crate::{Adaptor, Image};
+use crate::{Adapter, Dimension};
#[allow(clippy::type_complexity)]
static DEMON: RoCell