Compare commits

...

8 Commits

Author SHA1 Message Date
June 971393892a v0.4.3 release 2025-09-07 20:32:16 -05:00
June 440515a3db Actually query terminals and fix terminals if we fail initialization (#103) 2025-09-06 12:02:04 -05:00
itsjunetime 690489016c fmt 2025-09-05 11:15:58 -05:00
itsjunetime bd5554db27 Update mupdf to use git dependency so it works on windows 2025-09-05 10:34:46 -05:00
itsjunetime 45409bacd0 fix CI? 2025-09-05 10:15:49 -05:00
itsjunetime 0481c14c4d fix CI 2025-09-05 08:41:38 -05:00
itsjunetime a78ea5a08c Update deps for new kittage 2025-09-05 08:31:03 -05:00
June f7eabc9af2 Require CI to run with locked flag so lockfile is always in sync (#100) 2025-08-29 09:17:14 -05:00
8 changed files with 348 additions and 288 deletions
+5 -5
View File
@@ -31,12 +31,12 @@ jobs:
- name: Install clippy and fmt - name: Install clippy and fmt
run: rustup component add clippy rustfmt run: rustup component add clippy rustfmt
- name: Clippy - name: Clippy
run: cargo clippy -- -D warnings run: cargo clippy --locked -- -D warnings
- name: Tests - name: Tests
run: cargo test run: cargo test --locked
- name: Check fmt - name: Check fmt
run: cargo fmt -- --check run: cargo fmt -- --check
- name: Run tests - name: Run benchmarks as tests
run: cargo test --benches -- adobe_example run: cargo test --locked --benches -- adobe_example
- name: Build - name: Build
run: cargo build run: cargo build --locked
+3
View File
@@ -1,6 +1,9 @@
# Unreleased # Unreleased
- Fix issue with some terminals hanging on startup
- Fix issues with some iterm2-backend terminals not displaying anything
- Allow using ctrl+scroll to zoom in/out while zoomed using kitty backend - Allow using ctrl+scroll to zoom in/out while zoomed using kitty backend
- (Internal) run CI with `--locked` flag to ensure lockfile is always in-sync
# v0.4.2 # v0.4.2
Generated
+256 -238
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -38,7 +38,7 @@ flume = { version = "0.11.0", default-features = false, features = ["async"] }
xflags = "0.4.0-pre.2" xflags = "0.4.0-pre.2"
mimalloc = "0.1.43" mimalloc = "0.1.43"
nix = { version = "0.30.0", features = ["signal"] } nix = { version = "0.30.0", features = ["signal"] }
mupdf = { version = "0.5.0", default-features = false, features = ["svg", "system-fonts", "img"] } mupdf = { git = "https://github.com/messense/mupdf-rs.git", rev = "2e0fae910fac8048c7008211fc4d3b9f5d227a07", default-features = false, features = ["svg", "system-fonts", "img"] }
rayon = { version = "*", default-features = false } rayon = { version = "*", default-features = false }
# kittage = { path = "../kittage/", features = ["crossterm-tokio", "image-crate", "log"] } # kittage = { path = "../kittage/", features = ["crossterm-tokio", "image-crate", "log"] }
kittage = { git = "https://github.com/itsjunetime/kittage.git", features = ["crossterm-tokio", "image-crate", "log"] } kittage = { git = "https://github.com/itsjunetime/kittage.git", features = ["crossterm-tokio", "image-crate", "log"] }
+7
View File
@@ -26,6 +26,7 @@ pub enum MaybeTransferred {
Transferred(kittage::ImageId) Transferred(kittage::ImageId)
} }
#[derive(Debug)]
pub enum ConvertedImage { pub enum ConvertedImage {
Generic(Protocol), Generic(Protocol),
Kitty { Kitty {
@@ -168,6 +169,12 @@ pub async fn run_conversion_loop(
) )
}; };
log::debug!(
"got converted page for num {} with results {:?}",
page_info.page_num,
page_info.result_rects
);
// update the iteration to the iteration that we stole this image from // update the iteration to the iteration that we stole this image from
*iteration = new_iter; *iteration = new_iter;
+58 -24
View File
@@ -1,9 +1,11 @@
use core::error::Error; use core::{
error::Error,
num::{NonZeroU32, NonZeroUsize}
};
use std::{ use std::{
borrow::Cow, borrow::Cow,
ffi::OsString, ffi::OsString,
io::{BufReader, Read, Stdout, stdout}, io::{BufReader, Read, Stdout, Write, stdout},
num::{NonZeroU32, NonZeroUsize},
path::PathBuf path::PathBuf
}; };
@@ -54,8 +56,27 @@ impl std::fmt::Debug for WrappedErr {
impl std::error::Error for WrappedErr {} impl std::error::Error for WrappedErr {}
fn reset_term() {
_ = execute!(
std::io::stdout(),
LeaveAlternateScreen,
crossterm::cursor::Show,
crossterm::event::DisableMouseCapture
)
}
#[tokio::main] #[tokio::main]
async fn main() -> Result<(), WrappedErr> { async fn main() -> Result<(), WrappedErr> {
inner_main().await.inspect_err(|_| reset_term())
}
async fn inner_main() -> Result<(), WrappedErr> {
let hook = std::panic::take_hook();
std::panic::set_hook(Box::new(move |info| {
reset_term();
hook(info);
}));
#[cfg(feature = "tracing")] #[cfg(feature = "tracing")]
console_subscriber::init(); console_subscriber::init();
@@ -172,14 +193,39 @@ async fn main() -> Result<(), WrappedErr> {
window_size.height = h; window_size.height = h;
} }
let cell_height_px = window_size.height / window_size.rows;
let cell_width_px = window_size.width / window_size.columns;
execute!(
std::io::stdout(),
EnterAlternateScreen,
crossterm::cursor::Hide,
crossterm::event::EnableMouseCapture
)
.map_err(|e| {
WrappedErr(
format!(
"Couldn't enter the alternate screen and hide the cursor for proper presentation: {e}"
)
.into()
)
})?;
// We need to create `picker` on this thread because if we create it on the `renderer` thread, // We need to create `picker` on this thread because if we create it on the `renderer` thread,
// it messes up something with user input. Input never makes it to the crossterm thing // it messes up something with user input. Input never makes it to the crossterm thing
let picker = Picker::from_query_stdio() let picker = Picker::from_query_stdio()
.map_err(|e| WrappedErr(match e { .or_else(|e| match e {
ratatui_image::errors::Errors::NoFontSize => ratatui_image::errors::Errors::NoFontSize if
"Unable to detect your terminal's font size; this is an issue with your terminal emulator.\nPlease use a different terminal emulator or report this bug to tdf.".into(), window_size.width != 0
e => format!("Couldn't get the necessary information to set up images: {e}").into() && window_size.height != 0
}))?; && window_size.columns != 0
&& window_size.rows != 0
=> Ok(Picker::from_fontsize((cell_width_px, cell_height_px))),
ratatui_image::errors::Errors::NoFontSize => Err(WrappedErr(
"Unable to detect your terminal's font size; this is an issue with your terminal emulator.\nPlease use a different terminal emulator or report this bug to tdf.".into()
)),
e => Err(WrappedErr(format!("Couldn't get the necessary information to set up images: {e}").into()))
})?;
// then we want to spawn off the rendering task // then we want to spawn off the rendering task
// We need to use the thread::spawn API so that this exists in a thread not owned by tokio, // We need to use the thread::spawn API so that this exists in a thread not owned by tokio,
@@ -189,8 +235,6 @@ async fn main() -> Result<(), WrappedErr> {
.and_then(NonZeroUsize::new) .and_then(NonZeroUsize::new)
.map_or(PrerenderLimit::All, PrerenderLimit::Limited); .map_or(PrerenderLimit::All, PrerenderLimit::Limited);
let cell_height_px = window_size.height / window_size.rows;
let cell_width_px = window_size.width / window_size.columns;
std::thread::spawn(move || { std::thread::spawn(move || {
renderer::start_rendering( renderer::start_rendering(
&file_path, &file_path,
@@ -236,20 +280,6 @@ async fn main() -> Result<(), WrappedErr> {
})?; })?;
term.skip_diff(true); term.skip_diff(true);
execute!(
term.backend_mut(),
EnterAlternateScreen,
crossterm::cursor::Hide,
crossterm::event::EnableMouseCapture
)
.map_err(|e| {
WrappedErr(
format!(
"Couldn't enter the alternate screen and hide the cursor for proper presentation: {e}"
)
.into()
)
})?;
enable_raw_mode().map_err(|e| { enable_raw_mode().map_err(|e| {
WrappedErr( WrappedErr(
format!("Can't enable raw mode, which is necessary to receive input: {e}").into() format!("Can't enable raw mode, which is necessary to receive input: {e}").into()
@@ -478,6 +508,10 @@ fn parse_color_to_i32(cs: &str) -> Result<i32, csscolorparser::ParseColorError>
} }
fn get_font_size_through_stdio() -> Result<(u16, u16), WrappedErr> { fn get_font_size_through_stdio() -> Result<(u16, u16), WrappedErr> {
// send the command code to get the terminal window size
print!("\x1b[14t");
std::io::stdout().flush().unwrap();
// we need to enable raw mode here since this bit of output won't print a newline; it'll // we need to enable raw mode here since this bit of output won't print a newline; it'll
// just print the info it wants to tell us. So we want to get all characters as they come // just print the info it wants to tell us. So we want to get all characters as they come
enable_raw_mode().map_err(|e| { enable_raw_mode().map_err(|e| {
+17 -19
View File
@@ -2,7 +2,7 @@ use std::{collections::VecDeque, num::NonZeroUsize, thread::sleep, time::Duratio
use flume::{Receiver, SendError, Sender, TryRecvError}; use flume::{Receiver, SendError, Sender, TryRecvError};
use mupdf::{ use mupdf::{
Colorspace, Document, Matrix, Page, Pixmap, Quad, TextPageOptions, text_page::SearchHitResponse Colorspace, Document, Matrix, Page, Pixmap, Quad, TextPageFlags, text_page::SearchHitResponse
}; };
use ratatui::layout::Rect; use ratatui::layout::Rect;
@@ -520,7 +520,7 @@ fn render_single_page_to_ctx(
}) })
} }
#[derive(Clone)] #[derive(Clone, Debug)]
pub struct HighlightRect { pub struct HighlightRect {
pub ul_x: u32, pub ul_x: u32,
pub ul_y: u32, pub ul_y: u32,
@@ -536,15 +536,14 @@ fn search_page(
) -> Result<Vec<Quad>, mupdf::error::Error> { ) -> Result<Vec<Quad>, mupdf::error::Error> {
search_term search_term
.map(|term| { .map(|term| {
page.to_text_page(TextPageOptions::empty()) page.to_text_page(TextPageFlags::empty()).and_then(|page| {
.and_then(|page| { let mut v = Vec::with_capacity(trusted_search_results);
let mut v = Vec::with_capacity(trusted_search_results); page.search_cb(term, &mut v, |v, results| {
page.search_cb(term, &mut v, |v, results| { v.extend(results.iter().cloned());
v.extend(results.iter().cloned()); SearchHitResponse::ContinueSearch
SearchHitResponse::ContinueSearch
})
.map(|_| v)
}) })
.map(|_| v)
})
}) })
.transpose() .transpose()
.map(Option::unwrap_or_default) .map(Option::unwrap_or_default)
@@ -552,15 +551,14 @@ fn search_page(
#[inline] #[inline]
fn count_search_results(page: &Page, search_term: &str) -> Result<usize, mupdf::error::Error> { fn count_search_results(page: &Page, search_term: &str) -> Result<usize, mupdf::error::Error> {
page.to_text_page(TextPageOptions::empty()) page.to_text_page(TextPageFlags::empty()).and_then(|page| {
.and_then(|page| { let mut count = 0;
let mut count = 0; page.search_cb(search_term, &mut count, |count, results| {
page.search_cb(search_term, &mut count, |count, results| { *count += results.len();
*count += results.len(); SearchHitResponse::ContinueSearch
SearchHitResponse::ContinueSearch })?;
})?; Ok(count)
Ok(count) })
})
} }
struct PopOnNext<'a> { struct PopOnNext<'a> {