Fix viewer scrolling so current line stays visible
This commit is contained in:
parent
9996616d9b
commit
525acb9eb4
2 changed files with 21 additions and 12 deletions
|
|
@ -46,8 +46,13 @@ impl LogViewer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn visible_lines(&self) -> Vec<&String> {
|
/// Returns visible lines together with their original buffer index.
|
||||||
self.buffer.iter().filter(|l| self.search.matches(l)).collect()
|
pub fn visible_lines(&self) -> Vec<(usize, &String)> {
|
||||||
|
self.buffer
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|(_, l)| self.search.matches(l))
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_line(&mut self, line: String) {
|
pub fn push_line(&mut self, line: String) {
|
||||||
|
|
|
||||||
24
src/ui.rs
24
src/ui.rs
|
|
@ -109,19 +109,22 @@ fn draw_log_buffer(f: &mut Frame, viewer: &LogViewer, area: ratatui::layout::Rec
|
||||||
let title = format!(" {} — {} ", viewer.source, if viewer.live { "LIVE" } else { "PAUSED" });
|
let title = format!(" {} — {} ", viewer.source, if viewer.live { "LIVE" } else { "PAUSED" });
|
||||||
let visible = viewer.visible_lines();
|
let visible = viewer.visible_lines();
|
||||||
|
|
||||||
|
// Compute the viewport offset so the current line stays in view.
|
||||||
|
let current_visible_idx = visible
|
||||||
|
.iter()
|
||||||
|
.position(|(i, _)| *i == viewer.scroll)
|
||||||
|
.unwrap_or(visible.len().saturating_sub(1));
|
||||||
|
let scroll_offset = current_visible_idx
|
||||||
|
.saturating_sub(area.height as usize / 2)
|
||||||
|
.min(visible.len().saturating_sub(1));
|
||||||
|
|
||||||
let lines: Vec<Line> = visible
|
let lines: Vec<Line> = visible
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.map(|(global_idx, line)| {
|
||||||
.map(|(i, line)| {
|
let is_current = *global_idx == viewer.scroll;
|
||||||
let global_idx = viewer
|
|
||||||
.buffer
|
|
||||||
.iter()
|
|
||||||
.position(|l| std::ptr::eq(l.as_ptr(), line.as_ptr()))
|
|
||||||
.unwrap_or(i);
|
|
||||||
let is_current = global_idx == viewer.scroll;
|
|
||||||
let is_match = viewer
|
let is_match = viewer
|
||||||
.search_cursor
|
.search_cursor
|
||||||
.map(|c| c == global_idx)
|
.map(|c| c == *global_idx)
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
|
|
||||||
let mut style = Style::default();
|
let mut style = Style::default();
|
||||||
|
|
@ -139,7 +142,8 @@ fn draw_log_buffer(f: &mut Frame, viewer: &LogViewer, area: ratatui::layout::Rec
|
||||||
|
|
||||||
let paragraph = Paragraph::new(Text::from(lines))
|
let paragraph = Paragraph::new(Text::from(lines))
|
||||||
.block(default_block(&title))
|
.block(default_block(&title))
|
||||||
.wrap(Wrap { trim: false });
|
.wrap(Wrap { trim: false })
|
||||||
|
.scroll((scroll_offset as u16, 0));
|
||||||
f.render_widget(paragraph, area);
|
f.render_widget(paragraph, area);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue