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:
parent
c9bd44f983
commit
8e17b34eff
11 changed files with 265 additions and 175 deletions
|
@ -25,20 +25,20 @@ use crate::{
|
|||
CURSORS_VISIBLE_FOR, FILE_HEADER_HEIGHT, GIT_BLAME_MAX_AUTHOR_CHARS_DISPLAYED, MAX_LINE_LEN,
|
||||
MULTI_BUFFER_EXCERPT_HEADER_HEIGHT,
|
||||
};
|
||||
use buffer_diff::{DiffHunkSecondaryStatus, DiffHunkStatus};
|
||||
use buffer_diff::{DiffHunkSecondaryStatus, DiffHunkStatus, DiffHunkStatusKind};
|
||||
use client::ParticipantIndex;
|
||||
use collections::{BTreeMap, HashMap, HashSet};
|
||||
use file_icons::FileIcons;
|
||||
use git::{blame::BlameEntry, Oid};
|
||||
use gpui::{
|
||||
anchored, deferred, div, fill, linear_color_stop, linear_gradient, outline, pattern_slash,
|
||||
point, px, quad, relative, size, svg, transparent_black, Action, AnyElement, App,
|
||||
AvailableSpace, Axis, Bounds, ClickEvent, ClipboardItem, ContentMask, Context, Corner, Corners,
|
||||
CursorStyle, DispatchPhase, Edges, Element, ElementInputHandler, Entity, Focusable as _,
|
||||
FontId, GlobalElementId, Hitbox, Hsla, InteractiveElement, IntoElement, Keystroke, Length,
|
||||
ModifiersChangedEvent, MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad,
|
||||
ParentElement, Pixels, ScrollDelta, ScrollWheelEvent, ShapedLine, SharedString, Size,
|
||||
StatefulInteractiveElement, Style, Styled, Subscription, TextRun, TextStyleRefinement, Window,
|
||||
anchored, deferred, div, fill, linear_color_stop, linear_gradient, outline, point, px, quad,
|
||||
relative, size, svg, transparent_black, Action, AnyElement, App, AvailableSpace, Axis, Bounds,
|
||||
ClickEvent, ClipboardItem, ContentMask, Context, Corner, Corners, CursorStyle, DispatchPhase,
|
||||
Edges, Element, ElementInputHandler, Entity, Focusable as _, FontId, GlobalElementId, Hitbox,
|
||||
Hsla, InteractiveElement, IntoElement, Keystroke, Length, ModifiersChangedEvent, MouseButton,
|
||||
MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad, ParentElement, Pixels, ScrollDelta,
|
||||
ScrollWheelEvent, ShapedLine, SharedString, Size, StatefulInteractiveElement, Style, Styled,
|
||||
Subscription, TextRun, TextStyleRefinement, Window,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use language::{
|
||||
|
@ -74,7 +74,7 @@ use ui::{
|
|||
POPOVER_Y_PADDING,
|
||||
};
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
use util::{RangeExt, ResultExt};
|
||||
use util::{debug_panic, RangeExt, ResultExt};
|
||||
use workspace::{item::Item, notifications::NotifyTaskExt};
|
||||
|
||||
const INLINE_BLAME_PADDING_EM_WIDTHS: f32 = 7.;
|
||||
|
@ -2124,7 +2124,10 @@ impl EditorElement {
|
|||
.get(&display_row)
|
||||
.unwrap_or(&non_relative_number);
|
||||
write!(&mut line_number, "{number}").unwrap();
|
||||
if matches!(row_info.diff_status, Some(DiffHunkStatus::Removed(_))) {
|
||||
if row_info
|
||||
.diff_status
|
||||
.is_some_and(|status| status.is_deleted())
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -4174,10 +4177,10 @@ impl EditorElement {
|
|||
if row_infos[row_ix].diff_status.is_none() {
|
||||
continue;
|
||||
}
|
||||
if matches!(
|
||||
row_infos[row_ix].diff_status,
|
||||
Some(DiffHunkStatus::Added(_))
|
||||
) && !matches!(*status, DiffHunkStatus::Added(_))
|
||||
if row_infos[row_ix]
|
||||
.diff_status
|
||||
.is_some_and(|status| status.is_added())
|
||||
&& !status.is_added()
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -4571,39 +4574,35 @@ impl EditorElement {
|
|||
);
|
||||
Some((
|
||||
hunk_bounds,
|
||||
cx.theme().status().modified,
|
||||
cx.theme().colors().version_control_modified,
|
||||
Corners::all(px(0.)),
|
||||
&DiffHunkSecondaryStatus::None,
|
||||
DiffHunkSecondaryStatus::None,
|
||||
))
|
||||
}
|
||||
DisplayDiffHunk::Unfolded {
|
||||
status,
|
||||
display_row_range,
|
||||
..
|
||||
} => hitbox.as_ref().map(|hunk_hitbox| match status {
|
||||
DiffHunkStatus::Added(secondary_status) => (
|
||||
} => hitbox.as_ref().map(|hunk_hitbox| match status.kind {
|
||||
DiffHunkStatusKind::Added => (
|
||||
hunk_hitbox.bounds,
|
||||
cx.theme().status().created,
|
||||
cx.theme().colors().version_control_added,
|
||||
Corners::all(px(0.)),
|
||||
secondary_status,
|
||||
status.secondary,
|
||||
),
|
||||
DiffHunkStatus::Modified(secondary_status) => (
|
||||
DiffHunkStatusKind::Modified => (
|
||||
hunk_hitbox.bounds,
|
||||
cx.theme().status().modified,
|
||||
cx.theme().colors().version_control_modified,
|
||||
Corners::all(px(0.)),
|
||||
secondary_status,
|
||||
status.secondary,
|
||||
),
|
||||
DiffHunkStatus::Removed(secondary_status)
|
||||
if !display_row_range.is_empty() =>
|
||||
{
|
||||
(
|
||||
hunk_hitbox.bounds,
|
||||
cx.theme().status().deleted,
|
||||
Corners::all(px(0.)),
|
||||
secondary_status,
|
||||
)
|
||||
}
|
||||
DiffHunkStatus::Removed(secondary_status) => (
|
||||
DiffHunkStatusKind::Deleted if !display_row_range.is_empty() => (
|
||||
hunk_hitbox.bounds,
|
||||
cx.theme().colors().version_control_deleted,
|
||||
Corners::all(px(0.)),
|
||||
status.secondary,
|
||||
),
|
||||
DiffHunkStatusKind::Deleted => (
|
||||
Bounds::new(
|
||||
point(
|
||||
hunk_hitbox.origin.x - hunk_hitbox.size.width,
|
||||
|
@ -4611,19 +4610,21 @@ impl EditorElement {
|
|||
),
|
||||
size(hunk_hitbox.size.width * px(2.), hunk_hitbox.size.height),
|
||||
),
|
||||
cx.theme().status().deleted,
|
||||
cx.theme().colors().version_control_deleted,
|
||||
Corners::all(1. * line_height),
|
||||
secondary_status,
|
||||
status.secondary,
|
||||
),
|
||||
}),
|
||||
};
|
||||
|
||||
if let Some((hunk_bounds, mut background_color, corner_radii, secondary_status)) =
|
||||
if let Some((hunk_bounds, background_color, corner_radii, secondary_status)) =
|
||||
hunk_to_paint
|
||||
{
|
||||
if *secondary_status != DiffHunkSecondaryStatus::None {
|
||||
background_color.a *= 0.6;
|
||||
}
|
||||
let background_color = if secondary_status != DiffHunkSecondaryStatus::None {
|
||||
background_color.opacity(0.3)
|
||||
} else {
|
||||
background_color.opacity(1.0)
|
||||
};
|
||||
window.paint_quad(quad(
|
||||
hunk_bounds,
|
||||
corner_radii,
|
||||
|
@ -4659,7 +4660,7 @@ impl EditorElement {
|
|||
status,
|
||||
..
|
||||
} => {
|
||||
if status.is_removed() && display_row_range.is_empty() {
|
||||
if status.is_deleted() && display_row_range.is_empty() {
|
||||
let row = display_row_range.start;
|
||||
|
||||
let offset = line_height / 2.;
|
||||
|
@ -5312,10 +5313,10 @@ impl EditorElement {
|
|||
if end_display_row != start_display_row {
|
||||
end_display_row.0 -= 1;
|
||||
}
|
||||
let color = match &hunk.status() {
|
||||
DiffHunkStatus::Added(_) => theme.status().created,
|
||||
DiffHunkStatus::Modified(_) => theme.status().modified,
|
||||
DiffHunkStatus::Removed(_) => theme.status().deleted,
|
||||
let color = match &hunk.status().kind {
|
||||
DiffHunkStatusKind::Added => theme.status().created,
|
||||
DiffHunkStatusKind::Modified => theme.status().modified,
|
||||
DiffHunkStatusKind::Deleted => theme.status().deleted,
|
||||
};
|
||||
ColoredRange {
|
||||
start: start_display_row,
|
||||
|
@ -6896,46 +6897,38 @@ impl Element for EditorElement {
|
|||
)
|
||||
};
|
||||
|
||||
let (mut highlighted_rows, distinguish_unstaged_hunks) =
|
||||
self.editor.update(cx, |editor, cx| {
|
||||
(
|
||||
editor.highlighted_display_rows(window, cx),
|
||||
editor.distinguish_unstaged_diff_hunks,
|
||||
)
|
||||
});
|
||||
let mut highlighted_rows = self
|
||||
.editor
|
||||
.update(cx, |editor, cx| editor.highlighted_display_rows(window, cx));
|
||||
|
||||
for (ix, row_info) in row_infos.iter().enumerate() {
|
||||
let background = match row_info.diff_status {
|
||||
Some(DiffHunkStatus::Added(secondary_status)) => {
|
||||
let color = style.status.created_background;
|
||||
match secondary_status {
|
||||
DiffHunkSecondaryStatus::HasSecondaryHunk
|
||||
| DiffHunkSecondaryStatus::OverlapsWithSecondaryHunk
|
||||
if distinguish_unstaged_hunks =>
|
||||
{
|
||||
pattern_slash(color, line_height.0 / 4.0)
|
||||
}
|
||||
_ => color.into(),
|
||||
}
|
||||
}
|
||||
Some(DiffHunkStatus::Removed(secondary_status)) => {
|
||||
let color = style.status.deleted_background;
|
||||
match secondary_status {
|
||||
DiffHunkSecondaryStatus::HasSecondaryHunk
|
||||
| DiffHunkSecondaryStatus::OverlapsWithSecondaryHunk
|
||||
if distinguish_unstaged_hunks =>
|
||||
{
|
||||
pattern_slash(color, line_height.0 / 4.0)
|
||||
}
|
||||
_ => color.into(),
|
||||
}
|
||||
}
|
||||
_ => continue,
|
||||
let Some(diff_status) = row_info.diff_status else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let staged_opacity = 0.10;
|
||||
let unstaged_opacity = 0.04;
|
||||
|
||||
let background_color = match diff_status.kind {
|
||||
DiffHunkStatusKind::Added => cx.theme().colors().version_control_added,
|
||||
DiffHunkStatusKind::Deleted => {
|
||||
cx.theme().colors().version_control_deleted
|
||||
}
|
||||
DiffHunkStatusKind::Modified => {
|
||||
debug_panic!("modified diff status for row info");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let background_color =
|
||||
if diff_status.secondary == DiffHunkSecondaryStatus::None {
|
||||
background_color.opacity(staged_opacity)
|
||||
} else {
|
||||
background_color.opacity(unstaged_opacity)
|
||||
};
|
||||
|
||||
highlighted_rows
|
||||
.entry(start_row + DisplayRow(ix as u32))
|
||||
.or_insert(background);
|
||||
.or_insert(background_color.into());
|
||||
}
|
||||
|
||||
let highlighted_ranges = self.editor.read(cx).background_highlights_in_range(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue