use crate::blame::BlameInfo;
use crate::config::{
DiffExtentMarkerMode, DiffExtentMarkerScope, DiffForegroundMode, DiffHighlightMode,
FoldContextMode, SyntaxMode,
};
use crate::syntax::SyntaxSide;
use oyo_core::diff::DiffResult;
use oyo_core::{multi::BlameSource, AnimationFrame, StepDirection};
use ratatui::style::Color;
use ratatui::text::Line;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Instant;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AnimationPhase {
Idle,
FadeOut,
FadeIn,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum ViewMode {
#[default]
UnifiedPane,
Split,
Evolution,
Blame,
}
impl ViewMode {
pub fn next(self) -> Self {
match self {
ViewMode::UnifiedPane => ViewMode::Split,
ViewMode::Split => ViewMode::Evolution,
ViewMode::Evolution => ViewMode::Blame,
ViewMode::Blame => ViewMode::UnifiedPane,
}
}
pub fn prev(self) -> Self {
match self {
ViewMode::UnifiedPane => ViewMode::Blame,
ViewMode::Split => ViewMode::UnifiedPane,
ViewMode::Evolution => ViewMode::Split,
ViewMode::Blame => ViewMode::Evolution,
}
}
}
#[derive(Clone, Copy, Debug)]
pub(crate) struct HunkStart {
pub(crate) idx: usize,
pub(crate) change_id: Option<usize>,
}
#[derive(Clone, Copy, Debug)]
pub(crate) struct HunkBounds {
pub(crate) start: HunkStart,
pub(crate) end: HunkStart,
}
pub(crate) const FILE_PANEL_MIN_WIDTH: u16 = 24;
pub(crate) const DIFF_VIEW_MIN_WIDTH: u16 = 50;
#[derive(Clone, Copy, Debug)]
pub(crate) struct NoStepState {
pub(crate) current_hunk: usize,
pub(crate) cursor_change: Option<usize>,
pub(crate) last_nav_was_hunk: bool,
}
#[derive(Clone, Copy, Debug)]
pub(crate) enum StepEdge {
Start,
End,
}
#[derive(Clone, Copy, Debug)]
pub(crate) struct StepEdgeHint {
pub(crate) change_id: Option<usize>,
pub(crate) edge: StepEdge,
pub(crate) until: Instant,
}
#[derive(Clone, Copy, Debug)]
pub(crate) enum HunkEdge {
First,
Last,
}
#[derive(Clone, Copy, Debug)]
pub(crate) struct HunkEdgeHint {
pub(crate) edge: HunkEdge,
pub(crate) until: Instant,
}
#[derive(Clone, Debug)]
pub(crate) struct BlameStepHint {
pub(crate) change_id: usize,
pub(crate) text: String,
}
#[derive(Clone, Debug)]
pub(crate) struct BlameDisplay {
pub(crate) group_key: String,
pub(crate) text: String,
pub(crate) author_time: Option<i64>,
pub(crate) uncommitted: bool,
}
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub(crate) struct BlameCacheKey {
pub(crate) path: PathBuf,
pub(crate) line: usize,
pub(crate) source: BlameSource,
}
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub(crate) struct BlamePrefetchKey {
pub(crate) path: PathBuf,
pub(crate) source: BlameSource,
}
#[derive(Clone, Copy, Debug)]
pub(crate) struct BlamePrefetchRange {
pub(crate) start: usize,
pub(crate) end: usize,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) struct BlameRenderKey {
pub(crate) file_index: usize,
pub(crate) current_step: usize,
pub(crate) current_hunk: usize,
pub(crate) hunk_preview_mode: bool,
pub(crate) preview_from_backward: bool,
pub(crate) stepping: bool,
pub(crate) line_wrap: bool,
pub(crate) wrap_width: usize,
pub(crate) blame_width: u16,
pub(crate) view_len: usize,
pub(crate) window_start: usize,
pub(crate) animation_frame: AnimationFrame,
pub(crate) cache_rev: u64,
pub(crate) time_bucket: i64,
}
pub(crate) struct BlameRenderCache {
pub(crate) key: BlameRenderKey,
pub(crate) wrap_counts: Vec<usize>,
pub(crate) extra_rows_after_line: Vec<usize>,
pub(crate) extra_texts_after_line: Vec<Vec<String>>,
pub(crate) display_texts: Vec<String>,
pub(crate) bar_colors: Vec<Option<Color>>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) struct UnifiedRenderKey {
pub(crate) file_index: usize,
pub(crate) frame: AnimationFrame,
pub(crate) current_step: usize,
pub(crate) active_change: Option<usize>,
pub(crate) cursor_change: Option<usize>,
pub(crate) peek_state: Option<PeekState>,
pub(crate) animating_hunk: Option<usize>,
pub(crate) step_direction: StepDirection,
pub(crate) current_hunk: usize,
pub(crate) last_nav_was_hunk: bool,
pub(crate) hunk_preview_mode: bool,
pub(crate) preview_from_backward: bool,
pub(crate) show_hunk_extent_while_stepping: bool,
pub(crate) placeholder_view: bool,
pub(crate) fold_context: FoldContextMode,
pub(crate) viewport_height: usize,
pub(crate) windowed: bool,
pub(crate) window_start: usize,
pub(crate) stepping: bool,
pub(crate) line_wrap: bool,
pub(crate) wrap_width: usize,
pub(crate) scroll_offset: usize,
pub(crate) horizontal_scroll: usize,
pub(crate) diff_bg: bool,
pub(crate) diff_fg: DiffForegroundMode,
pub(crate) diff_highlight: DiffHighlightMode,
pub(crate) diff_extent_marker: DiffExtentMarkerMode,
pub(crate) diff_extent_marker_scope: DiffExtentMarkerScope,
pub(crate) diff_extent_marker_context: bool,
pub(crate) gutter_signs: bool,
pub(crate) strikethrough_deletions: bool,
pub(crate) search_query: String,
pub(crate) search_active: bool,
pub(crate) syntax_mode: SyntaxMode,
pub(crate) syntax_theme: String,
pub(crate) theme_is_light: bool,
pub(crate) syntax_epoch: u64,
pub(crate) step_edge_hint: bool,
pub(crate) hunk_edge_hint: bool,
pub(crate) blame_hunk_hint: Option<String>,
}
pub(crate) struct UnifiedRenderModel {
pub(crate) key: UnifiedRenderKey,
pub(crate) gutter_lines: Vec<Line<'static>>,
pub(crate) content_lines: Vec<Line<'static>>,
pub(crate) bg_lines: Option<Vec<Line<'static>>>,
pub(crate) display_len: usize,
pub(crate) max_line_width: usize,
pub(crate) primary_display_idx: Option<usize>,
pub(crate) active_display_idx: Option<usize>,
}
#[derive(Clone, Debug)]
pub(crate) struct BlameRequest {
pub(crate) repo_root: PathBuf,
pub(crate) path: PathBuf,
pub(crate) source: BlameSource,
pub(crate) start: usize,
pub(crate) end: usize,
}
#[derive(Clone, Debug)]
pub(crate) struct BlameResponse {
pub(crate) path: PathBuf,
pub(crate) source: BlameSource,
pub(crate) start: usize,
pub(crate) end: usize,
pub(crate) entries: Vec<(usize, BlameInfo)>,
}
#[derive(Clone, Debug)]
pub(crate) struct DiffRequest {
pub(crate) file_index: usize,
pub(crate) old: Arc<str>,
pub(crate) new: Arc<str>,
}
#[derive(Clone, Debug)]
pub(crate) struct DiffResponse {
pub(crate) file_index: usize,
pub(crate) diff: Result<DiffResult, String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PeekScope {
Change,
Hunk,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PeekMode {
Old,
Modified,
Mixed,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct PeekState {
pub scope: PeekScope,
pub mode: PeekMode,
}
#[derive(Debug, Clone)]
pub(crate) struct SyntaxScopeCache {
pub(crate) file_index: usize,
pub(crate) side: SyntaxSide,
pub(crate) line_num: usize,
pub(crate) label: String,
}