use crate::view::overlay::Overlay;
use crate::view::theme::{Theme, TokenColorExt};
use crate::view::ui::view_pipeline::{LineStart, ViewLine};
use ratatui::style::Style;
pub(super) struct TailFillInput<'a> {
pub current_view_line: &'a ViewLine,
pub theme: &'a Theme,
pub overlay_fill: Option<&'a Overlay>,
pub syntax_extend_bg: Option<ratatui::style::Color>,
pub first_line_byte_pos: Option<usize>,
pub last_line_byte_pos: Option<usize>,
}
pub(super) struct TailFillResult {
pub style: Style,
pub source_byte: Option<usize>,
}
pub(super) fn resolve_tail_fill(input: TailFillInput<'_>) -> Option<TailFillResult> {
let TailFillInput {
current_view_line,
theme,
overlay_fill,
syntax_extend_bg,
first_line_byte_pos,
last_line_byte_pos,
} = input;
let row_had_source_bytes = first_line_byte_pos.is_some() && last_line_byte_pos.is_some();
let overlay_style = if row_had_source_bytes {
overlay_fill.and_then(|overlay| overlay_bg_style(overlay, theme))
} else {
None
};
let syntax_style = if row_had_source_bytes {
syntax_extend_bg.map(|bg| Style::default().fg(bg).bg(bg))
} else {
None
};
let style = overlay_style
.or(syntax_style)
.or_else(|| virtual_line_fallback_style(current_view_line, theme))?;
let source_byte = if current_view_line.line_start == LineStart::AfterInjectedNewline {
None
} else {
current_view_line.source_start_byte
};
Some(TailFillResult { style, source_byte })
}
fn overlay_bg_style(overlay: &Overlay, theme: &Theme) -> Option<Style> {
use crate::view::overlay::OverlayFace;
let bg = match &overlay.face {
OverlayFace::Background { color } => Some(*color),
OverlayFace::Style { style } => style.bg,
OverlayFace::ThemedStyle {
fallback_style,
bg_theme,
..
} => bg_theme
.as_ref()
.and_then(|key| theme.resolve_theme_key(key))
.or(fallback_style.bg),
_ => None,
}?;
Some(Style::default().fg(bg).bg(bg))
}
fn virtual_line_fallback_style(view_line: &ViewLine, theme: &Theme) -> Option<Style> {
if view_line.line_start != LineStart::AfterInjectedNewline {
return None;
}
let token_style = view_line
.virtual_line_style
.as_ref()
.or_else(|| view_line.char_styles.first().and_then(|s| s.as_ref()))?;
let bg = token_style.bg.as_ref()?.to_ratatui(theme);
Some(Style::default().fg(bg).bg(bg))
}