aboutsummaryrefslogtreecommitdiffstats
path: root/src/view.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/view.rs')
-rw-r--r--src/view.rs115
1 files changed, 33 insertions, 82 deletions
diff --git a/src/view.rs b/src/view.rs
index 4a5cb73..fa50532 100644
--- a/src/view.rs
+++ b/src/view.rs
@@ -5,10 +5,7 @@ use crossterm::{
},
style::Attribute,
};
-use std::{
- cmp::{min, Ordering},
- iter,
-};
+use std::cmp::{min, Ordering};
use unicode_width::UnicodeWidthChar;
use crate::{Bk, Direction, SearchArgs};
@@ -199,7 +196,7 @@ impl Page {
}
}
fn scroll_down(&self, bk: &mut Bk, n: usize) {
- if bk.line + bk.rows < bk.chap().lines.len() {
+ if bk.line + bk.rows < bk.chapters[bk.chapter].lines.len() {
bk.line += n;
} else {
self.next_chapter(bk);
@@ -210,11 +207,11 @@ impl Page {
bk.line = bk.line.saturating_sub(n);
} else if bk.chapter > 0 {
bk.chapter -= 1;
- bk.line = bk.chap().lines.len().saturating_sub(bk.rows);
+ bk.line = bk.chapters[bk.chapter].lines.len().saturating_sub(bk.rows);
}
}
fn click(&self, bk: &mut Bk, e: MouseEvent) {
- let c = bk.chap();
+ let c = &bk.chapters[bk.chapter];
let line = bk.line + e.row as usize;
if e.column < bk.pad() || line >= c.lines.len() {
@@ -251,9 +248,9 @@ impl Page {
if let Ok(i) = r {
let url = &c.links[i].2;
- let &(chapter, byte) = bk.links.get(url).unwrap();
- let line = super::get_line(&bk.chapters[chapter].lines, byte);
- bk.jump((chapter, line));
+ let &(c, byte) = bk.links.get(url).unwrap();
+ bk.mark('\'');
+ bk.jump_byte(c, byte);
}
}
fn start_search(&self, bk: &mut Bk, dir: Direction) {
@@ -287,28 +284,20 @@ impl View for Page {
Char('?') => self.start_search(bk, Direction::Prev),
Char('/') => self.start_search(bk, Direction::Next),
Char('N') => {
- Search::search(
- &Search,
- bk,
- SearchArgs {
- dir: Direction::Prev,
- skip: true,
- },
- );
+ bk.search(SearchArgs {
+ dir: Direction::Prev,
+ skip: true,
+ });
}
Char('n') => {
- Search::search(
- &Search,
- bk,
- SearchArgs {
- dir: Direction::Next,
- skip: true,
- },
- );
+ bk.search(SearchArgs {
+ dir: Direction::Next,
+ skip: true,
+ });
}
End | Char('G') => {
bk.mark('\'');
- bk.line = bk.chap().lines.len().saturating_sub(bk.rows);
+ bk.line = bk.chapters[bk.chapter].lines.len().saturating_sub(bk.rows);
}
Home | Char('g') => {
bk.mark('\'');
@@ -329,14 +318,24 @@ impl View for Page {
}
fn on_resize(&self, bk: &mut Bk) {
// lazy
- bk.line = min(bk.line, bk.chap().lines.len() - 1);
+ bk.line = min(bk.line, bk.chapters[bk.chapter].lines.len() - 1);
}
fn render(&self, bk: &Bk) -> Vec<String> {
- let c = bk.chap();
+ let c = &bk.chapters[bk.chapter];
let last_line = min(bk.line + bk.rows, c.lines.len());
let text_start = c.lines[bk.line].0;
let text_end = c.lines[last_line - 1].1;
+ let mut search = Vec::new();
+ if !bk.query.is_empty() {
+ let len = bk.query.len();
+ for (pos, _) in c.text[text_start..text_end].match_indices(&bk.query) {
+ search.push((text_start + pos, Attribute::Reverse));
+ search.push((text_start + pos + len, Attribute::NoReverse));
+ }
+ }
+ let mut search = search.into_iter().peekable();
+
let mut base = {
let start = match c.attrs.binary_search_by_key(&text_start, |&x| x.0) {
Ok(n) => n,
@@ -358,16 +357,6 @@ impl View for Page {
head.into_iter().chain(tail).peekable()
};
- let mut search = Vec::new();
- if !bk.query.is_empty() {
- let len = bk.query.len();
- for (pos, _) in c.text[text_start..text_end].match_indices(&bk.query) {
- search.push((text_start + pos, Attribute::Reverse));
- search.push((text_start + pos + len, Attribute::NoReverse));
- }
- }
- let mut search = search.into_iter().peekable();
-
let mut attrs = Vec::new();
loop {
match (search.peek(), base.peek()) {
@@ -410,41 +399,6 @@ impl View for Page {
}
pub struct Search;
-impl Search {
- fn search(&self, bk: &mut Bk, args: SearchArgs) -> bool {
- let (start, end) = bk.chap().lines[bk.line];
- match args.dir {
- Direction::Next => {
- let byte = if args.skip { end } else { start };
- let head = (bk.chapter, byte);
- let tail = (bk.chapter + 1..bk.chapters.len() - 1).map(|n| (n, 0));
- for (c, byte) in iter::once(head).chain(tail) {
- if let Some(index) = bk.chapters[c].text[byte..].find(&bk.query) {
- bk.line = super::get_line(&bk.chapters[c].lines, index + byte);
- bk.chapter = c;
- return true;
- }
- }
- false
- }
- Direction::Prev => {
- let byte = if args.skip { start } else { end };
- let head = (bk.chapter, byte);
- let tail = (0..bk.chapter)
- .rev()
- .map(|c| (c, bk.chapters[c].text.len()));
- for (c, byte) in iter::once(head).chain(tail) {
- if let Some(index) = bk.chapters[c].text[..byte].rfind(&bk.query) {
- bk.line = super::get_line(&bk.chapters[c].lines, index);
- bk.chapter = c;
- return true;
- }
- }
- false
- }
- }
- }
-}
impl View for Search {
fn on_key(&self, bk: &mut Bk, kc: KeyCode) {
match kc {
@@ -459,13 +413,10 @@ impl View for Search {
Backspace => {
bk.query.pop();
bk.jump_reset();
- self.search(
- bk,
- SearchArgs {
- dir: bk.dir.clone(),
- skip: false,
- },
- );
+ bk.search(SearchArgs {
+ dir: bk.dir.clone(),
+ skip: false,
+ });
}
Char(c) => {
bk.query.push(c);
@@ -473,7 +424,7 @@ impl View for Search {
dir: bk.dir.clone(),
skip: false,
};
- if !self.search(bk, args) {
+ if !bk.search(args) {
bk.jump_reset();
}
}