#[allow(clippy::wildcard_imports)]
use super::*;
pub fn count_changes(chunks: &[DiffChunk]) -> usize {
chunks.iter().filter(|c| c.tag != DiffTag::Equal).count()
}
#[allow(clippy::too_many_arguments)]
pub fn navigate_chunk(
chunks: &[DiffChunk],
current_chunk: &Rc<Cell<Option<usize>>>,
direction: i32, left_tv: &TextView,
left_buf: &TextBuffer,
left_scroll: &ScrolledWindow,
right_tv: &TextView,
right_buf: &TextBuffer,
right_scroll: &ScrolledWindow,
active_tv: &TextView,
wrap: bool,
) {
let cursor_line = cursor_line_from_view(active_tv);
let side = if active_tv == right_tv {
Side::B
} else {
Side::A
};
if let Some(idx) = diff_state::find_next_chunk(chunks, cursor_line, direction, side, wrap) {
let chunk = &chunks[idx];
scroll_to_line(left_tv, left_buf, chunk.start_a, left_scroll);
scroll_to_line(right_tv, right_buf, chunk.start_b, right_scroll);
place_cursor_at_line(left_buf, chunk.start_a);
place_cursor_at_line(right_buf, chunk.start_b);
current_chunk.set(Some(idx));
}
}
pub fn scroll_for_view(tv: &TextView, fallback: &ScrolledWindow) -> ScrolledWindow {
tv.ancestor(ScrolledWindow::static_type())
.and_then(|w| w.downcast::<ScrolledWindow>().ok())
.unwrap_or_else(|| fallback.clone())
}
pub fn cursor_line_from_view(tv: &TextView) -> usize {
let buf = tv.buffer();
let mark = buf.get_insert();
let iter = buf.iter_at_mark(&mark);
iter.line() as usize
}
pub fn place_cursor_at_line(buf: &TextBuffer, line: usize) {
if let Some(iter) = buf.iter_at_line(line as i32) {
buf.place_cursor(&iter);
}
}
pub fn scroll_to_line(tv: &TextView, buf: &TextBuffer, line: usize, scroll: &ScrolledWindow) {
if let Some(iter) = buf.iter_at_line(line as i32) {
let (y, h) = tv.line_yrange(&iter);
let visible_h = scroll.vadjustment().page_size();
let target = (y as f64 + h as f64 / 2.0) - visible_h / 2.0;
scroll.vadjustment().set_value(target.max(0.0));
}
}
pub fn update_chunk_label(label: &Label, chunks: &[DiffChunk], current: Option<usize>) {
label.set_label(&diff_state::format_chunk_label(chunks, current));
}
pub fn update_chunk_nav_sensitivity(
prev_btn: &Button,
next_btn: &Button,
chunks: &[DiffChunk],
active_tv: &TextView,
right_tv: &TextView,
wrap: bool,
) {
let cursor_line = cursor_line_from_view(active_tv);
let side = if active_tv == right_tv {
Side::B
} else {
Side::A
};
let (prev, next) = diff_state::chunk_nav_sensitivity(chunks, cursor_line, side, wrap);
prev_btn.set_sensitive(prev);
next_btn.set_sensitive(next);
}