feat: add pierre-style presentation to diff view

This commit is contained in:
2026-11-06 15:21:20 +07:00
parent 7214c70ea7
commit e8e1cb39e0
5 changed files with 636 additions and 229 deletions
+138
View File
@@ -0,0 +1,138 @@
//! Shared helpers for the editor's views: gutter cells, role colors, change
//! washes and diff row building.
#[cfg(feature = "diff_view")]
use std::ops::Range;
use gpui::{App, HighlightStyle, Hsla, IntoElement, ParentElement as _, Styled as _, div};
use gpui_native_theme::{ActiveTheme as _, ColorTokens, Ramps};
#[cfg(feature = "diff_view")]
use similar::{Change, ChangeTag};
#[cfg(feature = "diff_view")]
use crate::diff_view::{DiffRow, DiffRowKind};
#[cfg(feature = "diff_view")]
use crate::highlight::HighlightedCode;
use crate::highlight::Role;
/// Maps a highlight role to the theme's semantic palette.
pub(crate) fn role_color(role: Role, colors: ColorTokens, ramps: Ramps) -> Hsla {
match role {
Role::Text => colors.foreground,
Role::Keyword => ramps.primary.base,
Role::String | Role::Escape => ramps.success.base,
Role::Comment | Role::Punctuation => colors.muted_foreground,
Role::Function | Role::Property => ramps.info.base,
Role::Type => ramps.warning.base,
Role::Number | Role::Constant => ramps.secondary.base,
Role::Operator => colors.foreground,
Role::Tag => ramps.destructive.base,
}
}
/// Builds the highlight style for one run of a code view row.
pub(crate) fn run_style(
role: Role,
selected: bool,
colors: ColorTokens,
ramps: Ramps,
) -> HighlightStyle {
HighlightStyle {
color: Some(role_color(role, colors, ramps)),
background_color: selected.then_some(colors.selection),
..Default::default()
}
}
/// A gutter cell sized to the whole row.
pub(crate) fn gutter_cell<E>(cx: &App, color: Hsla, content: E) -> gpui::Div
where
E: IntoElement,
{
let theme = cx.theme();
div()
.size_10()
.flex()
.items_center()
.justify_center()
.flex_none()
.font_family(theme.mono_font)
.text_size(theme.sizes.small.text_size)
.line_height(gpui::relative(1.0))
.text_color(color)
.child(content)
}
/// Builds a diff line row from a `similar` change.
#[cfg(feature = "diff_view")]
pub(crate) fn line_row(
change: &Change<&str>,
code: &HighlightedCode,
changed_ranges: Vec<Range<usize>>,
) -> DiffRow {
let content = match change.tag() {
ChangeTag::Equal => change
.new_index()
.and_then(|ix| code.lines.get(ix))
.cloned()
.unwrap_or_default(),
ChangeTag::Delete => change
.old_index()
.and_then(|ix| code.lines.get(ix))
.cloned()
.unwrap_or_default(),
ChangeTag::Insert => change
.new_index()
.and_then(|ix| code.lines.get(ix))
.cloned()
.unwrap_or_default(),
};
let (old_number, new_number) = match change.tag() {
ChangeTag::Equal => (
change.old_index().map(|ix| ix + 1),
change.new_index().map(|ix| ix + 1),
),
ChangeTag::Delete => (change.old_index().map(|ix| ix + 1), None),
ChangeTag::Insert => (None, change.new_index().map(|ix| ix + 1)),
};
DiffRow {
kind: match change.tag() {
ChangeTag::Equal => DiffRowKind::Context,
ChangeTag::Delete => DiffRowKind::Removed,
ChangeTag::Insert => DiffRowKind::Added,
},
content,
old_number,
new_number,
changed_ranges,
header: Default::default(),
hidden_lines: 0,
}
}
/// A change wash: the ramp color at the alpha rows tint with.
pub(crate) fn wash(color: Hsla) -> Hsla {
Hsla {
a: color.a * 0.14,
..color
}
}
/// The stronger wash under number gutters and intra-line word changes.
pub(crate) fn wash_strong(color: Hsla) -> Hsla {
Hsla {
a: color.a * 0.34,
..color
}
}
/// The subtle wash that sets the number gutter off from the code.
pub(crate) fn wash_gutter(colors: &ColorTokens) -> Hsla {
Hsla {
a: colors.muted.a * 0.18,
..colors.muted
}
}