Something went wrong. Try again.
Codex, Claude, and local AI agents on the Commodore 64 Ultimate.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111pub const VIEW_ROWS: usize = 21;
pub struct ScrollbackView { start: usize, maximum_start: usize, total: usize,}
impl ScrollbackView { pub const fn new(total: usize) -> Self { let maximum_start = total.saturating_sub(VIEW_ROWS); Self { start: maximum_start, maximum_start, total, } }
pub const fn start(&self) -> usize { self.start }
pub const fn total(&self) -> usize { self.total }
pub fn end(&self) -> usize { (self.start + VIEW_ROWS).min(self.total) }
pub fn older_line(&mut self) -> bool { if self.start == 0 { return false; } self.start -= 1; true }
pub fn newer_line(&mut self) -> bool { if self.start == self.maximum_start { return false; } self.start += 1; true }
pub fn older_page(&mut self) -> bool { let next = self.start.saturating_sub(VIEW_ROWS); if next == self.start { return false; } self.start = next; true }
pub fn newer_page(&mut self) -> bool { let next = (self.start + VIEW_ROWS).min(self.maximum_start); if next == self.start { return false; } self.start = next; true }}
#[cfg(test)]mod tests { use super::{ScrollbackView, VIEW_ROWS};
#[test] fn starts_at_latest_page() { let view = ScrollbackView::new(40); assert_eq!(view.start(), 40 - VIEW_ROWS); assert_eq!(view.end(), 40); }
#[test] fn clamps_line_navigation() { let mut view = ScrollbackView::new(VIEW_ROWS + 2); assert!(view.older_line()); assert!(view.older_line()); assert!(!view.older_line()); assert!(view.newer_line()); assert!(view.newer_line()); assert!(!view.newer_line()); }
#[test] fn pages_include_partial_oldest_page() { let mut view = ScrollbackView::new(VIEW_ROWS * 2 + 10); assert_eq!(view.start(), VIEW_ROWS + 10); assert!(view.older_page()); assert_eq!(view.start(), 10); assert!(view.older_page()); assert_eq!(view.start(), 0); assert!(view.newer_page()); assert_eq!(view.start(), VIEW_ROWS); assert!(view.newer_page()); assert_eq!(view.start(), VIEW_ROWS + 10); }
#[test] fn short_transcript_does_not_scroll() { let mut view = ScrollbackView::new(3); assert_eq!(view.start(), 0); assert_eq!(view.end(), 3); assert!(!view.older_line()); assert!(!view.newer_page()); }}