From 8422a81d8854cbf67fb2891ef5b6c699ff05c354 Mon Sep 17 00:00:00 2001 From: Mikayla Maki Date: Thu, 6 Mar 2025 18:13:50 -0800 Subject: [PATCH] Add staged variants of the hunk_style controls (#26259) This PR adds a few more hunk style settings that flips the emphasis. Normally, the concept at Zed has been that the project diff should emphasize what's going into the commit. However, this leads to a problem where the default state of all diff hunks are in the non-emphasized state, making them hard to see and interact with. Especially on light themes. This PR is an experiment in flipping the emphasis states. Now the project diff is more like a queue of work, with the next "job" (hunk to be evaluated) emphasized, and the "completed" (staged) hunks deemphasized. This fixes the default state issue but is a big jump from how we've been thinking about it. So here we can try it out and see how it feels :) Release Notes: - Git Beta: Added hunk style settings to emphasize the unstaged state, rather than the staged state. --- crates/editor/src/element.rs | 71 +++++++++++++++++++------- crates/project/src/project_settings.rs | 4 ++ 2 files changed, 57 insertions(+), 18 deletions(-) diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index fd756bbd05..1e3f7f2e7b 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -4349,6 +4349,11 @@ impl EditorElement { fn paint_gutter_diff_hunks(layout: &mut EditorLayout, window: &mut Window, cx: &mut App) { let is_light = cx.theme().appearance().is_light(); + let hunk_style = ProjectSettings::get_global(cx) + .git + .hunk_style + .unwrap_or_default(); + if layout.display_hunks.is_empty() { return; } @@ -4412,9 +4417,20 @@ impl EditorElement { if let Some((hunk_bounds, mut background_color, corner_radii, secondary_status)) = hunk_to_paint { - if secondary_status.has_secondary_hunk() { - background_color = - background_color.opacity(if is_light { 0.2 } else { 0.32 }); + match hunk_style { + GitHunkStyleSetting::Transparent | GitHunkStyleSetting::Pattern => { + if secondary_status.has_secondary_hunk() { + background_color = + background_color.opacity(if is_light { 0.2 } else { 0.32 }); + } + } + GitHunkStyleSetting::StagedPattern + | GitHunkStyleSetting::StagedTransparent => { + if !secondary_status.has_secondary_hunk() { + background_color = + background_color.opacity(if is_light { 0.2 } else { 0.32 }); + } + } } // Flatten the background color with the editor color to prevent @@ -6734,10 +6750,10 @@ 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) + let hunk_style = ProjectSettings::get_global(cx) .git .hunk_style - .map_or(false, |style| matches!(style, GitHunkStyleSetting::Pattern)); + .unwrap_or_default(); for (ix, row_info) in row_infos.iter().enumerate() { let Some(diff_status) = row_info.diff_status else { @@ -6757,20 +6773,39 @@ impl Element for EditorElement { let unstaged = diff_status.has_secondary_hunk(); let hunk_opacity = if is_light { 0.16 } else { 0.12 }; + let slash_width = line_height.0 / 1.5; // ~16 by default - 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 staged_background = match hunk_style { + GitHunkStyleSetting::Transparent | GitHunkStyleSetting::Pattern => { + solid_background(background_color.opacity(hunk_opacity)) + } + GitHunkStyleSetting::StagedPattern => { + pattern_slash(background_color.opacity(hunk_opacity), slash_width) + } + GitHunkStyleSetting::StagedTransparent => { + solid_background(background_color.opacity(if is_light { + 0.08 + } else { + 0.04 + })) + } + }; + + let unstaged_background = match hunk_style { + GitHunkStyleSetting::Transparent => { + solid_background(background_color.opacity(if is_light { + 0.08 + } else { + 0.04 + })) + } + GitHunkStyleSetting::Pattern => { + pattern_slash(background_color.opacity(hunk_opacity), slash_width) + } + GitHunkStyleSetting::StagedPattern + | GitHunkStyleSetting::StagedTransparent => { + solid_background(background_color.opacity(hunk_opacity)) + } }; let background = if unstaged { diff --git a/crates/project/src/project_settings.rs b/crates/project/src/project_settings.rs index c5425084a9..e825742d4f 100644 --- a/crates/project/src/project_settings.rs +++ b/crates/project/src/project_settings.rs @@ -212,6 +212,10 @@ pub enum GitHunkStyleSetting { Transparent, /// Show unstaged hunks with a pattern background Pattern, + /// Show staged hunks with a pattern background + StagedPattern, + /// Show staged hunks with a pattern background + StagedTransparent, } #[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema)]