diff --git a/CHANGELOG.md b/CHANGELOG.md index e2e9386..ddb717c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +0.1.1 +----- + +- Fix scroll limitation in source view #41 + 0.1.0 ----- diff --git a/src/app.rs b/src/app.rs index 7a1be49..2293d76 100644 --- a/src/app.rs +++ b/src/app.rs @@ -637,8 +637,9 @@ impl App { context, }); } - self.history.push(entry); self.session_view.reset(); + self.session_view.scroll_to_line(entry.source(0).line_no); + self.history.push(entry); Ok(()) } diff --git a/src/view/session.rs b/src/view/session.rs index bd293b7..099bf7a 100644 --- a/src/view/session.rs +++ b/src/view/session.rs @@ -1,3 +1,5 @@ +use std::cell::Cell; + use super::context::ContextComponent; use super::source::SourceComponent; use super::stack::StackComponent; @@ -184,6 +186,7 @@ fn build_pane_widget(frame: &mut Frame, app: &App, pane: &Pane, area: Rect, inde }; } +#[derive(Default)] pub struct SearchState { pub show: bool, pub search: String, @@ -196,9 +199,11 @@ impl SearchState { } } +#[derive(Default)] pub struct SessionViewState { pub full_screen: bool, pub source_scroll: (u16, u16), + pub source_area: Cell, pub context_scroll: (u16, u16), pub context_filter: SearchState, pub stack_scroll: (u16, u16), @@ -207,17 +212,12 @@ pub struct SessionViewState { pub current_pane: usize, } -impl Default for SessionViewState { - fn default() -> Self { - Self::new() - } -} - impl SessionViewState { pub fn new() -> Self { Self { full_screen: false, source_scroll: (0, 0), + source_area: Cell::new(Rect::new(0, 0, 0, 0)), context_scroll: (0, 0), context_filter: SearchState { show: false, @@ -271,10 +271,56 @@ impl SessionViewState { pub(crate) fn stack_depth(&self) -> u16 { self.stack_scroll.0 } + + pub(crate) fn scroll_to_line(&mut self, line_no: u32) -> () { + let area = self.source_area.get(); + let mid_point = (area.height as u32).div_ceil(2); + let offset = if line_no > mid_point { + line_no - mid_point + } else { + 0 + }; + self.source_scroll.0 = offset as u16; + } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Default)] pub enum SessionViewMode { + #[default] Current, History, } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + pub fn scroll_to_line() -> () { + let mut view = SessionViewState::default(); + view.source_area = Cell::new(Rect{ + x: 0, + y: 0, + width: 0, + height: 10, + }); + view.scroll_to_line(0); + + assert_eq!(0, view.source_scroll.0); + + view.scroll_to_line(5); + assert_eq!(0, view.source_scroll.0); + + view.scroll_to_line(6); + assert_eq!(1, view.source_scroll.0); + + view.scroll_to_line(10); + assert_eq!(5, view.source_scroll.0); + + view.scroll_to_line(20); + assert_eq!(15, view.source_scroll.0); + + view.scroll_to_line(100); + assert_eq!(95, view.source_scroll.0); + } +} diff --git a/src/view/source.rs b/src/view/source.rs index e504adb..42d491d 100644 --- a/src/view/source.rs +++ b/src/view/source.rs @@ -34,6 +34,11 @@ impl View for SourceComponent { .constraints(constraints) .split(area); + // make the app aware of the source area so we can + // center the source code on the releant line when + // setpping into code + app.session_view.source_area.set(rows[0]); + let mut annotations = vec![]; let mut lines: Vec = Vec::new(); @@ -86,23 +91,16 @@ impl View for SourceComponent { } } - let scroll: u16 = if stack.source.line_no as u16 > area.height { - let center = (stack.source.line_no as u16) - .saturating_sub(area.height.div_ceil(2)) as i16; - center - .saturating_add(app.session_view.source_scroll.0 as i16) - .max(0) as u16 - } else { - app.session_view.source_scroll.0 - }; - - frame.render_widget(Paragraph::new(lines.clone()).scroll((scroll, app.session_view.source_scroll.1)), rows[0]); + frame.render_widget( + Paragraph::new(lines.clone()).scroll(app.session_view.source_scroll), + rows[0], + ); for (line_no, line_length, line) in annotations { let x_offset = rows[0].x + (line_length as u16).saturating_sub(app.session_view.source_scroll.1); let area = Rect { x: x_offset, - y: (line_no as u32).saturating_sub(scroll as u32) as u16 + 1, + y: (line_no as u32).saturating_sub(app.session_view.source_scroll.0 as u32) as u16 + 1, width: rows[0].width.saturating_sub(x_offset), height: 1, };