From e0911f25072f01ca7e440a077d2c3888ca3e4ab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=89=E5=92=B2=E9=9B=85=20misaki=20masa?= Date: Tue, 27 Jan 2026 22:03:48 +0800 Subject: [PATCH] refactor: new `yazi-tty` crate (#3623) --- Cargo.lock | 171 +++++++++++++++--- Cargo.toml | 1 + yazi-actor/Cargo.toml | 1 + yazi-actor/src/mgr/bulk_rename.rs | 2 +- yazi-actor/src/mgr/refresh.rs | 2 +- yazi-actor/src/tasks/inspect.rs | 2 +- yazi-adapter/Cargo.toml | 1 + yazi-adapter/src/adapter.rs | 10 +- yazi-adapter/src/adapters.rs | 69 +++++++ yazi-adapter/src/brand.rs | 26 --- yazi-adapter/src/drivers/kgp_old.rs | 2 +- yazi-adapter/src/emulator.rs | 11 +- yazi-adapter/src/lib.rs | 2 +- yazi-adapter/src/mux.rs | 2 +- yazi-adapter/src/unknown.rs | 15 -- yazi-build/Cargo.toml | 1 + yazi-build/build.rs | 4 +- yazi-config/Cargo.toml | 1 + yazi-config/src/lib.rs | 2 +- yazi-fm/Cargo.toml | 1 + yazi-fm/src/app/commands/render.rs | 2 +- yazi-fm/src/main.rs | 2 +- yazi-fm/src/term.rs | 2 +- yazi-parser/Cargo.toml | 1 + yazi-parser/src/app/notify.rs | 37 ++-- yazi-plugin/src/utils/layer.rs | 7 +- yazi-term/Cargo.toml | 7 +- yazi-term/src/lib.rs | 4 - yazi-tty/Cargo.toml | 26 +++ yazi-tty/README.md | 5 + {yazi-term/src/tty => yazi-tty/src}/handle.rs | 0 .../src/tty/mod.rs => yazi-tty/src/lib.rs | 2 +- {yazi-term/src/tty => yazi-tty/src}/tty.rs | 0 .../src/tty => yazi-tty/src}/windows.rs | 0 yazi-widgets/Cargo.toml | 1 + yazi-widgets/src/clipboard.rs | 2 +- 36 files changed, 293 insertions(+), 131 deletions(-) create mode 100644 yazi-adapter/src/adapters.rs create mode 100644 yazi-tty/Cargo.toml create mode 100644 yazi-tty/README.md rename {yazi-term/src/tty => yazi-tty/src}/handle.rs (100%) rename yazi-term/src/tty/mod.rs => yazi-tty/src/lib.rs (76%) rename {yazi-term/src/tty => yazi-tty/src}/tty.rs (100%) rename {yazi-term/src/tty => yazi-tty/src}/windows.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 57172e35..a6793513 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -583,6 +583,7 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", + "serde", "wasm-bindgen", "windows-link", ] @@ -1002,6 +1003,16 @@ dependencies = [ "darling_macro 0.20.11", ] +[[package]] +name = "darling" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +dependencies = [ + "darling_core 0.21.3", + "darling_macro 0.21.3", +] + [[package]] name = "darling" version = "0.23.0" @@ -1026,6 +1037,20 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.114", +] + [[package]] name = "darling_core" version = "0.23.0" @@ -1050,6 +1075,17 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core 0.21.3", + "quote", + "syn 2.0.114", +] + [[package]] name = "darling_macro" version = "0.23.0" @@ -1134,6 +1170,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" dependencies = [ "powerfmt", + "serde_core", ] [[package]] @@ -1759,6 +1796,12 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.16.1" @@ -1938,6 +1981,17 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8" +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + [[package]] name = "indexmap" version = "2.13.0" @@ -1945,7 +1999,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.16.1", "serde", "serde_core", ] @@ -2091,7 +2145,7 @@ version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fe90c1150662e858c7d5f945089b7517b0a80d8bf7ba4b1b5ffc984e7230a5b" dependencies = [ - "hashbrown", + "hashbrown 0.16.1", "portable-atomic", "thiserror 2.0.18", ] @@ -2292,7 +2346,7 @@ version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593" dependencies = [ - "hashbrown", + "hashbrown 0.16.1", ] [[package]] @@ -3097,7 +3151,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07" dependencies = [ "base64", - "indexmap", + "indexmap 2.13.0", "quick-xml", "serde", "time", @@ -3380,7 +3434,7 @@ checksum = "5ef8dea09a92caaf73bff7adb70b76162e5937524058a7e5bff37869cbbec293" dependencies = [ "bitflags 2.10.0", "compact_str", - "hashbrown", + "hashbrown 0.16.1", "indoc", "itertools", "kasuari", @@ -3444,7 +3498,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7dbfa023cd4e604c2553483820c5fe8aa9d71a42eea5aa77c6e7f35756612db" dependencies = [ "bitflags 2.10.0", - "hashbrown", + "hashbrown 0.16.1", "indoc", "instability", "itertools", @@ -3816,6 +3870,30 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54e910108742c57a770f492731f99be216a52fadd361b06c8fb59d74ccc267d2" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -3915,6 +3993,37 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serde_with" +version = "3.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.13.0", + "schemars 0.9.0", + "schemars 1.2.0", + "serde_core", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" +dependencies = [ + "darling 0.21.3", + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "serdect" version = "0.4.2" @@ -4524,7 +4633,7 @@ version = "0.9.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46" dependencies = [ - "indexmap", + "indexmap 2.13.0", "serde_core", "serde_spanned", "toml_datetime", @@ -5426,7 +5535,7 @@ dependencies = [ "anyhow", "crossterm 0.29.0", "futures", - "hashbrown", + "hashbrown 0.16.1", "libc", "mlua", "paste", @@ -5447,6 +5556,7 @@ dependencies = [ "yazi-scheduler", "yazi-shared", "yazi-term", + "yazi-tty", "yazi-vfs", "yazi-watcher", "yazi-widgets", @@ -5473,6 +5583,7 @@ dependencies = [ "yazi-macro", "yazi-shared", "yazi-term", + "yazi-tty", ] [[package]] @@ -5481,7 +5592,7 @@ version = "26.1.22" dependencies = [ "ansi-to-tui", "futures", - "hashbrown", + "hashbrown 0.16.1", "mlua", "paste", "ratatui", @@ -5506,7 +5617,7 @@ dependencies = [ "clap_complete_fig", "clap_complete_nushell", "futures", - "hashbrown", + "hashbrown 0.16.1", "regex", "vergen-gitcl", "yazi-adapter", @@ -5522,6 +5633,7 @@ name = "yazi-build" version = "26.1.22" dependencies = [ "yazi-term", + "yazi-tty", ] [[package]] @@ -5565,8 +5677,8 @@ dependencies = [ "crossterm 0.29.0", "dirs", "globset", - "hashbrown", - "indexmap", + "hashbrown 0.16.1", + "indexmap 2.13.0", "ratatui", "regex", "serde", @@ -5578,6 +5690,7 @@ dependencies = [ "yazi-macro", "yazi-shared", "yazi-term", + "yazi-tty", ] [[package]] @@ -5586,8 +5699,8 @@ version = "26.1.22" dependencies = [ "anyhow", "crossterm 0.29.0", - "hashbrown", - "indexmap", + "hashbrown 0.16.1", + "indexmap 2.13.0", "parking_lot", "ratatui", "tokio", @@ -5615,7 +5728,7 @@ name = "yazi-dds" version = "26.1.22" dependencies = [ "anyhow", - "hashbrown", + "hashbrown 0.16.1", "mlua", "ordered-float 5.1.0", "parking_lot", @@ -5681,6 +5794,7 @@ dependencies = [ "yazi-proxy", "yazi-shared", "yazi-term", + "yazi-tty", "yazi-vfs", "yazi-watcher", "yazi-widgets", @@ -5696,7 +5810,7 @@ dependencies = [ "core-foundation-sys", "dirs", "foldhash", - "hashbrown", + "hashbrown 0.16.1", "libc", "objc2", "parking_lot", @@ -5733,10 +5847,11 @@ dependencies = [ "bitflags 2.10.0", "crossterm 0.29.0", "dyn-clone", - "hashbrown", + "hashbrown 0.16.1", "mlua", "ordered-float 5.1.0", "serde", + "serde_with", "tokio", "yazi-binding", "yazi-boot", @@ -5754,7 +5869,7 @@ dependencies = [ "anyhow", "crossterm 0.29.0", "futures", - "hashbrown", + "hashbrown 0.16.1", "libc", "mlua", "parking_lot", @@ -5811,7 +5926,7 @@ dependencies = [ "anyhow", "async-priority-channel", "foldhash", - "hashbrown", + "hashbrown 0.16.1", "libc", "lru", "mlua", @@ -5854,7 +5969,7 @@ dependencies = [ "dyn-clone", "foldhash", "futures", - "hashbrown", + "hashbrown 0.16.1", "libc", "memchr", "ordered-float 5.1.0", @@ -5882,6 +5997,17 @@ name = "yazi-term" version = "26.1.22" dependencies = [ "crossterm 0.29.0", + "libc", + "parking_lot", + "tracing", + "yazi-macro", + "yazi-shared", +] + +[[package]] +name = "yazi-tty" +version = "26.1.22" +dependencies = [ "libc", "parking_lot", "tracing", @@ -5897,7 +6023,7 @@ dependencies = [ "anyhow", "deadpool", "futures", - "hashbrown", + "hashbrown 0.16.1", "parking_lot", "russh", "tokio", @@ -5915,7 +6041,7 @@ name = "yazi-watcher" version = "26.1.22" dependencies = [ "anyhow", - "hashbrown", + "hashbrown 0.16.1", "notify", "parking_lot", "percent-encoding", @@ -5950,6 +6076,7 @@ dependencies = [ "yazi-parser", "yazi-shared", "yazi-term", + "yazi-tty", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 8a133b3e..fd98d7e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,6 +55,7 @@ russh = { version = "0.57.0", default-features = false, features = scopeguard = "1.2.0" serde = { version = "1.0.228", features = [ "derive" ] } serde_json = "1.0.149" +serde_with = "3.16.1" syntect = { version = "5.3.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] } thiserror = "2.0.18" tokio = { version = "1.49.0", features = [ "full" ] } diff --git a/yazi-actor/Cargo.toml b/yazi-actor/Cargo.toml index 01ac9fa1..e94ab82d 100644 --- a/yazi-actor/Cargo.toml +++ b/yazi-actor/Cargo.toml @@ -29,6 +29,7 @@ yazi-proxy = { path = "../yazi-proxy", version = "26.1.22" } yazi-scheduler = { path = "../yazi-scheduler", version = "26.1.22" } yazi-shared = { path = "../yazi-shared", version = "26.1.22" } yazi-term = { path = "../yazi-term", version = "26.1.22" } +yazi-tty = { path = "../yazi-tty", version = "26.1.22" } yazi-vfs = { path = "../yazi-vfs", version = "26.1.22" } yazi-watcher = { path = "../yazi-watcher", version = "26.1.22" } yazi-widgets = { path = "../yazi-widgets", version = "26.1.22" } diff --git a/yazi-actor/src/mgr/bulk_rename.rs b/yazi-actor/src/mgr/bulk_rename.rs index 9c853bd9..ad0a99ca 100644 --- a/yazi-actor/src/mgr/bulk_rename.rs +++ b/yazi-actor/src/mgr/bulk_rename.rs @@ -13,7 +13,7 @@ use yazi_macro::{err, succ}; use yazi_parser::VoidOpt; use yazi_proxy::{AppProxy, HIDER, TasksProxy}; use yazi_shared::{data::Data, path::PathDyn, strand::{AsStrand, AsStrandJoin, Strand, StrandBuf, StrandLike}, terminal_clear, url::{AsUrl, UrlBuf, UrlCow, UrlLike}}; -use yazi_term::tty::TTY; +use yazi_tty::TTY; use yazi_vfs::{VfsFile, maybe_exists, provider}; use yazi_watcher::WATCHER; diff --git a/yazi-actor/src/mgr/refresh.rs b/yazi-actor/src/mgr/refresh.rs index 7ca8ff14..14875ce7 100644 --- a/yazi-actor/src/mgr/refresh.rs +++ b/yazi-actor/src/mgr/refresh.rs @@ -7,7 +7,7 @@ use yazi_macro::{act, succ}; use yazi_parser::VoidOpt; use yazi_proxy::MgrProxy; use yazi_shared::{data::Data, url::{UrlBuf, UrlLike}}; -use yazi_term::tty::TTY; +use yazi_tty::TTY; use yazi_vfs::{VfsFiles, VfsFilesOp}; use crate::{Actor, Ctx}; diff --git a/yazi-actor/src/tasks/inspect.rs b/yazi-actor/src/tasks/inspect.rs index dc78acd5..7c762bfb 100644 --- a/yazi-actor/src/tasks/inspect.rs +++ b/yazi-actor/src/tasks/inspect.rs @@ -9,7 +9,7 @@ use yazi_macro::succ; use yazi_parser::VoidOpt; use yazi_proxy::{AppProxy, HIDER}; use yazi_shared::{data::Data, terminal_clear}; -use yazi_term::tty::TTY; +use yazi_tty::TTY; use crate::{Actor, Ctx}; diff --git a/yazi-adapter/Cargo.toml b/yazi-adapter/Cargo.toml index a9b637fb..49bf7dff 100644 --- a/yazi-adapter/Cargo.toml +++ b/yazi-adapter/Cargo.toml @@ -17,6 +17,7 @@ yazi-fs = { path = "../yazi-fs", version = "26.1.22" } yazi-macro = { path = "../yazi-macro", version = "26.1.22" } yazi-shared = { path = "../yazi-shared", version = "26.1.22" } yazi-term = { path = "../yazi-term", version = "26.1.22" } +yazi-tty = { path = "../yazi-tty", version = "26.1.22" } # External dependencies ansi-to-tui = { workspace = true } diff --git a/yazi-adapter/src/adapter.rs b/yazi-adapter/src/adapter.rs index e10b7db7..1011f611 100644 --- a/yazi-adapter/src/adapter.rs +++ b/yazi-adapter/src/adapter.rs @@ -5,7 +5,7 @@ use ratatui::layout::Rect; use tracing::warn; use yazi_shared::env_exists; -use crate::{Emulator, SHOWN, TMUX, drivers}; +use crate::{Adapters, Emulator, SHOWN, TMUX, drivers}; #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum Adapter { @@ -85,13 +85,13 @@ impl Adapter { impl Adapter { pub fn matches(emulator: &Emulator) -> Self { - let mut protocols = emulator.adapters().to_owned(); + let mut adapters: Adapters = emulator.into(); if env_exists("ZELLIJ_SESSION_NAME") { - protocols.retain(|p| *p == Self::Sixel); + adapters.retain(|p| *p == Self::Sixel); } else if TMUX.get() { - protocols.retain(|p| *p != Self::KgpOld); + adapters.retain(|p| *p != Self::KgpOld); } - if let Some(p) = protocols.first() { + if let Some(p) = adapters.first() { return *p; } diff --git a/yazi-adapter/src/adapters.rs b/yazi-adapter/src/adapters.rs new file mode 100644 index 00000000..ca4a5e89 --- /dev/null +++ b/yazi-adapter/src/adapters.rs @@ -0,0 +1,69 @@ +use std::ops::{Deref, DerefMut}; + +use yazi_shared::Either; + +use crate::{Adapter, Brand, Emulator, Unknown}; + +pub(super) struct Adapters(Vec); + +impl Deref for Adapters { + type Target = Vec; + + fn deref(&self) -> &Self::Target { &self.0 } +} + +impl DerefMut for Adapters { + fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } +} + +impl From<&Emulator> for Adapters { + fn from(value: &Emulator) -> Self { + match value.kind { + Either::Left(b) => b.into(), + Either::Right(u) => u.into(), + } + } +} + +impl From for Adapters { + fn from(value: Brand) -> Self { + use Brand as B; + + use crate::Adapter as A; + + Self(match value { + B::Kitty => vec![A::Kgp], + B::Konsole => vec![A::KgpOld], + B::Iterm2 => vec![A::Iip, A::Sixel], + B::WezTerm => vec![A::Iip, A::Sixel], + B::Foot => vec![A::Sixel], + B::Ghostty => vec![A::Kgp], + B::Microsoft => vec![A::Sixel], + B::Warp => vec![A::Iip, A::KgpOld], + B::Rio => vec![A::Iip, A::Sixel], + B::BlackBox => vec![A::Sixel], + B::VSCode => vec![A::Iip, A::Sixel], + B::Tabby => vec![A::Iip, A::Sixel], + B::Hyper => vec![A::Iip, A::Sixel], + B::Mintty => vec![A::Iip], + B::Tmux => vec![], + B::VTerm => vec![], + B::Apple => vec![], + B::Urxvt => vec![], + B::Bobcat => vec![A::Iip, A::Sixel], + }) + } +} + +impl From for Adapters { + fn from(value: Unknown) -> Self { + use Adapter as A; + + Self(match (value.kgp, value.sixel) { + (true, true) => vec![A::Sixel, A::KgpOld], + (true, false) => vec![A::KgpOld], + (false, true) => vec![A::Sixel], + (false, false) => vec![], + }) + } +} diff --git a/yazi-adapter/src/brand.rs b/yazi-adapter/src/brand.rs index c180591c..51a6a21e 100644 --- a/yazi-adapter/src/brand.rs +++ b/yazi-adapter/src/brand.rs @@ -88,32 +88,6 @@ impl Brand { None } - pub(super) fn adapters(self) -> &'static [crate::Adapter] { - use crate::Adapter as A; - - match self { - Self::Kitty => &[A::Kgp], - Self::Konsole => &[A::KgpOld], - Self::Iterm2 => &[A::Iip, A::Sixel], - Self::WezTerm => &[A::Iip, A::Sixel], - Self::Foot => &[A::Sixel], - Self::Ghostty => &[A::Kgp], - Self::Microsoft => &[A::Sixel], - Self::Warp => &[A::Iip, A::KgpOld], - Self::Rio => &[A::Iip, A::Sixel], - Self::BlackBox => &[A::Sixel], - Self::VSCode => &[A::Iip, A::Sixel], - Self::Tabby => &[A::Iip, A::Sixel], - Self::Hyper => &[A::Iip, A::Sixel], - Self::Mintty => &[A::Iip], - Self::Tmux => &[], - Self::VTerm => &[], - Self::Apple => &[], - Self::Urxvt => &[], - Self::Bobcat => &[A::Iip, A::Sixel], - } - } - fn env() -> (String, String) { let (term, program) = Mux::term_program(); ( diff --git a/yazi-adapter/src/drivers/kgp_old.rs b/yazi-adapter/src/drivers/kgp_old.rs index a2aa23d8..9f87ba35 100644 --- a/yazi-adapter/src/drivers/kgp_old.rs +++ b/yazi-adapter/src/drivers/kgp_old.rs @@ -5,7 +5,7 @@ use anyhow::Result; use base64::{Engine, engine::general_purpose}; use image::DynamicImage; use ratatui::layout::Rect; -use yazi_term::tty::TTY; +use yazi_tty::TTY; use crate::{CLOSE, ESCAPE, Emulator, Image, START, adapter::Adapter}; diff --git a/yazi-adapter/src/emulator.rs b/yazi-adapter/src/emulator.rs index 4d192917..6ee8e3fe 100644 --- a/yazi-adapter/src/emulator.rs +++ b/yazi-adapter/src/emulator.rs @@ -6,9 +6,9 @@ use scopeguard::defer; use tokio::time::sleep; use tracing::{debug, error, warn}; use yazi_shared::Either; -use yazi_term::tty::{Handle, TTY}; +use yazi_tty::{Handle, TTY}; -use crate::{Adapter, Brand, Dimension, Mux, TMUX, Unknown}; +use crate::{Brand, Dimension, Mux, TMUX, Unknown}; #[derive(Clone, Debug)] pub struct Emulator { @@ -76,13 +76,6 @@ impl Emulator { }) } - pub fn adapters(&self) -> &'static [Adapter] { - match self.kind { - Either::Left(brand) => brand.adapters(), - Either::Right(unknown) => unknown.adapters(), - } - } - pub fn move_lock((x, y): (u16, u16), cb: F) -> Result where F: FnOnce(&mut BufWriter) -> Result, diff --git a/yazi-adapter/src/lib.rs b/yazi-adapter/src/lib.rs index 4333d583..1bf99bf9 100644 --- a/yazi-adapter/src/lib.rs +++ b/yazi-adapter/src/lib.rs @@ -1,6 +1,6 @@ yazi_macro::mod_pub!(drivers); -yazi_macro::mod_flat!(adapter brand dimension emulator icc image info mux unknown); +yazi_macro::mod_flat!(adapter adapters brand dimension emulator icc image info mux unknown); use yazi_shared::{RoCell, SyncCell, in_wsl}; diff --git a/yazi-adapter/src/mux.rs b/yazi-adapter/src/mux.rs index b102acd6..3bc396cb 100644 --- a/yazi-adapter/src/mux.rs +++ b/yazi-adapter/src/mux.rs @@ -3,7 +3,7 @@ use std::borrow::Cow; use anyhow::Result; use tracing::error; use yazi_macro::time; -use yazi_term::tty::TTY; +use yazi_tty::TTY; use crate::{CLOSE, ESCAPE, Emulator, START, TMUX}; diff --git a/yazi-adapter/src/unknown.rs b/yazi-adapter/src/unknown.rs index 74f5f8fd..ba004d66 100644 --- a/yazi-adapter/src/unknown.rs +++ b/yazi-adapter/src/unknown.rs @@ -1,20 +1,5 @@ -use crate::Adapter; - #[derive(Clone, Copy, Debug, Default)] pub struct Unknown { pub kgp: bool, pub sixel: bool, } - -impl Unknown { - pub(super) fn adapters(self) -> &'static [Adapter] { - use Adapter as A; - - match (self.kgp, self.sixel) { - (true, true) => &[A::Sixel, A::KgpOld], - (true, false) => &[A::KgpOld], - (false, true) => &[A::Sixel], - (false, false) => &[], - } - } -} diff --git a/yazi-build/Cargo.toml b/yazi-build/Cargo.toml index 95c35bfd..98d00fea 100644 --- a/yazi-build/Cargo.toml +++ b/yazi-build/Cargo.toml @@ -19,6 +19,7 @@ strip = true [build-dependencies] yazi-term = { path = "../yazi-term", version = "26.1.22" } +yazi-tty = { path = "../yazi-tty", version = "26.1.22" } [[bin]] name = "yazi-build" diff --git a/yazi-build/build.rs b/yazi-build/build.rs index 34bfeefb..34b78d02 100644 --- a/yazi-build/build.rs +++ b/yazi-build/build.rs @@ -1,9 +1,9 @@ use std::{env, error::Error, io::{BufRead, BufReader, Read, Write}, process::{Command, Stdio}, thread}; -use yazi_term::tty::TTY; +use yazi_tty::TTY; fn main() -> Result<(), Box> { - yazi_term::init(); + yazi_tty::init(); let manifest = env::var_os("CARGO_MANIFEST_DIR").unwrap().to_string_lossy().replace(r"\", "/"); let crates = if manifest.contains("/git/checkouts/yazi-") { diff --git a/yazi-config/Cargo.toml b/yazi-config/Cargo.toml index 2f203321..61573e79 100644 --- a/yazi-config/Cargo.toml +++ b/yazi-config/Cargo.toml @@ -17,6 +17,7 @@ yazi-fs = { path = "../yazi-fs", version = "26.1.22" } yazi-macro = { path = "../yazi-macro", version = "26.1.22" } yazi-shared = { path = "../yazi-shared", version = "26.1.22" } yazi-term = { path = "../yazi-term", version = "26.1.22" } +yazi-tty = { path = "../yazi-tty", version = "26.1.22" } # External dependencies anyhow = { workspace = true } diff --git a/yazi-config/src/lib.rs b/yazi-config/src/lib.rs index 7668fd29..023e796c 100644 --- a/yazi-config/src/lib.rs +++ b/yazi-config/src/lib.rs @@ -5,7 +5,7 @@ yazi_macro::mod_flat!(icon layout pattern platform preset priority style utils y use std::io::{Read, Write}; use yazi_shared::{RoCell, SyncCell}; -use yazi_term::tty::TTY; +use yazi_tty::TTY; pub static YAZI: RoCell = RoCell::new(); pub static KEYMAP: RoCell = RoCell::new(); diff --git a/yazi-fm/Cargo.toml b/yazi-fm/Cargo.toml index 8ce177ed..81f34d46 100644 --- a/yazi-fm/Cargo.toml +++ b/yazi-fm/Cargo.toml @@ -40,6 +40,7 @@ yazi-plugin = { path = "../yazi-plugin", version = "26.1.22" } yazi-proxy = { path = "../yazi-proxy", version = "26.1.22" } yazi-shared = { path = "../yazi-shared", version = "26.1.22" } yazi-term = { path = "../yazi-term", version = "26.1.22" } +yazi-tty = { path = "../yazi-tty", version = "26.1.22" } yazi-vfs = { path = "../yazi-vfs", version = "26.1.22" } yazi-watcher = { path = "../yazi-watcher", version = "26.1.22" } yazi-widgets = { path = "../yazi-widgets", version = "26.1.22" } diff --git a/yazi-fm/src/app/commands/render.rs b/yazi-fm/src/app/commands/render.rs index 123ccfe6..cc8836b5 100644 --- a/yazi-fm/src/app/commands/render.rs +++ b/yazi-fm/src/app/commands/render.rs @@ -8,7 +8,7 @@ use yazi_binding::elements::COLLISION; use yazi_macro::{act, succ}; use yazi_parser::VoidOpt; use yazi_shared::{data::Data, event::NEED_RENDER}; -use yazi_term::tty::TTY; +use yazi_tty::TTY; use crate::{app::App, root::Root}; diff --git a/yazi-fm/src/main.rs b/yazi-fm/src/main.rs index 6f7f0153..feeb5266 100644 --- a/yazi-fm/src/main.rs +++ b/yazi-fm/src/main.rs @@ -14,7 +14,7 @@ async fn main() -> anyhow::Result<()> { Logs::start()?; _ = fdlimit::raise_fd_limit(); - yazi_term::init(); + yazi_tty::init(); yazi_fs::init(); diff --git a/yazi-fm/src/term.rs b/yazi-fm/src/term.rs index c906befc..9527d9bd 100644 --- a/yazi-fm/src/term.rs +++ b/yazi-fm/src/term.rs @@ -6,7 +6,7 @@ use ratatui::{CompletedFrame, Frame, Terminal, backend::CrosstermBackend, buffer use yazi_adapter::{Emulator, Mux, TMUX}; use yazi_config::{THEME, YAZI}; use yazi_shared::SyncCell; -use yazi_term::tty::{TTY, TtyWriter}; +use yazi_tty::{TTY, TtyWriter}; static CSI_U: AtomicBool = AtomicBool::new(false); diff --git a/yazi-parser/Cargo.toml b/yazi-parser/Cargo.toml index 381575f2..b0bd11b1 100644 --- a/yazi-parser/Cargo.toml +++ b/yazi-parser/Cargo.toml @@ -33,4 +33,5 @@ hashbrown = { workspace = true } mlua = { workspace = true } ordered-float = { workspace = true } serde = { workspace = true } +serde_with = { workspace = true } tokio = { workspace = true } diff --git a/yazi-parser/src/app/notify.rs b/yazi-parser/src/app/notify.rs index 027652d1..08622b1f 100644 --- a/yazi-parser/src/app/notify.rs +++ b/yazi-parser/src/app/notify.rs @@ -1,16 +1,19 @@ use std::{str::FromStr, time::Duration}; use anyhow::anyhow; -use mlua::{ExternalError, ExternalResult}; -use serde::Deserialize; +use mlua::{FromLua, IntoLua, Lua, LuaSerdeExt, Value}; +use serde::{Deserialize, Serialize}; +use serde_with::{DurationSeconds, serde_as}; use yazi_config::{Style, THEME}; use yazi_shared::event::CmdCow; -#[derive(Clone)] +#[serde_as] +#[derive(Clone, Deserialize, Serialize)] pub struct NotifyOpt { pub title: String, pub content: String, pub level: NotifyLevel, + #[serde_as(as = "DurationSeconds")] // FIXME pub timeout: Duration, } @@ -22,32 +25,16 @@ impl TryFrom for NotifyOpt { } } -impl TryFrom for NotifyOpt { - type Error = mlua::Error; +impl FromLua for NotifyOpt { + fn from_lua(value: Value, lua: &Lua) -> mlua::Result { lua.from_value(value) } +} - fn try_from(t: mlua::Table) -> Result { - let timeout = t.raw_get("timeout")?; - if timeout < 0.0 { - return Err("timeout must be non-negative".into_lua_err()); - } - - let level = if let Ok(s) = t.raw_get::("level") { - s.to_str()?.parse().into_lua_err()? - } else { - Default::default() - }; - - Ok(Self { - title: t.raw_get("title")?, - content: t.raw_get("content")?, - level, - timeout: Duration::from_secs_f64(timeout), - }) - } +impl IntoLua for NotifyOpt { + fn into_lua(self, lua: &Lua) -> mlua::Result { lua.to_value(&self) } } // --- Level -#[derive(Clone, Copy, Default, Deserialize, Eq, PartialEq)] +#[derive(Clone, Copy, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(rename_all = "kebab-case")] pub enum NotifyLevel { #[default] diff --git a/yazi-plugin/src/utils/layer.rs b/yazi-plugin/src/utils/layer.rs index d0f7a81d..c829b627 100644 --- a/yazi-plugin/src/utils/layer.rs +++ b/yazi-plugin/src/utils/layer.rs @@ -6,7 +6,7 @@ use tokio_stream::wrappers::UnboundedReceiverStream; use yazi_binding::{elements::{Line, Pos, Text}, runtime}; use yazi_config::{keymap::{Chord, ChordCow, Key}, popup::{ConfirmCfg, InputCfg}}; use yazi_macro::relay; -use yazi_parser::which::ActivateOpt; +use yazi_parser::{app::NotifyOpt, which::ActivateOpt}; use yazi_proxy::{AppProxy, ConfirmProxy, InputProxy, WhichProxy}; use yazi_shared::Debounce; @@ -100,10 +100,7 @@ impl Utils { } pub(super) fn notify(lua: &Lua) -> mlua::Result { - lua.create_function(|_, t: Table| { - AppProxy::notify(t.try_into()?); - Ok(()) - }) + lua.create_function(|_, opt: NotifyOpt| Ok(AppProxy::notify(opt))) } fn parse_keys(value: Value) -> mlua::Result> { diff --git a/yazi-term/Cargo.toml b/yazi-term/Cargo.toml index 4e54fd74..3199591a 100644 --- a/yazi-term/Cargo.toml +++ b/yazi-term/Cargo.toml @@ -15,18 +15,13 @@ workspace = true yazi-macro = { path = "../yazi-macro", version = "26.1.22" } yazi-shared = { path = "../yazi-shared", version = "26.1.22" } -# Logging -tracing = { workspace = true } - # External dependencies crossterm = { workspace = true } parking_lot = { workspace = true } +tracing = { workspace = true } [target."cfg(unix)".dependencies] libc = { workspace = true } [target.'cfg(target_os = "macos")'.dependencies] crossterm = { workspace = true, features = [ "use-dev-tty", "libc" ] } - -[target.'cfg(windows)'.dependencies] -windows-sys = { version = "0.61.2", features = [ "Win32_Globalization", "Win32_Storage_FileSystem", "Win32_System_IO", "Win32_System_Console", "Win32_System_Threading", "Win32_Security" ] } diff --git a/yazi-term/src/lib.rs b/yazi-term/src/lib.rs index 1be38f4f..e3bf6e8c 100644 --- a/yazi-term/src/lib.rs +++ b/yazi-term/src/lib.rs @@ -1,5 +1 @@ -yazi_macro::mod_pub!(tty); - yazi_macro::mod_flat!(background cursor r#if); - -pub fn init() { tty::init(); } diff --git a/yazi-tty/Cargo.toml b/yazi-tty/Cargo.toml new file mode 100644 index 00000000..f2de9f00 --- /dev/null +++ b/yazi-tty/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "yazi-tty" +version = "26.1.22" +edition = "2024" +license = "MIT" +authors = [ "sxyazi " ] +description = "Yazi TTY access layer" +homepage = "https://yazi-rs.github.io" +repository = "https://github.com/sxyazi/yazi" + +[lints] +workspace = true + +[dependencies] +yazi-macro = { path = "../yazi-macro", version = "26.1.22" } +yazi-shared = { path = "../yazi-shared", version = "26.1.22" } + +# External dependencies +parking_lot = { workspace = true } +tracing = { workspace = true } + +[target."cfg(unix)".dependencies] +libc = { workspace = true } + +[target.'cfg(windows)'.dependencies] +windows-sys = { version = "0.61.2", features = [ "Win32_Globalization", "Win32_Storage_FileSystem", "Win32_System_IO", "Win32_System_Console", "Win32_System_Threading", "Win32_Security" ] } diff --git a/yazi-tty/README.md b/yazi-tty/README.md new file mode 100644 index 00000000..5a309446 --- /dev/null +++ b/yazi-tty/README.md @@ -0,0 +1,5 @@ +# yazi-tty + +This crate is part of [Yazi][source], and it is not supposed to be used outside, as there are no guarantees about the stability of its API. + +[source]: https://github.com/sxyazi/yazi diff --git a/yazi-term/src/tty/handle.rs b/yazi-tty/src/handle.rs similarity index 100% rename from yazi-term/src/tty/handle.rs rename to yazi-tty/src/handle.rs diff --git a/yazi-term/src/tty/mod.rs b/yazi-tty/src/lib.rs similarity index 76% rename from yazi-term/src/tty/mod.rs rename to yazi-tty/src/lib.rs index b02aab83..59e3ed0e 100644 --- a/yazi-term/src/tty/mod.rs +++ b/yazi-tty/src/lib.rs @@ -5,4 +5,4 @@ yazi_macro::mod_flat!(windows); pub static TTY: yazi_shared::RoCell = yazi_shared::RoCell::new(); -pub(super) fn init() { TTY.with(<_>::default); } +pub fn init() { TTY.with(<_>::default); } diff --git a/yazi-term/src/tty/tty.rs b/yazi-tty/src/tty.rs similarity index 100% rename from yazi-term/src/tty/tty.rs rename to yazi-tty/src/tty.rs diff --git a/yazi-term/src/tty/windows.rs b/yazi-tty/src/windows.rs similarity index 100% rename from yazi-term/src/tty/windows.rs rename to yazi-tty/src/windows.rs diff --git a/yazi-widgets/Cargo.toml b/yazi-widgets/Cargo.toml index 4c1ec9a1..843bff4a 100644 --- a/yazi-widgets/Cargo.toml +++ b/yazi-widgets/Cargo.toml @@ -18,6 +18,7 @@ yazi-macro = { path = "../yazi-macro", version = "26.1.22" } yazi-parser = { path = "../yazi-parser", version = "26.1.22" } yazi-shared = { path = "../yazi-shared", version = "26.1.22" } yazi-term = { path = "../yazi-term", version = "26.1.22" } +yazi-tty = { path = "../yazi-tty", version = "26.1.22" } # External dependencies anyhow = { workspace = true } diff --git a/yazi-widgets/src/clipboard.rs b/yazi-widgets/src/clipboard.rs index 8b0d20ec..c65c399c 100644 --- a/yazi-widgets/src/clipboard.rs +++ b/yazi-widgets/src/clipboard.rs @@ -55,7 +55,7 @@ impl Clipboard { use crossterm::execute; use tokio::{io::AsyncWriteExt, process::Command}; - use yazi_term::tty::TTY; + use yazi_tty::TTY; s.as_ref().clone_into(&mut self.content.lock()); execute!(TTY.writer(), osc52::SetClipboard::new(s.as_ref())).ok();