Git · DiffViewer: rows move to their own file; shorter comments

This commit is contained in:
ZacharyZhang-NY committed 2026-10-07 00:45:24 -04:00
1 parent e69b96c9e3
commit e226d7979b
5 files changed
+110 -94

No files matched your search

+96
View File
@@ -0,0 +1,96 @@
//! The rows a diff viewer draws, and their colors.
use std::ops::Range;
use gpui::{App, HighlightStyle, Hsla, SharedString, StyledText};
use super::{
diff::{DiffLine, LineKind, Stretch, pair_places},
viewer::DiffLayout,
};
use crate::{
editor::{code_colors, stack},
theme::Palette,
};
/// A line's place: its stretch, then its line there.
pub type Place = (usize, usize);
/// A row as the viewer draws it.
#[derive(Clone)]
pub(super) enum Shown {
/// A hunk's header and its place among the stretches.
Header(usize, SharedString),
Line(Place, DiffLine),
Pair(Option<(Place, DiffLine)>, Option<(Place, DiffLine)>),
/// A folded stretch: its place among the stretches and how many lines it hides.
Fold(usize, usize),
}
pub(super) fn shown(stretches: &[Stretch], layout: DiffLayout, open: &[usize]) -> Vec<Shown> {
let mut rows = Vec::new();
for (ix, stretch) in stretches.iter().enumerate() {
match stretch {
Stretch::Hunk { header, lines } => {
rows.push(Shown::Header(ix, header.clone()));
let at = |line: usize| ((ix, line), lines[line].clone());
match layout {
DiffLayout::Unified => rows.extend((0..lines.len()).map(|line| {
let (place, line) = at(line);
Shown::Line(place, line)
})),
DiffLayout::Split => rows.extend(
pair_places(lines)
.into_iter()
.map(|(left, right)| Shown::Pair(left.map(at), right.map(at))),
),
}
}
Stretch::Folded(lines) if open.contains(&ix) => {
rows.extend(lines.iter().enumerate().map(|(at, line)| {
let place = (ix, at);
match layout {
DiffLayout::Unified => Shown::Line(place, line.clone()),
DiffLayout::Split => {
Shown::Pair(Some((place, line.clone())), Some((place, line.clone())))
}
}
}))
}
Stretch::Folded(lines) => rows.push(Shown::Fold(ix, lines.len())),
}
}
rows
}
/// The wash behind a line, and behind its changed words.
pub(super) fn washes(kind: LineKind, colors: &Palette) -> (Option<Hsla>, Hsla) {
match kind {
LineKind::Same => (None, colors.hover),
LineKind::Added => (
Some(colors.success.opacity(0.08)),
colors.success.opacity(0.25),
),
LineKind::Removed => (
Some(colors.danger.opacity(0.08)),
colors.danger.opacity(0.25),
),
}
}
/// A line's code, colored as code, its changed words washed.
pub(super) fn code(line: &DiffLine, colors: &Palette, cx: &App) -> StyledText {
let (_, word) = washes(line.kind, colors);
let mut styles: Vec<(Range<usize>, HighlightStyle)> = code_colors(&line.text, cx);
styles.extend(line.words.iter().map(|range| {
(
range.clone(),
HighlightStyle {
background_color: Some(word),
..HighlightStyle::default()
},
)
}));
styles.sort_by_key(|(range, _)| range.start);
StyledText::new(line.text.clone()).with_highlights(stack(styles))
}