@@ -32,14 +32,15 @@ use collections::{BTreeMap, HashMap, HashSet};
use file_icons::FileIcons;
use git::{blame::BlameEntry, status::FileStatus, Oid};
use gpui::{
- 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,
+ anchored, deferred, div, fill, linear_color_stop, linear_gradient, outline, pattern_slash,
+ point, px, quad, relative, size, solid_background, 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::{
@@ -54,7 +55,7 @@ use multi_buffer::{
Anchor, ExcerptId, ExcerptInfo, ExpandExcerptDirection, MultiBufferPoint, MultiBufferRow,
RowInfo,
};
-use project::project_settings::{self, GitGutterSetting, ProjectSettings};
+use project::project_settings::{self, GitGutterSetting, GitHunkStyleSetting, ProjectSettings};
use settings::Settings;
use smallvec::{smallvec, SmallVec};
use std::{
@@ -4346,7 +4347,7 @@ impl EditorElement {
}
}
- fn paint_diff_hunks(layout: &mut EditorLayout, window: &mut Window, cx: &mut App) {
+ fn paint_gutter_diff_hunks(layout: &mut EditorLayout, window: &mut Window, cx: &mut App) {
let is_light = cx.theme().appearance().is_light();
if layout.display_hunks.is_empty() {
@@ -4416,10 +4417,19 @@ impl EditorElement {
background_color =
background_color.opacity(if is_light { 0.2 } else { 0.32 });
}
+
+ // Flatten the background color with the editor color to prevent
+ // elements below transparent hunks from showing through
+ let flattened_background_color = cx
+ .theme()
+ .colors()
+ .editor_background
+ .blend(background_color);
+
window.paint_quad(quad(
hunk_bounds,
corner_radii,
- background_color,
+ flattened_background_color,
Edges::default(),
transparent_black(),
));
@@ -4547,7 +4557,7 @@ impl EditorElement {
)
});
if show_git_gutter {
- Self::paint_diff_hunks(layout, window, cx)
+ Self::paint_gutter_diff_hunks(layout, window, cx)
}
let highlight_width = 0.275 * layout.position_map.line_height;
@@ -6711,15 +6721,16 @@ impl Element for EditorElement {
.update(cx, |editor, cx| editor.highlighted_display_rows(window, cx));
let is_light = cx.theme().appearance().is_light();
+ let use_pattern = ProjectSettings::get_global(cx)
+ .git
+ .hunk_style
+ .map_or(false, |style| matches!(style, GitHunkStyleSetting::Pattern));
for (ix, row_info) in row_infos.iter().enumerate() {
let Some(diff_status) = row_info.diff_status else {
continue;
};
- let staged_opacity = if is_light { 0.14 } else { 0.10 };
- let unstaged_opacity = 0.04;
-
let background_color = match diff_status.kind {
DiffHunkStatusKind::Added => cx.theme().colors().version_control_added,
DiffHunkStatusKind::Deleted => {
@@ -6730,15 +6741,34 @@ impl Element for EditorElement {
continue;
}
};
- let background_color = if diff_status.has_secondary_hunk() {
- background_color.opacity(unstaged_opacity)
+
+ let unstaged = diff_status.has_secondary_hunk();
+ let hunk_opacity = if is_light { 0.16 } else { 0.12 };
+
+ let staged_background =
+ solid_background(background_color.opacity(hunk_opacity));
+ let unstaged_background = if use_pattern {
+ pattern_slash(
+ background_color.opacity(hunk_opacity),
+ window.rem_size().0 * 1.125, // ~18 by default
+ )
+ } else {
+ solid_background(background_color.opacity(if is_light {
+ 0.08
+ } else {
+ 0.04
+ }))
+ };
+
+ let background = if unstaged {
+ unstaged_background
} else {
- background_color.opacity(staged_opacity)
+ staged_background
};
highlighted_rows
.entry(start_row + DisplayRow(ix as u32))
- .or_insert(background_color.into());
+ .or_insert(background);
}
let highlighted_ranges = self.editor.read(cx).background_highlights_in_range(