diff --git a/.gdbinit b/.gdbinit index dbc6aca4..acbd163b 100644 --- a/.gdbinit +++ b/.gdbinit @@ -1,2 +1,4 @@ break rust_panic break core::option::expect_failed::h4927e1fef06c4878 +break core::panicking::panic +break libcore/panicking.rs:58 diff --git a/ui/src/cells.rs b/ui/src/cells.rs index ce3bd5cd..172c690b 100644 --- a/ui/src/cells.rs +++ b/ui/src/cells.rs @@ -4,6 +4,7 @@ */ use std::ops::{Index, IndexMut, Deref, DerefMut}; use std::convert::From; +use std::fmt; use super::position::*; use termion::color::AnsiValue; @@ -175,12 +176,28 @@ impl<'a> From<&'a String> for CellBuffer { } } +impl fmt::Display for CellBuffer { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + '_y: for y in 0..self.rows { + '_x: for x in 0..self.cols { + let c: &char = &self[(x,y)].ch(); + write!(f, "{}", *c); + if *c == '\n' { + continue '_y; + } + } + } + Ok(()) + } +} + /// A single point on a terminal display. /// /// A `Cell` contains a character and style. #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct Cell { ch: char, + fg: Color, bg: Color, attrs: Attr, diff --git a/ui/src/components/mail/view.rs b/ui/src/components/mail/view.rs index 19db0c49..d9e969c5 100644 --- a/ui/src/components/mail/view.rs +++ b/ui/src/components/mail/view.rs @@ -139,12 +139,18 @@ impl Component for MailView { let mut buf = CellBuffer::from(&text); match self.mode { ViewMode::Url => { - let c_slice: &mut [Cell] = &mut buf; - for (lidx, l) in finder.links(&envelope.body().text()).enumerate() { - let i = l.start()+ (lidx * 3); - for c in c_slice[i..i+3].iter_mut() { - c.set_fg(Color::Byte(226)); + // URL indexes must be colored (ugh..) + let (cols, _) = buf.size(); + let lines: Vec<&str> = text.split('\n').collect(); + let mut shift = 0; + for (ridx, r) in lines.iter().enumerate() { + for (lidx, l) in finder.links(&r).enumerate() { + buf[(l.start() + shift - 1, 0)].set_fg(Color::Byte(226)); + buf[(l.start() + shift - 2, 0)].set_fg(Color::Byte(226)); + buf[(l.start() + shift - 3, 0)].set_fg(Color::Byte(226)); } + // Each Cell represents one char so next line will be: + shift += r.chars().count()+1; } }, _ => {}, @@ -153,7 +159,7 @@ impl Component for MailView { }; let cursor_pos = self.pager.as_mut().map(|p| p.cursor_pos()); // TODO: pass string instead of envelope - self.pager = Some(Pager::from_buf(buf)); + self.pager = Some(Pager::from_buf(buf, cursor_pos)); self.dirty = false; } self.pager.as_mut().map(|p| p.draw(grid, (set_y(upper_left, y + 1),bottom_right), context)); @@ -163,7 +169,7 @@ impl Component for MailView { match event.event_type { UIEventType::Input(Key::Char(c)) if c >= '0' && c <= '9' => { //TODO:this should be an Action match self.mode { - ViewMode::Url => { self.cmd_buf.push(c); + ViewMode::Url => { self.cmd_buf.push(c); eprintln!("buf is {}", self.cmd_buf); return; }, _ => {}, diff --git a/ui/src/components/mod.rs b/ui/src/components/mod.rs index 4c9411e8..56eddbf5 100644 --- a/ui/src/components/mod.rs +++ b/ui/src/components/mod.rs @@ -99,23 +99,23 @@ pub fn copy_area_with_break(grid_dest: &mut CellBuffer, grid_src: &CellBuffer, d if grid_src[(src_x, src_y)].ch() == '\n' { src_y += 1; src_x = 0; - if src_y == get_y(bottom_right!(src)) { + if src_y >= get_y(bottom_right!(src)) { break 'y_; } continue 'y_; } grid_dest[(x,y)] = grid_src[(src_x, src_y)]; - if src_x == get_x(bottom_right!(src)) { + src_x += 1; + if src_x >= get_x(bottom_right!(src)) { src_y += 1; src_x = 0; - if src_y == get_y(bottom_right!(src)) { + if src_y >= get_y(bottom_right!(src)) { //clear_area(grid_dest, ((get_x(upper_left!(dest)), y), bottom_right!(dest))); break 'y_; } break 'x_; } - src_x += 1; } } } @@ -133,13 +133,13 @@ pub fn copy_area(grid_dest: &mut CellBuffer, grid_src: &CellBuffer, dest: Area, for y in get_y(upper_left!(dest))..=get_y(bottom_right!(dest)) { 'for_x: for x in get_x(upper_left!(dest))..=get_x(bottom_right!(dest)) { grid_dest[(x,y)] = grid_src[(src_x, src_y)]; - if src_x == get_x(bottom_right!(src)) { + if src_x >= get_x(bottom_right!(src)) { break 'for_x; } src_x += 1; } src_x = get_x(upper_left!(src)); - if src_y == get_y(bottom_right!(src)) { + if src_y >= get_y(bottom_right!(src)) { clear_area(grid_dest, ((get_x(upper_left!(dest)), y), bottom_right!(dest))); break; } diff --git a/ui/src/components/utilities.rs b/ui/src/components/utilities.rs index c1cae74b..d448d8e1 100644 --- a/ui/src/components/utilities.rs +++ b/ui/src/components/utilities.rs @@ -178,21 +178,21 @@ impl Pager { content: content, } } - pub fn from_str(s: &str) -> Self { + pub fn from_str(s: &str, cursor_pos: Option) -> Self { let lines: Vec<&str> = s.trim().split('\n').collect(); let height = lines.len(); let width = lines.iter().map(|l| l.len()).max().unwrap_or(0); let mut content = CellBuffer::new(width, height, Cell::with_char(' ')); Pager::print_string(&mut content, s); Pager { - cursor_pos: 0, + cursor_pos: cursor_pos.unwrap_or(0), height: height, width: width, dirty: true, content: content, } } - pub fn from_buf(buf: CellBuffer) -> Self { + pub fn from_buf(buf: CellBuffer, cursor_pos: Option) -> Self { let lines: Vec<&[Cell]> = buf.split(|cell| cell.ch() == '\n').collect(); let height = lines.len(); let width = lines.iter().map(|l| l.len()).max().unwrap_or(0) + 1; @@ -210,7 +210,7 @@ impl Pager { } } Pager { - cursor_pos: 0, + cursor_pos: cursor_pos.unwrap_or(0), height: height, width: width, dirty: true,