Color staged and unstaged hunks differently by opacity (#25108)

Release Notes:

- Make staged diff hunks appear as more opaque than unstaged hunks

---------

Co-authored-by: Nate Butler <iamnbutler@gmail.com>
This commit is contained in:
Cole Miller 2025-02-19 13:33:21 -05:00 committed by GitHub
parent c9bd44f983
commit 8e17b34eff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 265 additions and 175 deletions

View file

@ -29,10 +29,16 @@ struct BufferDiffInner {
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum DiffHunkStatus {
Added(DiffHunkSecondaryStatus),
Modified(DiffHunkSecondaryStatus),
Removed(DiffHunkSecondaryStatus),
pub struct DiffHunkStatus {
pub kind: DiffHunkStatusKind,
pub secondary: DiffHunkSecondaryStatus,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum DiffHunkStatusKind {
Added,
Modified,
Deleted,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -42,6 +48,16 @@ pub enum DiffHunkSecondaryStatus {
None,
}
impl DiffHunkSecondaryStatus {
pub fn is_secondary(&self) -> bool {
match self {
DiffHunkSecondaryStatus::HasSecondaryHunk => true,
DiffHunkSecondaryStatus::OverlapsWithSecondaryHunk => true,
DiffHunkSecondaryStatus::None => false,
}
}
}
/// A diff hunk resolved to rows in the buffer.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DiffHunk {
@ -927,34 +943,76 @@ impl BufferDiff {
impl DiffHunk {
pub fn status(&self) -> DiffHunkStatus {
if self.buffer_range.start == self.buffer_range.end {
DiffHunkStatus::Removed(self.secondary_status)
let kind = if self.buffer_range.start == self.buffer_range.end {
DiffHunkStatusKind::Deleted
} else if self.diff_base_byte_range.is_empty() {
DiffHunkStatus::Added(self.secondary_status)
DiffHunkStatusKind::Added
} else {
DiffHunkStatus::Modified(self.secondary_status)
DiffHunkStatusKind::Modified
};
DiffHunkStatus {
kind,
secondary: self.secondary_status,
}
}
}
impl DiffHunkStatus {
pub fn is_removed(&self) -> bool {
matches!(self, DiffHunkStatus::Removed(_))
pub fn is_deleted(&self) -> bool {
self.kind == DiffHunkStatusKind::Deleted
}
pub fn is_added(&self) -> bool {
self.kind == DiffHunkStatusKind::Added
}
pub fn is_modified(&self) -> bool {
self.kind == DiffHunkStatusKind::Modified
}
pub fn added(secondary: DiffHunkSecondaryStatus) -> Self {
Self {
kind: DiffHunkStatusKind::Added,
secondary,
}
}
pub fn modified(secondary: DiffHunkSecondaryStatus) -> Self {
Self {
kind: DiffHunkStatusKind::Modified,
secondary,
}
}
pub fn deleted(secondary: DiffHunkSecondaryStatus) -> Self {
Self {
kind: DiffHunkStatusKind::Deleted,
secondary,
}
}
#[cfg(any(test, feature = "test-support"))]
pub fn removed() -> Self {
DiffHunkStatus::Removed(DiffHunkSecondaryStatus::None)
pub fn deleted_none() -> Self {
Self {
kind: DiffHunkStatusKind::Deleted,
secondary: DiffHunkSecondaryStatus::None,
}
}
#[cfg(any(test, feature = "test-support"))]
pub fn added() -> Self {
DiffHunkStatus::Added(DiffHunkSecondaryStatus::None)
pub fn added_none() -> Self {
Self {
kind: DiffHunkStatusKind::Added,
secondary: DiffHunkSecondaryStatus::None,
}
}
#[cfg(any(test, feature = "test-support"))]
pub fn modified() -> Self {
DiffHunkStatus::Modified(DiffHunkSecondaryStatus::None)
pub fn modified_none() -> Self {
Self {
kind: DiffHunkStatusKind::Modified,
secondary: DiffHunkSecondaryStatus::None,
}
}
}
@ -1031,7 +1089,7 @@ mod tests {
diff.hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &buffer, None),
&buffer,
&diff_base,
&[(1..2, "two\n", "HELLO\n", DiffHunkStatus::modified())],
&[(1..2, "two\n", "HELLO\n", DiffHunkStatus::modified_none())],
);
buffer.edit([(0..0, "point five\n")]);
@ -1041,8 +1099,8 @@ mod tests {
&buffer,
&diff_base,
&[
(0..1, "", "point five\n", DiffHunkStatus::added()),
(2..3, "two\n", "HELLO\n", DiffHunkStatus::modified()),
(0..1, "", "point five\n", DiffHunkStatus::added_none()),
(2..3, "two\n", "HELLO\n", DiffHunkStatus::modified_none()),
],
);
@ -1105,23 +1163,18 @@ mod tests {
let uncommitted_diff = BufferDiff::build_sync(buffer.clone(), head_text.clone(), cx);
let expected_hunks = vec![
(
2..3,
"two\n",
"TWO\n",
DiffHunkStatus::Modified(DiffHunkSecondaryStatus::None),
),
(2..3, "two\n", "TWO\n", DiffHunkStatus::modified_none()),
(
4..6,
"four\nfive\n",
"FOUR\nFIVE\n",
DiffHunkStatus::Modified(DiffHunkSecondaryStatus::OverlapsWithSecondaryHunk),
DiffHunkStatus::modified(DiffHunkSecondaryStatus::OverlapsWithSecondaryHunk),
),
(
7..8,
"seven\n",
"SEVEN\n",
DiffHunkStatus::Modified(DiffHunkSecondaryStatus::HasSecondaryHunk),
DiffHunkStatus::modified(DiffHunkSecondaryStatus::HasSecondaryHunk),
),
];
@ -1197,9 +1250,9 @@ mod tests {
&buffer,
&diff_base,
&[
(6..7, "", "HELLO\n", DiffHunkStatus::added()),
(9..10, "six\n", "SIXTEEN\n", DiffHunkStatus::modified()),
(12..13, "", "WORLD\n", DiffHunkStatus::added()),
(6..7, "", "HELLO\n", DiffHunkStatus::added_none()),
(9..10, "six\n", "SIXTEEN\n", DiffHunkStatus::modified_none()),
(12..13, "", "WORLD\n", DiffHunkStatus::added_none()),
],
);
}