diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 071796e..3994f65 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -26,12 +26,12 @@ jobs: - name: Install build dependencies run: | sudo apt-get update - sudo apt-get install -y cmake libjpeg-dev libfontconfig1-dev libopenjp2-7-dev libglib2.0-dev libnss3-dev + sudo apt-get install -y cmake libjpeg-dev libfontconfig1-dev libopenjp2-7-dev libopenjpip7 libopenjp2-7 libglib2.0-dev libnss3-dev libunwind-dev libgoogle-perftools-dev libboost-dev - name: Build newer poppler run: | - wget https://poppler.freedesktop.org/poppler-23.12.0.tar.xz - tar xf poppler-23.12.0.tar.xz - cd poppler-23.12.0 + wget https://poppler.freedesktop.org/poppler-23.10.0.tar.xz + tar xf poppler-23.10.0.tar.xz + cd poppler-23.10.0 mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_C_COMPILER_LAUNCHER=sccache \ @@ -40,7 +40,6 @@ jobs: -DENABLE_GPGME=OFF \ -DENABLE_QT5=OFF \ -DENABLE_QT6=OFF \ - -DENABLE_BOOST=OFF \ -DENABLE_SPLASH=OFF \ -DENABLE_LIBCURL=OFF make -j$(nproc) @@ -52,6 +51,6 @@ jobs: - name: Check fmt run: cargo fmt -- --check - name: Run tests - run: cargo test + run: cargo test --benches -- adobe_example - name: Build run: cargo build diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a3c8a0..f6e8492 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ - Small internal changes to accomodate a few more clippy lints - Update `ratatui` and `ratatui-image` git dependencies to latest upstream - Move `ratatui-image/vb64` support under `nightly` feature, enabled by default +- Fixed a bug where jumping to a page out of range could result in weird `esc` key behavior +- Added CI # v0.1.0 diff --git a/Cargo.lock b/Cargo.lock index 5728e47..93ce78f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -149,9 +149,9 @@ dependencies = [ [[package]] name = "axum" -version = "0.7.7" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" dependencies = [ "async-trait", "axum-core", @@ -253,9 +253,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" [[package]] name = "byteorder" @@ -321,9 +321,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aeb932158bd710538c73702db6945cb68a8fb08c519e6e12706b94263b36db8" +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" dependencies = [ "jobserver", "libc", @@ -342,9 +342,9 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0890061c4d3223e7267f3bad2ec40b997d64faac1c2815a4a9d95018e2b9e9c" +checksum = "c360837f8f19e2e4468275138f1c0dec1647d1e17bb7c0215fe3cd7530e93c25" dependencies = [ "smallvec", "target-lexicon", @@ -385,18 +385,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.20" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.20" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" dependencies = [ "anstyle", "clap_lex", @@ -404,9 +404,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" [[package]] name = "compact_str" @@ -681,9 +681,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.34" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "miniz_oxide", @@ -910,9 +910,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" dependencies = [ "atomic-waker", "bytes", @@ -1039,9 +1039,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" +checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" dependencies = [ "bytes", "futures-channel", @@ -1294,9 +1294,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.162" +version = "0.2.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" +checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" [[package]] name = "libfuzzer-sys" @@ -2009,9 +2009,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" -version = "0.38.40" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags 2.6.0", "errno", @@ -2069,9 +2069,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -2258,7 +2258,7 @@ version = "7.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66d23aaf9f331227789a99e8de4c91bf46703add012bdfd45fdecdfb2975a005" dependencies = [ - "cfg-expr 0.17.0", + "cfg-expr 0.17.1", "heck", "pkg-config", "toml", diff --git a/src/main.rs b/src/main.rs index b5ccc11..5db3133 100644 --- a/src/main.rs +++ b/src/main.rs @@ -123,7 +123,7 @@ async fn main() -> Result<(), Box> { // 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()?; + let picker = Picker::from_query_stdio()?; // 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, diff --git a/src/tui.rs b/src/tui.rs index e742ec4..a508ab0 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -1,4 +1,4 @@ -use std::{io::stdout, num::NonZeroUsize, rc::Rc}; +use std::{borrow::Cow, io::stdout, num::NonZeroUsize, rc::Rc}; use crossterm::{ event::{Event, KeyCode, MouseEventKind}, @@ -152,18 +152,18 @@ impl Tui { let rendered_span = Span::styled(&rendered_str, Style::new().fg(Color::Cyan)); frame.render_widget(rendered_span, bottom_layout[1]); - let (msg_str, color) = match self.bottom_msg { + let (msg_str, color): (Cow<'_, str>, _) = match self.bottom_msg { BottomMessage::Help => ( - "/: Search, g: Go To Page, n: Next Search Result, N: Previous Search Result" - .to_string(), + "/: Search, g: Go To Page, n: Next Search Result, N: Previous Search Result".into(), Color::Blue ), - BottomMessage::Error(ref e) => (format!("Couldn't render a page: {e}"), Color::Red), + BottomMessage::Error(ref e) => (e.as_str().into(), Color::Red), BottomMessage::Input(ref input_state) => ( match input_state { InputCommand::GoToPage(page) => format!("Go to: {page}"), InputCommand::Search(s) => format!("Search: {s}") - }, + } + .into(), Color::Blue ), BottomMessage::SearchResults(ref term) => { @@ -181,7 +181,8 @@ impl Tui { format!( "Results for '{term}': {num_found} (searched: {}%)", num_searched / self.rendered.len() - ), + ) + .into(), Color::Blue ) } @@ -370,12 +371,16 @@ impl Tui { match key.code { KeyCode::Char(c) => { // TODO: refactor back to `if let` arm guards when those are stabilized - if let BottomMessage::Input(InputCommand::Search(ref mut term)) = self.bottom_msg { + if let BottomMessage::Input(InputCommand::Search(ref mut term)) = + self.bottom_msg + { term.push(c); return Some(InputAction::Redraw); } - if let BottomMessage::Input(InputCommand::GoToPage(ref mut page)) = self.bottom_msg { + if let BottomMessage::Input(InputCommand::GoToPage(ref mut page)) = + self.bottom_msg + { return c.to_digit(10).map(|input_num| { *page = (*page * 10) + input_num as usize; InputAction::Redraw @@ -389,13 +394,15 @@ impl Tui { 'k' => self.change_page(PageChange::Prev, ChangeAmount::WholeScreen), 'q' => Some(InputAction::QuitApp), 'g' => { - self.set_bottom_msg(Some(BottomMessage::Input(InputCommand::GoToPage(0)))); + self.set_bottom_msg(Some(BottomMessage::Input( + InputCommand::GoToPage(0) + ))); Some(InputAction::Redraw) } '/' => { - self.set_bottom_msg(Some(BottomMessage::Input(InputCommand::Search( - String::new() - )))); + self.set_bottom_msg(Some(BottomMessage::Input( + InputCommand::Search(String::new()) + ))); Some(InputAction::Redraw) } 'n' if self.page < self.rendered.len() - 1 => { @@ -424,27 +431,29 @@ impl Tui { }); jump_to_page(&mut self.page, &mut self.last_render.rect, prev_page) - }, + } _ => None } - }, + } KeyCode::Backspace => { - if let BottomMessage::Input(InputCommand::Search(ref mut term)) = self.bottom_msg { + if let BottomMessage::Input(InputCommand::Search(ref mut term)) = + self.bottom_msg + { term.pop(); return Some(InputAction::Redraw); } None - }, + } KeyCode::Right => self.change_page(PageChange::Next, ChangeAmount::Single), KeyCode::Down => self.change_page(PageChange::Next, ChangeAmount::WholeScreen), KeyCode::Left => self.change_page(PageChange::Prev, ChangeAmount::Single), KeyCode::Up => self.change_page(PageChange::Prev, ChangeAmount::WholeScreen), KeyCode::Esc => match self.bottom_msg { - BottomMessage::Input(_) => { + BottomMessage::Help => Some(InputAction::QuitApp), + _ => { self.set_bottom_msg(None); Some(InputAction::Redraw) } - _ => Some(InputAction::QuitApp) }, KeyCode::Enter => { let BottomMessage::Input(_) = self.bottom_msg else { @@ -463,10 +472,17 @@ impl Tui { // Only forward the command if it's within range InputCommand::GoToPage(page) => { let page = *page; - (page < self.rendered.len()).then(|| { + let rendered_len = self.rendered.len(); + + if page < rendered_len { self.set_page(page); - InputAction::JumpingToPage(page) - }) + Some(InputAction::JumpingToPage(page)) + } else { + self.set_bottom_msg(Some(BottomMessage::Error( + format!("Cannot jump to page {page}; there are only {rendered_len} pages in the document") + ))); + Some(InputAction::Redraw) + } } InputCommand::Search(term) => { let term = term.clone();