From 6dde040b97ada70dd263f325e68476b58f6474ff 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 0ac7a547ecce443e5c62f4613fcbf8bbefd4bb3a..d16c59b9ec5b9f60aa9d98cc120db915854a4021 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 c5425084a968d2ce8a15febec47dd5afaee6727c..e825742d4f44a36cf52966e165dcd9decdc21ff8 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)]