Skip to content
Closed
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
- Remove `lazy_static` dependency in favor of `std::sync::LazyLock`
- MSRV is now 1.80
- Use sixel if found in device attributes instead of static TERM list
- Dont Error in kitty if the temporary file has been deleted by the terminal. (Now `KittySupport::Local` is possible again)
- Properly check for kitty support on terminals via protocol query, instead of static `TERM` environment variable checking.
- This for example allows new terminals like (KDE)`Konsole`
- When using Kitty Local & Remote, wait until the terminal has responded before returning.

## 0.9.2
- Use iterm and sixel in more terminals
Expand Down
1 change: 1 addition & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::utils;

/// Configuration struct to customize printing behaviour.
#[derive(Debug, Clone)]
pub struct Config {
/// Enable true transparency instead of checkerboard background.
/// Available only for the block printer. Defaults to false.
Expand Down
9 changes: 7 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#[cfg(feature = "print-file")]
use std::path::Path;

use console::Term;
use crossterm::{
cursor::{RestorePosition, SavePosition},
execute,
Expand Down Expand Up @@ -99,7 +100,9 @@ pub fn print(img: &DynamicImage, config: &Config) -> ViuResult<(u32, u32)> {
execute!(&mut stdout, SavePosition)?;
}

let (w, h) = choose_printer(config).print(&mut stdout, img, config)?;
let term = Term::stdout();

let (w, h) = choose_printer(config).print(&mut stdout, &term, img, config)?;

if config.restore_cursor {
execute!(&mut stdout, RestorePosition)?;
Expand Down Expand Up @@ -130,7 +133,9 @@ pub fn print_from_file<P: AsRef<Path>>(filename: P, config: &Config) -> ViuResul
execute!(&mut stdout, SavePosition)?;
}

let (w, h) = choose_printer(config).print_from_file(&mut stdout, filename, config)?;
let term = Term::stdout();

let (w, h) = choose_printer(config).print_from_file(&mut stdout, &term, filename, config)?;

if config.restore_cursor {
execute!(&mut stdout, RestorePosition)?;
Expand Down
4 changes: 3 additions & 1 deletion src/printer/block.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::error::ViuResult;
use crate::printer::{adjust_offset, Printer};
use crate::printer::{adjust_offset, Printer, ReadKey};
use crate::Config;

use ansi_colours::ansi256_from_rgb;
Expand All @@ -16,13 +16,15 @@ const LOWER_HALF_BLOCK: &str = "\u{2584}";
const CHECKERBOARD_BACKGROUND_LIGHT: (u8, u8, u8) = (153, 153, 153);
const CHECKERBOARD_BACKGROUND_DARK: (u8, u8, u8) = (102, 102, 102);

#[derive(Debug, Clone)]
pub struct BlockPrinter;

impl Printer for BlockPrinter {
fn print(
&self,
// TODO: The provided object is not used because termcolor needs an implementation of the WriteColor trait
_stdout: &mut impl Write,
_stdin: &impl ReadKey,
img: &DynamicImage,
config: &Config,
) -> ViuResult<(u32, u32)> {
Expand Down
3 changes: 2 additions & 1 deletion src/printer/icy_sixel.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::{adjust_offset, find_best_fit, Printer};
use super::{adjust_offset, find_best_fit, Printer, ReadKey};
use icy_sixel::sixel_string;
use image::{imageops::FilterType, GenericImageView};

Expand All @@ -8,6 +8,7 @@ impl Printer for IcySixelPrinter {
fn print(
&self,
stdout: &mut impl std::io::Write,
_stdin: &impl ReadKey,
img: &image::DynamicImage,
config: &crate::Config,
) -> crate::ViuResult<(u32, u32)> {
Expand Down
20 changes: 15 additions & 5 deletions src/printer/iterm.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::error::ViuResult;
use crate::printer::{adjust_offset, find_best_fit, Printer};
use crate::printer::{adjust_offset, find_best_fit, Printer, ReadKey};
use crate::Config;
use base64::{engine::general_purpose, Engine};
use image::{DynamicImage, GenericImageView, ImageEncoder};
Expand All @@ -12,20 +12,22 @@ use std::{
path::Path,
};

#[allow(non_camel_case_types)]
pub struct iTermPrinter;

static ITERM_SUPPORT: LazyLock<bool> = LazyLock::new(check_iterm_support);

/// Returns the terminal's support for the iTerm graphics protocol.
pub fn is_iterm_supported() -> bool {
*ITERM_SUPPORT
}

#[allow(non_camel_case_types)]
#[derive(Debug, Clone)]
pub struct iTermPrinter;

impl Printer for iTermPrinter {
fn print(
&self,
stdout: &mut impl Write,
_stdin: &impl ReadKey,
img: &DynamicImage,
config: &Config,
) -> ViuResult<(u32, u32)> {
Expand All @@ -47,6 +49,7 @@ impl Printer for iTermPrinter {
fn print_from_file<P: AsRef<Path>>(
&self,
stdout: &mut impl Write,
_stdin: &impl ReadKey,
filename: P,
config: &Config,
) -> ViuResult<(u32, u32)> {
Expand Down Expand Up @@ -113,6 +116,8 @@ fn check_iterm_support() -> bool {

#[cfg(test)]
mod tests {
use crate::printer::TestKeys;

use super::*;
use image::GenericImage;

Expand All @@ -128,7 +133,12 @@ mod tests {
};
let mut vec = Vec::new();

assert_eq!(iTermPrinter.print(&mut vec, &img, &config).unwrap(), (2, 2));
let stdin = TestKeys::new(&[]);

assert_eq!(
iTermPrinter.print(&mut vec, &stdin, &img, &config).unwrap(),
(2, 2)
);
assert_eq!(std::str::from_utf8(&vec).unwrap(), "\x1b[4;5H\x1b]1337;File=inline=1;preserveAspectRatio=1;size=95;width=2;height=2:iVBORw0KGgoAAAANSUhEUgAAAAIAAAADCAYAAAC56t6BAAAAJklEQVR4AQEbAOT/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACBAYIAEMAFdTlTsEAAAAASUVORK5CYII=\x07\n");
}
}
Loading