Skip to content

Commit 8dedf62

Browse files
committed
Actually query terminals and fix terminals if we fail initialization
1 parent 6904890 commit 8dedf62

2 files changed

Lines changed: 58 additions & 26 deletions

File tree

‎src/main.rs‎

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
use core::error::Error;
1+
use core::{
2+
error::Error,
3+
num::{NonZeroU32, NonZeroUsize}
4+
};
25
use std::{
36
borrow::Cow,
47
ffi::OsString,
5-
io::{BufReader, Read, Stdout, stdout},
6-
num::{NonZeroU32, NonZeroUsize},
8+
io::{BufReader, Read, Stdout, Write, stdout},
79
path::PathBuf
810
};
911

@@ -54,8 +56,27 @@ impl std::fmt::Debug for WrappedErr {
5456

5557
impl std::error::Error for WrappedErr {}
5658

59+
fn reset_term() {
60+
_ = execute!(
61+
std::io::stdout(),
62+
LeaveAlternateScreen,
63+
crossterm::cursor::Show,
64+
crossterm::event::DisableMouseCapture
65+
)
66+
}
67+
5768
#[tokio::main]
5869
async fn main() -> Result<(), WrappedErr> {
70+
inner_main().await.inspect_err(|_| reset_term())
71+
}
72+
73+
async fn inner_main() -> Result<(), WrappedErr> {
74+
let hook = std::panic::take_hook();
75+
std::panic::set_hook(Box::new(move |info| {
76+
reset_term();
77+
hook(info);
78+
}));
79+
5980
#[cfg(feature = "tracing")]
6081
console_subscriber::init();
6182

@@ -172,14 +193,39 @@ async fn main() -> Result<(), WrappedErr> {
172193
window_size.height = h;
173194
}
174195

196+
let cell_height_px = window_size.height / window_size.rows;
197+
let cell_width_px = window_size.width / window_size.columns;
198+
199+
execute!(
200+
std::io::stdout(),
201+
EnterAlternateScreen,
202+
crossterm::cursor::Hide,
203+
crossterm::event::EnableMouseCapture
204+
)
205+
.map_err(|e| {
206+
WrappedErr(
207+
format!(
208+
"Couldn't enter the alternate screen and hide the cursor for proper presentation: {e}"
209+
)
210+
.into()
211+
)
212+
})?;
213+
175214
// We need to create `picker` on this thread because if we create it on the `renderer` thread,
176215
// it messes up something with user input. Input never makes it to the crossterm thing
177216
let picker = Picker::from_query_stdio()
178-
.map_err(|e| WrappedErr(match e {
179-
ratatui_image::errors::Errors::NoFontSize =>
180-
"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(),
181-
e => format!("Couldn't get the necessary information to set up images: {e}").into()
182-
}))?;
217+
.or_else(|e| match e {
218+
ratatui_image::errors::Errors::NoFontSize if
219+
window_size.width != 0
220+
&& window_size.height != 0
221+
&& window_size.columns != 0
222+
&& window_size.rows != 0
223+
=> Ok(Picker::from_fontsize((cell_width_px, cell_height_px))),
224+
ratatui_image::errors::Errors::NoFontSize => Err(WrappedErr(
225+
"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()
226+
)),
227+
e => Err(WrappedErr(format!("Couldn't get the necessary information to set up images: {e}").into()))
228+
})?;
183229

184230
// then we want to spawn off the rendering task
185231
// 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> {
189235
.and_then(NonZeroUsize::new)
190236
.map_or(PrerenderLimit::All, PrerenderLimit::Limited);
191237

192-
let cell_height_px = window_size.height / window_size.rows;
193-
let cell_width_px = window_size.width / window_size.columns;
194238
std::thread::spawn(move || {
195239
renderer::start_rendering(
196240
&file_path,
@@ -236,20 +280,6 @@ async fn main() -> Result<(), WrappedErr> {
236280
})?;
237281
term.skip_diff(true);
238282

239-
execute!(
240-
term.backend_mut(),
241-
EnterAlternateScreen,
242-
crossterm::cursor::Hide,
243-
crossterm::event::EnableMouseCapture
244-
)
245-
.map_err(|e| {
246-
WrappedErr(
247-
format!(
248-
"Couldn't enter the alternate screen and hide the cursor for proper presentation: {e}"
249-
)
250-
.into()
251-
)
252-
})?;
253283
enable_raw_mode().map_err(|e| {
254284
WrappedErr(
255285
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>
478508
}
479509

480510
fn get_font_size_through_stdio() -> Result<(u16, u16), WrappedErr> {
511+
// send the command code to get the terminal window size
512+
print!("\x1b[14t");
513+
std::io::stdout().flush().unwrap();
514+
481515
// we need to enable raw mode here since this bit of output won't print a newline; it'll
482516
// just print the info it wants to tell us. So we want to get all characters as they come
483517
enable_raw_mode().map_err(|e| {

‎src/tui.rs‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -427,8 +427,6 @@ impl Tui {
427427
}
428428
}
429429

430-
log::debug!("tui got page {page_num} ready with img {img:#?}");
431-
432430
// We always just set this here because we handle reloading in the `set_n_pages` function.
433431
// If the document was reloaded, then It'll have the `set_n_pages` called to set the new
434432
// number of pages, so the vec will already be cleared

0 commit comments

Comments
 (0)