refactor: new yazi-tty crate (#3623)

This commit is contained in:
三咲雅 misaki masa 2026-01-27 22:03:48 +08:00 committed by GitHub
parent 6150571738
commit e0911f2507
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 293 additions and 131 deletions

171
Cargo.lock generated
View file

@ -583,6 +583,7 @@ dependencies = [
"iana-time-zone", "iana-time-zone",
"js-sys", "js-sys",
"num-traits", "num-traits",
"serde",
"wasm-bindgen", "wasm-bindgen",
"windows-link", "windows-link",
] ]
@ -1002,6 +1003,16 @@ dependencies = [
"darling_macro 0.20.11", "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]] [[package]]
name = "darling" name = "darling"
version = "0.23.0" version = "0.23.0"
@ -1026,6 +1037,20 @@ dependencies = [
"syn 2.0.114", "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]] [[package]]
name = "darling_core" name = "darling_core"
version = "0.23.0" version = "0.23.0"
@ -1050,6 +1075,17 @@ dependencies = [
"syn 2.0.114", "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]] [[package]]
name = "darling_macro" name = "darling_macro"
version = "0.23.0" version = "0.23.0"
@ -1134,6 +1170,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587"
dependencies = [ dependencies = [
"powerfmt", "powerfmt",
"serde_core",
] ]
[[package]] [[package]]
@ -1759,6 +1796,12 @@ dependencies = [
"zerocopy", "zerocopy",
] ]
[[package]]
name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.16.1" version = "0.16.1"
@ -1938,6 +1981,17 @@ version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8" 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]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.13.0" version = "2.13.0"
@ -1945,7 +1999,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown", "hashbrown 0.16.1",
"serde", "serde",
"serde_core", "serde_core",
] ]
@ -2091,7 +2145,7 @@ version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fe90c1150662e858c7d5f945089b7517b0a80d8bf7ba4b1b5ffc984e7230a5b" checksum = "8fe90c1150662e858c7d5f945089b7517b0a80d8bf7ba4b1b5ffc984e7230a5b"
dependencies = [ dependencies = [
"hashbrown", "hashbrown 0.16.1",
"portable-atomic", "portable-atomic",
"thiserror 2.0.18", "thiserror 2.0.18",
] ]
@ -2292,7 +2346,7 @@ version = "0.16.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593" checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593"
dependencies = [ dependencies = [
"hashbrown", "hashbrown 0.16.1",
] ]
[[package]] [[package]]
@ -3097,7 +3151,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07" checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07"
dependencies = [ dependencies = [
"base64", "base64",
"indexmap", "indexmap 2.13.0",
"quick-xml", "quick-xml",
"serde", "serde",
"time", "time",
@ -3380,7 +3434,7 @@ checksum = "5ef8dea09a92caaf73bff7adb70b76162e5937524058a7e5bff37869cbbec293"
dependencies = [ dependencies = [
"bitflags 2.10.0", "bitflags 2.10.0",
"compact_str", "compact_str",
"hashbrown", "hashbrown 0.16.1",
"indoc", "indoc",
"itertools", "itertools",
"kasuari", "kasuari",
@ -3444,7 +3498,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7dbfa023cd4e604c2553483820c5fe8aa9d71a42eea5aa77c6e7f35756612db" checksum = "d7dbfa023cd4e604c2553483820c5fe8aa9d71a42eea5aa77c6e7f35756612db"
dependencies = [ dependencies = [
"bitflags 2.10.0", "bitflags 2.10.0",
"hashbrown", "hashbrown 0.16.1",
"indoc", "indoc",
"instability", "instability",
"itertools", "itertools",
@ -3816,6 +3870,30 @@ dependencies = [
"winapi-util", "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]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.2.0" version = "1.2.0"
@ -3915,6 +3993,37 @@ dependencies = [
"serde_core", "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]] [[package]]
name = "serdect" name = "serdect"
version = "0.4.2" 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" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46" checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46"
dependencies = [ dependencies = [
"indexmap", "indexmap 2.13.0",
"serde_core", "serde_core",
"serde_spanned", "serde_spanned",
"toml_datetime", "toml_datetime",
@ -5426,7 +5535,7 @@ dependencies = [
"anyhow", "anyhow",
"crossterm 0.29.0", "crossterm 0.29.0",
"futures", "futures",
"hashbrown", "hashbrown 0.16.1",
"libc", "libc",
"mlua", "mlua",
"paste", "paste",
@ -5447,6 +5556,7 @@ dependencies = [
"yazi-scheduler", "yazi-scheduler",
"yazi-shared", "yazi-shared",
"yazi-term", "yazi-term",
"yazi-tty",
"yazi-vfs", "yazi-vfs",
"yazi-watcher", "yazi-watcher",
"yazi-widgets", "yazi-widgets",
@ -5473,6 +5583,7 @@ dependencies = [
"yazi-macro", "yazi-macro",
"yazi-shared", "yazi-shared",
"yazi-term", "yazi-term",
"yazi-tty",
] ]
[[package]] [[package]]
@ -5481,7 +5592,7 @@ version = "26.1.22"
dependencies = [ dependencies = [
"ansi-to-tui", "ansi-to-tui",
"futures", "futures",
"hashbrown", "hashbrown 0.16.1",
"mlua", "mlua",
"paste", "paste",
"ratatui", "ratatui",
@ -5506,7 +5617,7 @@ dependencies = [
"clap_complete_fig", "clap_complete_fig",
"clap_complete_nushell", "clap_complete_nushell",
"futures", "futures",
"hashbrown", "hashbrown 0.16.1",
"regex", "regex",
"vergen-gitcl", "vergen-gitcl",
"yazi-adapter", "yazi-adapter",
@ -5522,6 +5633,7 @@ name = "yazi-build"
version = "26.1.22" version = "26.1.22"
dependencies = [ dependencies = [
"yazi-term", "yazi-term",
"yazi-tty",
] ]
[[package]] [[package]]
@ -5565,8 +5677,8 @@ dependencies = [
"crossterm 0.29.0", "crossterm 0.29.0",
"dirs", "dirs",
"globset", "globset",
"hashbrown", "hashbrown 0.16.1",
"indexmap", "indexmap 2.13.0",
"ratatui", "ratatui",
"regex", "regex",
"serde", "serde",
@ -5578,6 +5690,7 @@ dependencies = [
"yazi-macro", "yazi-macro",
"yazi-shared", "yazi-shared",
"yazi-term", "yazi-term",
"yazi-tty",
] ]
[[package]] [[package]]
@ -5586,8 +5699,8 @@ version = "26.1.22"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"crossterm 0.29.0", "crossterm 0.29.0",
"hashbrown", "hashbrown 0.16.1",
"indexmap", "indexmap 2.13.0",
"parking_lot", "parking_lot",
"ratatui", "ratatui",
"tokio", "tokio",
@ -5615,7 +5728,7 @@ name = "yazi-dds"
version = "26.1.22" version = "26.1.22"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"hashbrown", "hashbrown 0.16.1",
"mlua", "mlua",
"ordered-float 5.1.0", "ordered-float 5.1.0",
"parking_lot", "parking_lot",
@ -5681,6 +5794,7 @@ dependencies = [
"yazi-proxy", "yazi-proxy",
"yazi-shared", "yazi-shared",
"yazi-term", "yazi-term",
"yazi-tty",
"yazi-vfs", "yazi-vfs",
"yazi-watcher", "yazi-watcher",
"yazi-widgets", "yazi-widgets",
@ -5696,7 +5810,7 @@ dependencies = [
"core-foundation-sys", "core-foundation-sys",
"dirs", "dirs",
"foldhash", "foldhash",
"hashbrown", "hashbrown 0.16.1",
"libc", "libc",
"objc2", "objc2",
"parking_lot", "parking_lot",
@ -5733,10 +5847,11 @@ dependencies = [
"bitflags 2.10.0", "bitflags 2.10.0",
"crossterm 0.29.0", "crossterm 0.29.0",
"dyn-clone", "dyn-clone",
"hashbrown", "hashbrown 0.16.1",
"mlua", "mlua",
"ordered-float 5.1.0", "ordered-float 5.1.0",
"serde", "serde",
"serde_with",
"tokio", "tokio",
"yazi-binding", "yazi-binding",
"yazi-boot", "yazi-boot",
@ -5754,7 +5869,7 @@ dependencies = [
"anyhow", "anyhow",
"crossterm 0.29.0", "crossterm 0.29.0",
"futures", "futures",
"hashbrown", "hashbrown 0.16.1",
"libc", "libc",
"mlua", "mlua",
"parking_lot", "parking_lot",
@ -5811,7 +5926,7 @@ dependencies = [
"anyhow", "anyhow",
"async-priority-channel", "async-priority-channel",
"foldhash", "foldhash",
"hashbrown", "hashbrown 0.16.1",
"libc", "libc",
"lru", "lru",
"mlua", "mlua",
@ -5854,7 +5969,7 @@ dependencies = [
"dyn-clone", "dyn-clone",
"foldhash", "foldhash",
"futures", "futures",
"hashbrown", "hashbrown 0.16.1",
"libc", "libc",
"memchr", "memchr",
"ordered-float 5.1.0", "ordered-float 5.1.0",
@ -5882,6 +5997,17 @@ name = "yazi-term"
version = "26.1.22" version = "26.1.22"
dependencies = [ dependencies = [
"crossterm 0.29.0", "crossterm 0.29.0",
"libc",
"parking_lot",
"tracing",
"yazi-macro",
"yazi-shared",
]
[[package]]
name = "yazi-tty"
version = "26.1.22"
dependencies = [
"libc", "libc",
"parking_lot", "parking_lot",
"tracing", "tracing",
@ -5897,7 +6023,7 @@ dependencies = [
"anyhow", "anyhow",
"deadpool", "deadpool",
"futures", "futures",
"hashbrown", "hashbrown 0.16.1",
"parking_lot", "parking_lot",
"russh", "russh",
"tokio", "tokio",
@ -5915,7 +6041,7 @@ name = "yazi-watcher"
version = "26.1.22" version = "26.1.22"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"hashbrown", "hashbrown 0.16.1",
"notify", "notify",
"parking_lot", "parking_lot",
"percent-encoding", "percent-encoding",
@ -5950,6 +6076,7 @@ dependencies = [
"yazi-parser", "yazi-parser",
"yazi-shared", "yazi-shared",
"yazi-term", "yazi-term",
"yazi-tty",
] ]
[[package]] [[package]]

View file

@ -55,6 +55,7 @@ russh = { version = "0.57.0", default-features = false, features =
scopeguard = "1.2.0" scopeguard = "1.2.0"
serde = { version = "1.0.228", features = [ "derive" ] } serde = { version = "1.0.228", features = [ "derive" ] }
serde_json = "1.0.149" serde_json = "1.0.149"
serde_with = "3.16.1"
syntect = { version = "5.3.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] } syntect = { version = "5.3.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] }
thiserror = "2.0.18" thiserror = "2.0.18"
tokio = { version = "1.49.0", features = [ "full" ] } tokio = { version = "1.49.0", features = [ "full" ] }

View file

@ -29,6 +29,7 @@ yazi-proxy = { path = "../yazi-proxy", version = "26.1.22" }
yazi-scheduler = { path = "../yazi-scheduler", version = "26.1.22" } yazi-scheduler = { path = "../yazi-scheduler", version = "26.1.22" }
yazi-shared = { path = "../yazi-shared", version = "26.1.22" } yazi-shared = { path = "../yazi-shared", version = "26.1.22" }
yazi-term = { path = "../yazi-term", 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-vfs = { path = "../yazi-vfs", version = "26.1.22" }
yazi-watcher = { path = "../yazi-watcher", version = "26.1.22" } yazi-watcher = { path = "../yazi-watcher", version = "26.1.22" }
yazi-widgets = { path = "../yazi-widgets", version = "26.1.22" } yazi-widgets = { path = "../yazi-widgets", version = "26.1.22" }

View file

@ -13,7 +13,7 @@ use yazi_macro::{err, succ};
use yazi_parser::VoidOpt; use yazi_parser::VoidOpt;
use yazi_proxy::{AppProxy, HIDER, TasksProxy}; 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_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_vfs::{VfsFile, maybe_exists, provider};
use yazi_watcher::WATCHER; use yazi_watcher::WATCHER;

View file

@ -7,7 +7,7 @@ use yazi_macro::{act, succ};
use yazi_parser::VoidOpt; use yazi_parser::VoidOpt;
use yazi_proxy::MgrProxy; use yazi_proxy::MgrProxy;
use yazi_shared::{data::Data, url::{UrlBuf, UrlLike}}; use yazi_shared::{data::Data, url::{UrlBuf, UrlLike}};
use yazi_term::tty::TTY; use yazi_tty::TTY;
use yazi_vfs::{VfsFiles, VfsFilesOp}; use yazi_vfs::{VfsFiles, VfsFilesOp};
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};

View file

@ -9,7 +9,7 @@ use yazi_macro::succ;
use yazi_parser::VoidOpt; use yazi_parser::VoidOpt;
use yazi_proxy::{AppProxy, HIDER}; use yazi_proxy::{AppProxy, HIDER};
use yazi_shared::{data::Data, terminal_clear}; use yazi_shared::{data::Data, terminal_clear};
use yazi_term::tty::TTY; use yazi_tty::TTY;
use crate::{Actor, Ctx}; use crate::{Actor, Ctx};

View file

@ -17,6 +17,7 @@ yazi-fs = { path = "../yazi-fs", version = "26.1.22" }
yazi-macro = { path = "../yazi-macro", version = "26.1.22" } yazi-macro = { path = "../yazi-macro", version = "26.1.22" }
yazi-shared = { path = "../yazi-shared", version = "26.1.22" } yazi-shared = { path = "../yazi-shared", version = "26.1.22" }
yazi-term = { path = "../yazi-term", version = "26.1.22" } yazi-term = { path = "../yazi-term", version = "26.1.22" }
yazi-tty = { path = "../yazi-tty", version = "26.1.22" }
# External dependencies # External dependencies
ansi-to-tui = { workspace = true } ansi-to-tui = { workspace = true }

View file

@ -5,7 +5,7 @@ use ratatui::layout::Rect;
use tracing::warn; use tracing::warn;
use yazi_shared::env_exists; use yazi_shared::env_exists;
use crate::{Emulator, SHOWN, TMUX, drivers}; use crate::{Adapters, Emulator, SHOWN, TMUX, drivers};
#[derive(Clone, Copy, Debug, Eq, PartialEq)] #[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Adapter { pub enum Adapter {
@ -85,13 +85,13 @@ impl Adapter {
impl Adapter { impl Adapter {
pub fn matches(emulator: &Emulator) -> Self { 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") { if env_exists("ZELLIJ_SESSION_NAME") {
protocols.retain(|p| *p == Self::Sixel); adapters.retain(|p| *p == Self::Sixel);
} else if TMUX.get() { } 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; return *p;
} }

View file

@ -0,0 +1,69 @@
use std::ops::{Deref, DerefMut};
use yazi_shared::Either;
use crate::{Adapter, Brand, Emulator, Unknown};
pub(super) struct Adapters(Vec<Adapter>);
impl Deref for Adapters {
type Target = Vec<Adapter>;
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<Brand> 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<Unknown> 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![],
})
}
}

View file

@ -88,32 +88,6 @@ impl Brand {
None 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) { fn env() -> (String, String) {
let (term, program) = Mux::term_program(); let (term, program) = Mux::term_program();
( (

View file

@ -5,7 +5,7 @@ use anyhow::Result;
use base64::{Engine, engine::general_purpose}; use base64::{Engine, engine::general_purpose};
use image::DynamicImage; use image::DynamicImage;
use ratatui::layout::Rect; use ratatui::layout::Rect;
use yazi_term::tty::TTY; use yazi_tty::TTY;
use crate::{CLOSE, ESCAPE, Emulator, Image, START, adapter::Adapter}; use crate::{CLOSE, ESCAPE, Emulator, Image, START, adapter::Adapter};

View file

@ -6,9 +6,9 @@ use scopeguard::defer;
use tokio::time::sleep; use tokio::time::sleep;
use tracing::{debug, error, warn}; use tracing::{debug, error, warn};
use yazi_shared::Either; 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)] #[derive(Clone, Debug)]
pub struct Emulator { 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<F, T>((x, y): (u16, u16), cb: F) -> Result<T> pub fn move_lock<F, T>((x, y): (u16, u16), cb: F) -> Result<T>
where where
F: FnOnce(&mut BufWriter<Handle>) -> Result<T>, F: FnOnce(&mut BufWriter<Handle>) -> Result<T>,

View file

@ -1,6 +1,6 @@
yazi_macro::mod_pub!(drivers); 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}; use yazi_shared::{RoCell, SyncCell, in_wsl};

View file

@ -3,7 +3,7 @@ use std::borrow::Cow;
use anyhow::Result; use anyhow::Result;
use tracing::error; use tracing::error;
use yazi_macro::time; use yazi_macro::time;
use yazi_term::tty::TTY; use yazi_tty::TTY;
use crate::{CLOSE, ESCAPE, Emulator, START, TMUX}; use crate::{CLOSE, ESCAPE, Emulator, START, TMUX};

View file

@ -1,20 +1,5 @@
use crate::Adapter;
#[derive(Clone, Copy, Debug, Default)] #[derive(Clone, Copy, Debug, Default)]
pub struct Unknown { pub struct Unknown {
pub kgp: bool, pub kgp: bool,
pub sixel: 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) => &[],
}
}
}

View file

@ -19,6 +19,7 @@ strip = true
[build-dependencies] [build-dependencies]
yazi-term = { path = "../yazi-term", version = "26.1.22" } yazi-term = { path = "../yazi-term", version = "26.1.22" }
yazi-tty = { path = "../yazi-tty", version = "26.1.22" }
[[bin]] [[bin]]
name = "yazi-build" name = "yazi-build"

View file

@ -1,9 +1,9 @@
use std::{env, error::Error, io::{BufRead, BufReader, Read, Write}, process::{Command, Stdio}, thread}; 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<dyn Error>> { fn main() -> Result<(), Box<dyn Error>> {
yazi_term::init(); yazi_tty::init();
let manifest = env::var_os("CARGO_MANIFEST_DIR").unwrap().to_string_lossy().replace(r"\", "/"); let manifest = env::var_os("CARGO_MANIFEST_DIR").unwrap().to_string_lossy().replace(r"\", "/");
let crates = if manifest.contains("/git/checkouts/yazi-") { let crates = if manifest.contains("/git/checkouts/yazi-") {

View file

@ -17,6 +17,7 @@ yazi-fs = { path = "../yazi-fs", version = "26.1.22" }
yazi-macro = { path = "../yazi-macro", version = "26.1.22" } yazi-macro = { path = "../yazi-macro", version = "26.1.22" }
yazi-shared = { path = "../yazi-shared", version = "26.1.22" } yazi-shared = { path = "../yazi-shared", version = "26.1.22" }
yazi-term = { path = "../yazi-term", version = "26.1.22" } yazi-term = { path = "../yazi-term", version = "26.1.22" }
yazi-tty = { path = "../yazi-tty", version = "26.1.22" }
# External dependencies # External dependencies
anyhow = { workspace = true } anyhow = { workspace = true }

View file

@ -5,7 +5,7 @@ yazi_macro::mod_flat!(icon layout pattern platform preset priority style utils y
use std::io::{Read, Write}; use std::io::{Read, Write};
use yazi_shared::{RoCell, SyncCell}; use yazi_shared::{RoCell, SyncCell};
use yazi_term::tty::TTY; use yazi_tty::TTY;
pub static YAZI: RoCell<yazi::Yazi> = RoCell::new(); pub static YAZI: RoCell<yazi::Yazi> = RoCell::new();
pub static KEYMAP: RoCell<keymap::Keymap> = RoCell::new(); pub static KEYMAP: RoCell<keymap::Keymap> = RoCell::new();

View file

@ -40,6 +40,7 @@ yazi-plugin = { path = "../yazi-plugin", version = "26.1.22" }
yazi-proxy = { path = "../yazi-proxy", version = "26.1.22" } yazi-proxy = { path = "../yazi-proxy", version = "26.1.22" }
yazi-shared = { path = "../yazi-shared", version = "26.1.22" } yazi-shared = { path = "../yazi-shared", version = "26.1.22" }
yazi-term = { path = "../yazi-term", 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-vfs = { path = "../yazi-vfs", version = "26.1.22" }
yazi-watcher = { path = "../yazi-watcher", version = "26.1.22" } yazi-watcher = { path = "../yazi-watcher", version = "26.1.22" }
yazi-widgets = { path = "../yazi-widgets", version = "26.1.22" } yazi-widgets = { path = "../yazi-widgets", version = "26.1.22" }

View file

@ -8,7 +8,7 @@ use yazi_binding::elements::COLLISION;
use yazi_macro::{act, succ}; use yazi_macro::{act, succ};
use yazi_parser::VoidOpt; use yazi_parser::VoidOpt;
use yazi_shared::{data::Data, event::NEED_RENDER}; use yazi_shared::{data::Data, event::NEED_RENDER};
use yazi_term::tty::TTY; use yazi_tty::TTY;
use crate::{app::App, root::Root}; use crate::{app::App, root::Root};

View file

@ -14,7 +14,7 @@ async fn main() -> anyhow::Result<()> {
Logs::start()?; Logs::start()?;
_ = fdlimit::raise_fd_limit(); _ = fdlimit::raise_fd_limit();
yazi_term::init(); yazi_tty::init();
yazi_fs::init(); yazi_fs::init();

View file

@ -6,7 +6,7 @@ use ratatui::{CompletedFrame, Frame, Terminal, backend::CrosstermBackend, buffer
use yazi_adapter::{Emulator, Mux, TMUX}; use yazi_adapter::{Emulator, Mux, TMUX};
use yazi_config::{THEME, YAZI}; use yazi_config::{THEME, YAZI};
use yazi_shared::SyncCell; use yazi_shared::SyncCell;
use yazi_term::tty::{TTY, TtyWriter}; use yazi_tty::{TTY, TtyWriter};
static CSI_U: AtomicBool = AtomicBool::new(false); static CSI_U: AtomicBool = AtomicBool::new(false);

View file

@ -33,4 +33,5 @@ hashbrown = { workspace = true }
mlua = { workspace = true } mlua = { workspace = true }
ordered-float = { workspace = true } ordered-float = { workspace = true }
serde = { workspace = true } serde = { workspace = true }
serde_with = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }

View file

@ -1,16 +1,19 @@
use std::{str::FromStr, time::Duration}; use std::{str::FromStr, time::Duration};
use anyhow::anyhow; use anyhow::anyhow;
use mlua::{ExternalError, ExternalResult}; use mlua::{FromLua, IntoLua, Lua, LuaSerdeExt, Value};
use serde::Deserialize; use serde::{Deserialize, Serialize};
use serde_with::{DurationSeconds, serde_as};
use yazi_config::{Style, THEME}; use yazi_config::{Style, THEME};
use yazi_shared::event::CmdCow; use yazi_shared::event::CmdCow;
#[derive(Clone)] #[serde_as]
#[derive(Clone, Deserialize, Serialize)]
pub struct NotifyOpt { pub struct NotifyOpt {
pub title: String, pub title: String,
pub content: String, pub content: String,
pub level: NotifyLevel, pub level: NotifyLevel,
#[serde_as(as = "DurationSeconds<f64>")] // FIXME
pub timeout: Duration, pub timeout: Duration,
} }
@ -22,32 +25,16 @@ impl TryFrom<CmdCow> for NotifyOpt {
} }
} }
impl TryFrom<mlua::Table> for NotifyOpt { impl FromLua for NotifyOpt {
type Error = mlua::Error; fn from_lua(value: Value, lua: &Lua) -> mlua::Result<Self> { lua.from_value(value) }
fn try_from(t: mlua::Table) -> Result<Self, Self::Error> {
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::<mlua::String>("level") { impl IntoLua for NotifyOpt {
s.to_str()?.parse().into_lua_err()? fn into_lua(self, lua: &Lua) -> mlua::Result<Value> { lua.to_value(&self) }
} else {
Default::default()
};
Ok(Self {
title: t.raw_get("title")?,
content: t.raw_get("content")?,
level,
timeout: Duration::from_secs_f64(timeout),
})
}
} }
// --- Level // --- Level
#[derive(Clone, Copy, Default, Deserialize, Eq, PartialEq)] #[derive(Clone, Copy, Default, Deserialize, Eq, PartialEq, Serialize)]
#[serde(rename_all = "kebab-case")] #[serde(rename_all = "kebab-case")]
pub enum NotifyLevel { pub enum NotifyLevel {
#[default] #[default]

View file

@ -6,7 +6,7 @@ use tokio_stream::wrappers::UnboundedReceiverStream;
use yazi_binding::{elements::{Line, Pos, Text}, runtime}; use yazi_binding::{elements::{Line, Pos, Text}, runtime};
use yazi_config::{keymap::{Chord, ChordCow, Key}, popup::{ConfirmCfg, InputCfg}}; use yazi_config::{keymap::{Chord, ChordCow, Key}, popup::{ConfirmCfg, InputCfg}};
use yazi_macro::relay; 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_proxy::{AppProxy, ConfirmProxy, InputProxy, WhichProxy};
use yazi_shared::Debounce; use yazi_shared::Debounce;
@ -100,10 +100,7 @@ impl Utils {
} }
pub(super) fn notify(lua: &Lua) -> mlua::Result<Function> { pub(super) fn notify(lua: &Lua) -> mlua::Result<Function> {
lua.create_function(|_, t: Table| { lua.create_function(|_, opt: NotifyOpt| Ok(AppProxy::notify(opt)))
AppProxy::notify(t.try_into()?);
Ok(())
})
} }
fn parse_keys(value: Value) -> mlua::Result<Vec<Key>> { fn parse_keys(value: Value) -> mlua::Result<Vec<Key>> {

View file

@ -15,18 +15,13 @@ workspace = true
yazi-macro = { path = "../yazi-macro", version = "26.1.22" } yazi-macro = { path = "../yazi-macro", version = "26.1.22" }
yazi-shared = { path = "../yazi-shared", version = "26.1.22" } yazi-shared = { path = "../yazi-shared", version = "26.1.22" }
# Logging
tracing = { workspace = true }
# External dependencies # External dependencies
crossterm = { workspace = true } crossterm = { workspace = true }
parking_lot = { workspace = true } parking_lot = { workspace = true }
tracing = { workspace = true }
[target."cfg(unix)".dependencies] [target."cfg(unix)".dependencies]
libc = { workspace = true } libc = { workspace = true }
[target.'cfg(target_os = "macos")'.dependencies] [target.'cfg(target_os = "macos")'.dependencies]
crossterm = { workspace = true, features = [ "use-dev-tty", "libc" ] } 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" ] }

View file

@ -1,5 +1 @@
yazi_macro::mod_pub!(tty);
yazi_macro::mod_flat!(background cursor r#if); yazi_macro::mod_flat!(background cursor r#if);
pub fn init() { tty::init(); }

26
yazi-tty/Cargo.toml Normal file
View file

@ -0,0 +1,26 @@
[package]
name = "yazi-tty"
version = "26.1.22"
edition = "2024"
license = "MIT"
authors = [ "sxyazi <sxyazi@gmail.com>" ]
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" ] }

5
yazi-tty/README.md Normal file
View file

@ -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

View file

@ -5,4 +5,4 @@ yazi_macro::mod_flat!(windows);
pub static TTY: yazi_shared::RoCell<Tty> = yazi_shared::RoCell::new(); pub static TTY: yazi_shared::RoCell<Tty> = yazi_shared::RoCell::new();
pub(super) fn init() { TTY.with(<_>::default); } pub fn init() { TTY.with(<_>::default); }

View file

@ -18,6 +18,7 @@ yazi-macro = { path = "../yazi-macro", version = "26.1.22" }
yazi-parser = { path = "../yazi-parser", version = "26.1.22" } yazi-parser = { path = "../yazi-parser", version = "26.1.22" }
yazi-shared = { path = "../yazi-shared", version = "26.1.22" } yazi-shared = { path = "../yazi-shared", version = "26.1.22" }
yazi-term = { path = "../yazi-term", version = "26.1.22" } yazi-term = { path = "../yazi-term", version = "26.1.22" }
yazi-tty = { path = "../yazi-tty", version = "26.1.22" }
# External dependencies # External dependencies
anyhow = { workspace = true } anyhow = { workspace = true }

View file

@ -55,7 +55,7 @@ impl Clipboard {
use crossterm::execute; use crossterm::execute;
use tokio::{io::AsyncWriteExt, process::Command}; use tokio::{io::AsyncWriteExt, process::Command};
use yazi_term::tty::TTY; use yazi_tty::TTY;
s.as_ref().clone_into(&mut self.content.lock()); s.as_ref().clone_into(&mut self.content.lock());
execute!(TTY.writer(), osc52::SetClipboard::new(s.as_ref())).ok(); execute!(TTY.writer(), osc52::SetClipboard::new(s.as_ref())).ok();