use hjkl_engine::Host;
use super::App;
impl App {
pub fn sync_viewport_to_editor(&mut self) {
let fw = self.focused_window();
let win = self.windows[fw].as_ref().expect("focused_window open");
let (top_row, top_col) = (win.top_row, win.top_col);
let (cursor_row, cursor_col) = (win.cursor_row, win.cursor_col);
let maybe_rect = win.last_rect;
if let Some(rect) = maybe_rect {
let vp = self.active_mut().editor.host_mut().viewport_mut();
vp.top_row = top_row;
vp.top_col = top_col;
vp.width = rect.w;
vp.height = rect.h;
}
self.active_mut()
.editor
.set_cursor_quiet(cursor_row, cursor_col);
}
pub fn sync_viewport_from_editor(&mut self) {
self.adjust_blame_box_viewport();
let vp = self.active().editor.host().viewport();
let (top_row, top_col) = (vp.top_row, vp.top_col);
let (cursor_row, cursor_col) = self.active().editor.cursor();
let fw = self.focused_window();
let win = self.windows[fw].as_mut().expect("focused_window open");
win.top_row = top_row;
win.top_col = top_col;
win.cursor_row = cursor_row;
win.cursor_col = cursor_col;
}
pub(crate) fn adjust_blame_box_viewport(&mut self) {
let slot = self.active();
let box_mode = slot.editor.is_blame()
&& matches!(slot.editor.host().viewport().wrap, hjkl_buffer::Wrap::None);
if !box_mode {
return;
}
let height = slot.editor.host().viewport().height as usize;
if height < 3 {
return;
}
let cursor_row = slot.editor.buffer().cursor().row;
let line_count = slot.editor.buffer().row_count();
let scrolloff = slot
.editor
.settings()
.scrolloff
.min(height.saturating_sub(1) / 2);
for _ in 0..(height * 2 + 4) {
let (top, idx) = {
let slot = self.active();
let top = slot.editor.host().viewport().top_row;
let buf = slot.editor.buffer();
let plan = crate::app::git_hunks::build_blame_box_plan(
&slot.blame,
line_count,
|r| buf.is_row_hidden(r),
top,
height,
0, );
let idx = plan.iter().position(|r| {
matches!(r, hjkl_buffer_tui::render::BlameRow::Content(d) if *d == cursor_row)
});
(top, idx)
};
let new_top = match idx {
None => {
if cursor_row >= top {
top + 1
} else {
top.saturating_sub(1)
}
}
Some(i) => {
if i < scrolloff && top > 0 {
top - 1
} else if i + 1 + scrolloff > height && top + 1 < line_count {
top + 1
} else {
break;
}
}
};
if new_top == top {
break;
}
self.active_mut().editor.host_mut().viewport_mut().top_row = new_top;
}
}
pub(crate) fn switch_focus(&mut self, target_id: super::window::WindowId) {
self.sync_viewport_from_editor();
self.set_focused_window(target_id);
self.sync_viewport_to_editor();
}
pub(crate) fn switch_tab(&mut self, tab_idx: usize) {
self.sync_viewport_from_editor();
self.active_tab = tab_idx;
self.sync_viewport_to_editor();
}
}