Compare commits

...

5 Commits

Author SHA1 Message Date
itsjunetime 22bdb7d92b Switch to stable base64 simd library 2025-09-29 16:50:41 -05:00
itsjunetime f4f3b4f539 Actually update package Cargo.toml ugh 2025-09-15 10:05:20 -05:00
itsjunetime a79c534e97 Actually mark release on CHANGELOG 2025-09-07 20:33:43 -05:00
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
8 changed files with 306 additions and 205 deletions
+7
View File
@@ -1,6 +1,13 @@
# Unreleased
- Switched simd base64 crate for one that works on stable (from `vb64` to `base64_simd`)
# v0.4.3
- 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
- (Internal) run CI with `--locked` flag to ensure lockfile is always in-sync
# v0.4.2
Generated
+233 -172
View File
File diff suppressed because it is too large Load Diff
+2 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "tdf-viewer"
version = "0.4.2"
version = "0.4.3"
authors = ["June Welker <junewelker@gmail.com>"]
edition = "2024"
description = "A terminal viewer for PDFs"
@@ -57,8 +57,7 @@ inherits = "release"
lto = "fat"
[features]
default = ["nightly"]
nightly = ["ratatui-image/vb64"]
default = []
tracing = ["tokio/tracing", "dep:console-subscriber"]
epub = ["mupdf/epub"]
cbz = ["mupdf/cbz"]
+4 -2
View File
@@ -16,7 +16,9 @@ Designed to be performant, very responsive, and work well with even very large P
## Installation
1. Get the rust toolchain from [rustup.rs](https://rustup.rs)
2. Run `rustup install nightly && cargo +nightly install --git https://github.com/itsjunetime/tdf.git`
2. Run `cargo install --git https://github.com/itsjunetime/tdf.git`
If you want to use this with `epub`s or `cbz`s, add `--features epub` or `--features cbz` to the command line (or `--features cbz,epub` for both)
## To Build
First, you need to install the system dependencies. This will generally only include `libfontconfig` and `clang`. If you're on linux, these will probably show up in your package manager as something like `libfontconfig1-devel` or `libfontconfig-dev` and just `clang`.
@@ -25,7 +27,7 @@ If it turns out that you're missing one of these, it will fail to compile and te
1. Get the rust toolchain from [rustup.rs](https://rustup.rs)
2. Clone the repo and `cd` into it
3. Run `cargo +nightly build --release`
3. Run `cargo build --release`
The binary should then be found at `./target/release/tdf`.
+1 -1
Submodule ratatui updated: 47c200fb7f...6a0b8ddf76
+58 -24
View File
@@ -1,9 +1,11 @@
use core::error::Error;
use core::{
error::Error,
num::{NonZeroU32, NonZeroUsize}
};
use std::{
borrow::Cow,
ffi::OsString,
io::{BufReader, Read, Stdout, stdout},
num::{NonZeroU32, NonZeroUsize},
io::{BufReader, Read, Stdout, Write, stdout},
path::PathBuf
};
@@ -54,8 +56,27 @@ impl std::fmt::Debug for WrappedErr {
impl std::error::Error for WrappedErr {}
fn reset_term() {
_ = execute!(
std::io::stdout(),
LeaveAlternateScreen,
crossterm::cursor::Show,
crossterm::event::DisableMouseCapture
)
}
#[tokio::main]
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")]
console_subscriber::init();
@@ -172,14 +193,39 @@ async fn main() -> Result<(), WrappedErr> {
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,
// it messes up something with user input. Input never makes it to the crossterm thing
let picker = Picker::from_query_stdio()
.map_err(|e| WrappedErr(match e {
ratatui_image::errors::Errors::NoFontSize =>
"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 => format!("Couldn't get the necessary information to set up images: {e}").into()
}))?;
.or_else(|e| match e {
ratatui_image::errors::Errors::NoFontSize if
window_size.width != 0
&& 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
// 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)
.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 || {
renderer::start_rendering(
&file_path,
@@ -236,20 +280,6 @@ async fn main() -> Result<(), WrappedErr> {
})?;
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| {
WrappedErr(
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> {
// 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
// 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| {
-2
View File
@@ -427,8 +427,6 @@ impl Tui {
}
}
log::debug!("tui got page {page_num} ready with img {img:#?}");
// We always just set this here because we handle reloading in the `set_n_pages` function.
// If the document was reloaded, then It'll have the `set_n_pages` called to set the new
// number of pages, so the vec will already be cleared