This commit is contained in:
sxyazi 2023-11-23 20:27:17 +08:00
parent 1270fd15f9
commit a1197b5c83
No known key found for this signature in database
3 changed files with 88 additions and 3 deletions

View file

@ -7,7 +7,7 @@ use tracing::warn;
use yazi_config::PREVIEW;
use yazi_shared::{env_exists, RoCell};
use super::{Iterm2, Kitty};
use super::{Iterm2, Kitty, KittyOld};
use crate::{ueberzug::Ueberzug, Sixel, TMUX};
static IMAGE_SHOWN: AtomicBool = AtomicBool::new(false);
@ -18,6 +18,7 @@ static UEBERZUG: RoCell<Option<UnboundedSender<Option<(PathBuf, Rect)>>>> = RoCe
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Adaptor {
Kitty,
KittyOld,
Iterm2,
Sixel,
@ -83,7 +84,7 @@ impl Adaptor {
let mut protocols = match Self::emulator() {
Emulator::Unknown => vec![],
Emulator::Kitty => vec![Self::Kitty],
Emulator::Konsole => vec![Self::Kitty, Self::Iterm2, Self::Sixel],
Emulator::Konsole => vec![Self::KittyOld, Self::Iterm2, Self::Sixel],
Emulator::Iterm2 => vec![Self::Iterm2, Self::Sixel],
Emulator::WezTerm => vec![Self::Iterm2, Self::Sixel],
Emulator::Foot => vec![Self::Sixel],
@ -99,6 +100,9 @@ impl Adaptor {
if env_exists("ZELLIJ_SESSION_NAME") {
protocols.retain(|p| *p == Self::Sixel);
}
if *TMUX && protocols.len() > 1 {
protocols.retain(|p| *p != Self::KittyOld);
}
if let Some(p) = protocols.first() {
return *p;
}
@ -148,6 +152,7 @@ impl ToString for Adaptor {
fn to_string(&self) -> String {
match self {
Self::Kitty => "kitty",
Self::KittyOld => "kitty",
Self::Iterm2 => "iterm2",
Self::Sixel => "sixel",
Self::X11 => "x11",
@ -174,6 +179,7 @@ impl Adaptor {
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,
_ => Ok(if let Some(tx) = &*UEBERZUG {
@ -190,6 +196,7 @@ impl Adaptor {
match self {
Self::Kitty => Kitty::image_hide(rect),
Self::Iterm2 => Iterm2::image_hide(rect),
Self::KittyOld => KittyOld::image_hide(),
Self::Sixel => Sixel::image_hide(rect),
_ => Ok(if let Some(tx) = &*UEBERZUG {
tx.send(None)?;
@ -199,6 +206,6 @@ impl Adaptor {
#[inline]
pub(super) fn needs_ueberzug(self) -> bool {
!matches!(self, Self::Kitty | Self::Iterm2 | Self::Sixel)
!matches!(self, Self::Kitty | Self::KittyOld | Self::Iterm2 | Self::Sixel)
}
}

View file

@ -0,0 +1,76 @@
use std::{io::{stdout, Write}, path::Path};
use anyhow::Result;
use base64::{engine::general_purpose, Engine};
use image::DynamicImage;
use ratatui::prelude::Rect;
use yazi_shared::Term;
use super::image::Image;
use crate::{CLOSE, ESCAPE, START};
pub(super) struct KittyOld;
impl KittyOld {
pub(super) async fn image_show(path: &Path, rect: Rect) -> Result<()> {
let img = Image::downscale(path, (rect.width, rect.height)).await?;
let b = Self::encode(img).await?;
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<()> {
let mut stdout = stdout().lock();
stdout.write_all(format!("{}_Gq=1,a=d,d=A{}\\{}", START, ESCAPE, CLOSE).as_bytes())?;
stdout.flush()?;
Ok(())
}
async fn encode(img: DynamicImage) -> Result<Vec<u8>> {
fn output(raw: &[u8], format: u8, size: (u32, u32)) -> Result<Vec<u8>> {
let b64 = general_purpose::STANDARD.encode(raw).chars().collect::<Vec<_>>();
let mut it = b64.chunks(4096).peekable();
let mut buf = Vec::with_capacity(b64.len() + it.len() * 50);
if let Some(first) = it.next() {
write!(
buf,
"{}_Gq=1,a=T,z=-1,C=1,f={},s={},v={},m={};{}{}\\{}",
START,
format,
size.0,
size.1,
it.peek().is_some() as u8,
first.iter().collect::<String>(),
ESCAPE,
CLOSE
)?;
}
while let Some(chunk) = it.next() {
write!(
buf,
"{}_Gm={};{}{}\\{}",
START,
it.peek().is_some() as u8,
chunk.iter().collect::<String>(),
ESCAPE,
CLOSE
)?;
}
buf.write_all(CLOSE.as_bytes())?;
Ok(buf)
}
let size = (img.width(), img.height());
tokio::task::spawn_blocking(move || match img {
DynamicImage::ImageRgb8(v) => output(v.as_raw(), 24, size),
DynamicImage::ImageRgba8(v) => output(v.as_raw(), 32, size),
v => output(v.to_rgb8().as_raw(), 24, size),
})
.await?
}
}

View file

@ -4,12 +4,14 @@ mod adaptor;
mod image;
mod iterm2;
mod kitty;
mod kitty_old;
mod sixel;
mod ueberzug;
use adaptor::*;
use iterm2::*;
use kitty::*;
use kitty_old::*;
use sixel::*;
use yazi_shared::{env_exists, RoCell};