use std::collections::HashMap;
use crate::display_map::build_display_map;
use crate::git::types::FileDelta;
use crate::highlight::HighlightSpan;
use super::TextBuffer;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DiffViewMode {
Split,
Unified,
}
#[derive(Debug, Clone)]
pub struct DiffOptions {
pub ignore_whitespace: bool,
pub view_mode: DiffViewMode,
}
impl DiffOptions {
pub fn new(ignore_whitespace: bool, unified: bool) -> Self {
Self {
ignore_whitespace,
view_mode: if unified {
DiffViewMode::Unified
} else {
DiffViewMode::Split
},
}
}
}
pub struct DiffState {
pub options: DiffOptions,
pub deltas: Vec<FileDelta>,
pub selected_file: Option<usize>,
pub scroll_offset: usize,
pub cursor_row: usize,
pub viewport_height: usize,
pub loading: bool,
pub old_highlights: Vec<Vec<HighlightSpan>>,
pub new_highlights: Vec<Vec<HighlightSpan>>,
pub display_context: usize,
pub gap_expansions: HashMap<usize, usize>,
pub visual_row_offsets: Vec<usize>,
pub visual_row_heights: Vec<usize>,
pub visual_total_rows: usize,
pub search_active: bool,
pub search_query: TextBuffer,
pub search_matches: Vec<usize>,
pub search_match_index: Option<usize>,
}
impl DiffState {
pub fn new(options: DiffOptions) -> Self {
Self {
options,
deltas: Vec::new(),
selected_file: None,
scroll_offset: 0,
cursor_row: 0,
viewport_height: 20,
loading: false,
old_highlights: Vec::new(),
new_highlights: Vec::new(),
display_context: 3,
gap_expansions: HashMap::new(),
visual_row_offsets: Vec::new(),
visual_row_heights: Vec::new(),
visual_total_rows: 0,
search_active: false,
search_query: TextBuffer::new(),
search_matches: Vec::new(),
search_match_index: None,
}
}
pub fn selected_delta(&self) -> Option<&FileDelta> {
self.selected_file.and_then(|i| self.deltas.get(i))
}
pub fn current_source_line(&self) -> Option<u32> {
let delta = self.selected_delta()?;
let display_map = build_display_map(
delta,
self.options.view_mode,
self.display_context,
&self.gap_expansions,
);
let info = display_map.get(self.cursor_row)?;
info.new_lineno.or(info.old_lineno)
}
}