This commit is contained in:
sxyazi 2023-08-18 08:58:10 -07:00
parent 6f52057467
commit cf254f22a3
No known key found for this signature in database
9 changed files with 181 additions and 115 deletions

110
Cargo.lock generated
View file

@ -118,9 +118,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.73"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f768393e7fabd388fe8409b13faa4d93ab0fef35db1508438dfdb066918bcf38"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "app"
@ -277,9 +277,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.3.21"
version = "4.3.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c27cdf28c0f604ba3f512b0c9a409f8de8513e4816705deb0498b627e7c3a3fd"
checksum = "b417ae4361bca3f5de378294fc7472d3c4ed86a5ef9f49e93ae722f432aae8d2"
dependencies = [
"clap_builder",
"clap_derive",
@ -288,9 +288,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.3.21"
version = "4.3.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08a9f1ab5e9f01a9b81f202e8562eb9a10de70abf9eaeac1be465c28b75aa4aa"
checksum = "9c90dc0f0e42c64bff177ca9d7be6fcc9ddb0f26a6e062174a61c84dd6c644d4"
dependencies = [
"anstream",
"anstyle",
@ -307,7 +307,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.29",
]
[[package]]
@ -715,7 +715,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.29",
]
[[package]]
@ -1265,7 +1265,7 @@ dependencies = [
"libc",
"redox_syscall 0.3.5",
"smallvec",
"windows-targets 0.48.2",
"windows-targets 0.48.3",
]
[[package]]
@ -1297,7 +1297,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.29",
]
[[package]]
@ -1398,9 +1398,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.32"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
@ -1563,14 +1563,14 @@ checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.29",
]
[[package]]
name = "serde_json"
version = "1.0.104"
version = "1.0.105"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c"
checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360"
dependencies = [
"itoa",
"ryu",
@ -1714,9 +1714,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.28"
version = "2.0.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567"
checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a"
dependencies = [
"proc-macro2",
"quote",
@ -1746,22 +1746,22 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.45"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dedd246497092a89beedfe2c9f176d44c1b672ea6090edc20544ade01fbb7ea0"
checksum = "97a802ec30afc17eee47b2855fc72e0c4cd62be9b4efe6591edde0ec5bd68d8f"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.45"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d7b1fadccbbc7e19ea64708629f9d8dccd007c260d66485f20a6d41bc1cf4b3"
checksum = "6bb623b56e39ab7dcd4b1b98bb6c8f8d907ed255b18de254088016b27a8ee19b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.29",
]
[[package]]
@ -1830,9 +1830,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.31.0"
version = "1.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40de3a2ba249dcb097e01be5e67a5ff53cf250397715a071a81543e8a832a920"
checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9"
dependencies = [
"backtrace",
"bytes",
@ -1855,7 +1855,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.29",
]
[[package]]
@ -1924,7 +1924,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.29",
]
[[package]]
@ -2125,7 +2125,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.29",
"wasm-bindgen-shared",
]
@ -2147,7 +2147,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.28",
"syn 2.0.29",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -2210,7 +2210,7 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
dependencies = [
"windows-targets 0.48.2",
"windows-targets 0.48.3",
]
[[package]]
@ -2228,7 +2228,7 @@ version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets 0.48.2",
"windows-targets 0.48.3",
]
[[package]]
@ -2248,17 +2248,17 @@ dependencies = [
[[package]]
name = "windows-targets"
version = "0.48.2"
version = "0.48.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1eeca1c172a285ee6c2c84c341ccea837e7c01b12fbb2d0fe3c9e550ce49ec8"
checksum = "27f51fb4c64f8b770a823c043c7fad036323e1c48f55287b7bbb7987b2fcdf3b"
dependencies = [
"windows_aarch64_gnullvm 0.48.2",
"windows_aarch64_msvc 0.48.2",
"windows_i686_gnu 0.48.2",
"windows_i686_msvc 0.48.2",
"windows_x86_64_gnu 0.48.2",
"windows_x86_64_gnullvm 0.48.2",
"windows_x86_64_msvc 0.48.2",
"windows_aarch64_gnullvm 0.48.3",
"windows_aarch64_msvc 0.48.3",
"windows_i686_gnu 0.48.3",
"windows_i686_msvc 0.48.3",
"windows_x86_64_gnu 0.48.3",
"windows_x86_64_gnullvm 0.48.3",
"windows_x86_64_msvc 0.48.3",
]
[[package]]
@ -2269,9 +2269,9 @@ checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.2"
version = "0.48.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b10d0c968ba7f6166195e13d593af609ec2e3d24f916f081690695cf5eaffb2f"
checksum = "fde1bb55ae4ce76a597a8566d82c57432bc69c039449d61572a7a353da28f68c"
[[package]]
name = "windows_aarch64_msvc"
@ -2281,9 +2281,9 @@ checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.2"
version = "0.48.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "571d8d4e62f26d4932099a9efe89660e8bd5087775a2ab5cdd8b747b811f1058"
checksum = "1513e8d48365a78adad7322fd6b5e4c4e99d92a69db8df2d435b25b1f1f286d4"
[[package]]
name = "windows_i686_gnu"
@ -2293,9 +2293,9 @@ checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_gnu"
version = "0.48.2"
version = "0.48.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2229ad223e178db5fbbc8bd8d3835e51e566b8474bfca58d2e6150c48bb723cd"
checksum = "60587c0265d2b842298f5858e1a5d79d146f9ee0c37be5782e92a6eb5e1d7a83"
[[package]]
name = "windows_i686_msvc"
@ -2305,9 +2305,9 @@ checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_i686_msvc"
version = "0.48.2"
version = "0.48.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "600956e2d840c194eedfc5d18f8242bc2e17c7775b6684488af3a9fff6fe3287"
checksum = "224fe0e0ffff5d2ea6a29f82026c8f43870038a0ffc247aa95a52b47df381ac4"
[[package]]
name = "windows_x86_64_gnu"
@ -2317,9 +2317,9 @@ checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.2"
version = "0.48.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea99ff3f8b49fb7a8e0d305e5aec485bd068c2ba691b6e277d29eaeac945868a"
checksum = "62fc52a0f50a088de499712cbc012df7ebd94e2d6eb948435449d76a6287e7ad"
[[package]]
name = "windows_x86_64_gnullvm"
@ -2329,9 +2329,9 @@ checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.2"
version = "0.48.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f1a05a1ece9a7a0d5a7ccf30ba2c33e3a61a30e042ffd247567d1de1d94120d"
checksum = "2093925509d91ea3d69bcd20238f4c2ecdb1a29d3c281d026a09705d0dd35f3d"
[[package]]
name = "windows_x86_64_msvc"
@ -2341,15 +2341,15 @@ checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.2"
version = "0.48.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d419259aba16b663966e29e6d7c6ecfa0bb8425818bb96f6f1f3c3eb71a6e7b9"
checksum = "b6ade45bc8bf02ae2aa34a9d54ba660a1a58204da34ba793c00d83ca3730b5f1"
[[package]]
name = "winnow"
version = "0.5.10"
version = "0.5.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5504cc7644f4b593cbc05c4a55bf9bd4e94b867c3c0bd440934174d50482427d"
checksum = "d09770118a7eb1ccaf4a594a221334119a44a814fcb0d31c5b85e83e97227a97"
dependencies = [
"memchr",
]

View file

@ -1,4 +1,4 @@
use std::{path::{Path, PathBuf}, sync::atomic::{AtomicBool, Ordering}};
use std::path::{Path, PathBuf};
use anyhow::Result;
use config::{preview::PreviewAdaptor, BOOT, PREVIEW};
@ -9,8 +9,6 @@ use tokio::{fs, sync::mpsc::UnboundedSender};
use super::{Iterm2, Kitty};
use crate::Sixel;
static IMAGE_SHOWN: AtomicBool = AtomicBool::new(false);
#[allow(clippy::type_complexity)]
pub(super) static UEBERZUG: RoCell<Option<UnboundedSender<Option<(PathBuf, Rect)>>>> =
RoCell::new();
@ -19,10 +17,6 @@ pub struct Adaptor;
impl Adaptor {
pub async fn image_show(mut path: &Path, rect: Rect) -> Result<()> {
if IMAGE_SHOWN.swap(true, Ordering::Relaxed) {
Self::image_hide(rect).ok();
}
let cache = BOOT.cache(path);
if fs::metadata(&cache).await.is_ok() {
path = cache.as_path();
@ -39,9 +33,7 @@ impl Adaptor {
}
pub fn image_hide(rect: Rect) -> Result<()> {
if !IMAGE_SHOWN.swap(false, Ordering::Relaxed) {
return Ok(());
}
match PREVIEW.adaptor {
PreviewAdaptor::Kitty => Kitty::image_hide(),

View file

@ -1,4 +1,7 @@
use std::{io::{stdout, BufWriter, Write}, path::Path};
use std::{
io::{stdout, BufWriter, Write},
path::Path,
};
use anyhow::Result;
use base64::{engine::general_purpose, Engine};
@ -15,21 +18,19 @@ impl Iterm2 {
let img = Image::crop(path, (rect.width, rect.height)).await?;
let b = Self::encode(img).await?;
let mut stdout = stdout().lock();
Term::move_to(&mut stdout, rect.x, rect.y)?;
Ok(stdout.write_all(&b)?)
Self::image_hide(rect)?;
Term::move_lock(stdout().lock(), (rect.x, rect.y), |stdout| Ok(stdout.write_all(&b)?))
}
#[inline]
pub(super) fn image_hide(rect: Rect) -> Result<()> {
let s = " ".repeat(rect.width as usize);
let mut stdout = BufWriter::new(stdout().lock());
for y in rect.top()..=rect.bottom() {
Term::move_to(&mut stdout, rect.x, y)?;
stdout.write_all(s.as_bytes())?;
let stdout = BufWriter::new(stdout().lock());
Term::move_lock(stdout, (0, 0), |stdout| {
for y in rect.top()..rect.bottom() {
Term::move_to(stdout, rect.x, y)?;
Term::kill_to_end(stdout)?;
}
Ok(())
})
}
async fn encode(img: DynamicImage) -> Result<Vec<u8>> {

View file

@ -1,4 +1,7 @@
use std::{io::{stdout, Write}, path::Path};
use std::{
io::{stdout, Write},
path::Path,
};
use anyhow::Result;
use base64::{engine::general_purpose, Engine};
@ -15,13 +18,14 @@ impl Kitty {
let img = Image::crop(path, (rect.width, rect.height)).await?;
let b = Self::encode(img).await?;
let mut stdout = stdout().lock();
Term::move_to(&mut stdout, rect.x, rect.y)?;
Ok(stdout.write_all(&b)?)
Self::image_hide()?;
Term::move_lock(stdout().lock(), (rect.x, rect.y), |stdout| Ok(stdout.write_all(&b)?))
}
#[inline]
pub(super) fn image_hide() -> Result<()> { Ok(stdout().write_all(b"\x1b\\\x1b_Ga=d\x1b\\")?) }
pub(super) fn image_hide() -> Result<()> {
Ok(stdout().write_all(b"\x1b\\\x1b_Ga=d\x1b\\")?)
}
async fn encode(img: DynamicImage) -> Result<Vec<u8>> {
fn output(raw: &[u8], format: u8, size: (u32, u32)) -> Result<Vec<u8>> {

View file

@ -1,4 +1,7 @@
use std::{io::{stdout, BufWriter, Write}, path::Path};
use std::{
io::{stdout, BufWriter, Write},
path::Path,
};
use anyhow::{bail, Result};
use color_quant::NeuQuant;
@ -15,21 +18,19 @@ impl Sixel {
let img = Image::crop(path, (rect.width, rect.height)).await?;
let b = Self::encode(img).await?;
let mut stdout = stdout().lock();
Term::move_to(&mut stdout, rect.x, rect.y)?;
Ok(stdout.write_all(&b)?)
Self::image_hide(rect)?;
Term::move_lock(stdout().lock(), (rect.x, rect.y), |stdout| Ok(stdout.write_all(&b)?))
}
#[inline]
pub(super) fn image_hide(rect: Rect) -> Result<()> {
let s = " ".repeat(rect.width as usize);
let mut stdout = BufWriter::new(stdout().lock());
for y in rect.top()..=rect.bottom() {
Term::move_to(&mut stdout, rect.x, y)?;
stdout.write_all(s.as_bytes())?;
let stdout = BufWriter::new(stdout().lock());
Term::move_lock(stdout, (0, 0), |stdout| {
for y in rect.top()..rect.bottom() {
Term::move_to(stdout, rect.x, y)?;
Term::kill_to_end(stdout)?;
}
Ok(())
})
}
async fn encode(img: DynamicImage) -> Result<Vec<u8>> {

View file

@ -27,7 +27,7 @@ impl Default for PreviewAdaptor {
}
match env::var("TERM_PROGRAM").unwrap_or_default().as_str() {
"iTerm.app" => return Self::Iterm2,
"WezTerm" => return Self::Kitty,
"WezTerm" => return if cfg!(windows) { Self::Iterm2 } else { Self::Kitty },
"vscode" => return Self::Sixel,
"Hyper" => return Self::Sixel,
_ => {}

56
shared/src/term/cursor.rs Normal file
View file

@ -0,0 +1,56 @@
use anyhow::Result;
use std::io::{stdout, Write};
use crossterm::{
cursor::{self, MoveTo, RestorePosition, SavePosition, SetCursorStyle},
execute, queue,
terminal::{Clear, ClearType},
};
use crate::Term;
impl Term {
#[inline]
pub fn kill_to_end(stdout: &mut impl Write) -> Result<()> {
Ok(queue!(stdout, Clear(ClearType::UntilNewLine))?)
}
#[inline]
pub fn move_to(stdout: &mut impl Write, x: u16, y: u16) -> Result<()> {
Ok(queue!(stdout, MoveTo(x, y))?)
}
#[inline]
pub fn move_lock<W, F>(mut stdout: W, (x, y): (u16, u16), cb: F) -> Result<()>
where
W: Write,
F: FnOnce(&mut W) -> Result<()>,
{
#[cfg(target_os = "windows")]
{
queue!(&mut stdout, SavePosition, MoveTo(x, y), cursor::Show)?;
let result = cb(&mut stdout);
queue!(&mut stdout, cursor::Hide, RestorePosition)?;
stdout.flush()?;
result
}
#[cfg(not(target_os = "windows"))]
{
queue!(&mut stdout, SavePosition, MoveTo(x, y))?;
let result = cb(&mut stdout);
queue!(&mut stdout, RestorePosition)?;
stdout.flush()?;
result
}
}
#[inline]
pub fn set_cursor_block() -> Result<()> {
Ok(execute!(stdout(), SetCursorStyle::BlinkingBlock)?)
}
#[inline]
pub fn set_cursor_bar() -> Result<()> {
Ok(execute!(stdout(), SetCursorStyle::BlinkingBar)?)
}
}

5
shared/src/term/mod.rs Normal file
View file

@ -0,0 +1,5 @@
mod cursor;
mod term;
pub use cursor::*;
pub use term::*;

View file

@ -1,7 +1,21 @@
use std::{io::{stdout, Stdout, Write}, mem, ops::{Deref, DerefMut}};
use std::{
io::{stdout, Stdout, Write},
mem,
ops::{Deref, DerefMut},
};
use anyhow::Result;
use crossterm::{cursor::{MoveTo, SetCursorStyle}, event::{DisableBracketedPaste, DisableFocusChange, EnableBracketedPaste, EnableFocusChange, KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags}, execute, queue, terminal::{disable_raw_mode, enable_raw_mode, supports_keyboard_enhancement, Clear, ClearType, EnterAlternateScreen, LeaveAlternateScreen, WindowSize}};
use crossterm::{
event::{
DisableBracketedPaste, DisableFocusChange, EnableBracketedPaste, EnableFocusChange,
KeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags,
},
execute, queue,
terminal::{
disable_raw_mode, enable_raw_mode, supports_keyboard_enhancement, Clear, ClearType,
EnterAlternateScreen, LeaveAlternateScreen, WindowSize,
},
};
use ratatui::{backend::CrosstermBackend, Terminal};
pub struct Term {
@ -47,8 +61,8 @@ impl Term {
// TODO: Use `CSI 14 t` to get the actual size of the terminal
if size.width == 0 || size.height == 0 {
size.width = 300;
size.height = 300;
size.width = 1000;
size.height = 1000;
}
size
@ -62,21 +76,10 @@ impl Term {
#[inline]
pub fn clear(stdout: &mut impl Write) -> Result<()> {
execute!(stdout, Clear(ClearType::All))?;
queue!(stdout, Clear(ClearType::All))?;
writeln!(stdout)?;
Ok(stdout.flush()?)
}
#[inline]
pub fn move_to(stdout: &mut impl Write, x: u16, y: u16) -> Result<()> {
Ok(execute!(stdout, MoveTo(x, y))?)
}
#[inline]
pub fn set_cursor_block() -> Result<()> { Ok(execute!(stdout(), SetCursorStyle::BlinkingBlock)?) }
#[inline]
pub fn set_cursor_bar() -> Result<()> { Ok(execute!(stdout(), SetCursorStyle::BlinkingBar)?) }
}
impl Drop for Term {
@ -99,9 +102,13 @@ impl Drop for Term {
impl Deref for Term {
type Target = Terminal<CrosstermBackend<Stdout>>;
fn deref(&self) -> &Self::Target { &self.inner }
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl DerefMut for Term {
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.inner }
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}