From a7d74150ac7a663fdaa01ec5177e303baaf6c331 Mon Sep 17 00:00:00 2001
From: afdul <74723091+abdul2801@users.noreply.github.com>
Date: Tue, 18 Aug 2026 12:40:18 +0000
Subject: [PATCH] Fix the `git_gutter_width` setting (#62704)
# Objective
- Fixes #62645
## Solution
Since the default value isnt constant.It now has two options 1) Default
2) custom where user inputs a value.
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable
## Showcase
Release Notes:
- Added git_gutter_width setting to the Settings UI with default
(font-size-scaled) and custom (fixed pixel width) options
---------
Co-authored-by: Abdul Rafey Ahmed
Co-authored-by: MrSubidubi
---
Cargo.toml | 1 +
assets/settings/default.json | 6 +-
crates/agent_settings/src/agent_settings.rs | 10 +-
crates/collab_ui/src/panel_settings.rs | 5 +-
crates/editor/src/editor_settings.rs | 6 +-
crates/editor/src/element.rs | 12 +-
crates/git_ui/src/git_panel_settings.rs | 10 +-
.../src/markdown_preview_settings.rs | 6 +-
crates/migrator/src/migrations.rs | 6 +
.../src/migrations/m_2026_08_17/settings.rs | 32 ++++++
crates/migrator/src/migrator.rs | 59 ++++++++++
.../src/outline_panel_settings.rs | 6 +-
.../src/project_panel_settings.rs | 11 +-
crates/settings/src/content_into_gpui.rs | 10 +-
crates/settings_content/src/agent.rs | 9 +-
crates/settings_content/src/editor.rs | 31 ++++-
.../settings_content/src/settings_content.rs | 44 +++++--
crates/settings_content/src/terminal.rs | 6 +-
crates/settings_content/src/workspace.rs | 9 +-
.../src/components/number_field.rs | 3 +-
crates/settings_ui/src/page_data.rs | 107 ++++++++++++++----
crates/settings_ui/src/settings_ui.rs | 2 +
crates/terminal/src/terminal_settings.rs | 6 +-
crates/workspace/src/workspace_settings.rs | 2 +-
docs/src/reference/all-settings.md | 4 +-
25 files changed, 307 insertions(+), 96 deletions(-)
create mode 100644 crates/migrator/src/migrations/m_2026_08_17/settings.rs
diff --git a/Cargo.toml b/Cargo.toml
index b49e6de2314..b8d3b8df741 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -598,6 +598,7 @@ derive_more = { version = "2.1.1", features = [
"deref",
"deref_mut",
"display",
+ "from",
"from_str",
"mul",
"mul_assign",
diff --git a/assets/settings/default.json b/assets/settings/default.json
index 40e4c325de8..7e71a8cb0ac 100644
--- a/assets/settings/default.json
+++ b/assets/settings/default.json
@@ -703,9 +703,9 @@
"folds": true,
// Minimum number of characters to reserve space for in the gutter.
"min_line_number_digits": 4,
- // The width, in pixels, of the git diff hunk indicators in the gutter.
- // When set to null, the width scales with the buffer font size.
- "git_gutter_width": null,
+ // The width of the git diff hunk indicators in the gutter.
+ // Use "default" to scale with font size, or {"custom": } for a fixed width.
+ "git_gutter_width": "default",
},
"indent_guides": {
// Whether to show indent guides in the editor.
diff --git a/crates/agent_settings/src/agent_settings.rs b/crates/agent_settings/src/agent_settings.rs
index b30751f5db3..875b8fef456 100644
--- a/crates/agent_settings/src/agent_settings.rs
+++ b/crates/agent_settings/src/agent_settings.rs
@@ -10,13 +10,13 @@ use anyhow::Context as _;
use collections::{HashSet, IndexMap};
use fs::Fs;
use futures::channel::oneshot;
-use gpui::{App, Pixels, SharedString, px};
+use gpui::{App, Pixels, SharedString};
use language_model::LanguageModel;
use project::DisableAiSettings;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{
- DockPosition, DockSide, LanguageModelParameters, LanguageModelSelection,
+ DockPosition, DockSide, IntoGpui, LanguageModelParameters, LanguageModelSelection,
NotifyWhenAgentWaiting, PlaySoundWhenAgentDone, RegisterSetting, Settings, SettingsContent,
SettingsStore, SidebarDockPosition, SidebarSide, ThinkingBlockDisplay, ToolPermissionMode,
update_settings_file, update_settings_file_with_completion,
@@ -759,10 +759,10 @@ impl Settings for AgentSettings {
button: agent.button.unwrap(),
dock: agent.dock.unwrap(),
sidebar_side: agent.sidebar_side.unwrap(),
- default_width: px(agent.default_width.unwrap()),
- default_height: px(agent.default_height.unwrap()),
+ default_width: agent.default_width.unwrap().into_gpui(),
+ default_height: agent.default_height.unwrap().into_gpui(),
max_content_width: if agent.limit_content_width.unwrap() {
- Some(px(agent.max_content_width.unwrap()))
+ Some(agent.max_content_width.unwrap().into_gpui())
} else {
None
},
diff --git a/crates/collab_ui/src/panel_settings.rs b/crates/collab_ui/src/panel_settings.rs
index 3d6de1015a3..aa84407b3fc 100644
--- a/crates/collab_ui/src/panel_settings.rs
+++ b/crates/collab_ui/src/panel_settings.rs
@@ -1,6 +1,5 @@
use gpui::Pixels;
-use settings::{RegisterSetting, Settings};
-use ui::px;
+use settings::{IntoGpui, RegisterSetting, Settings};
use workspace::dock::DockPosition;
#[derive(Debug, RegisterSetting)]
@@ -17,7 +16,7 @@ impl Settings for CollaborationPanelSettings {
Self {
button: panel.button.unwrap(),
dock: panel.dock.unwrap().into(),
- default_width: panel.default_width.map(px).unwrap(),
+ default_width: panel.default_width.unwrap().into_gpui(),
}
}
}
diff --git a/crates/editor/src/editor_settings.rs b/crates/editor/src/editor_settings.rs
index f6fdd6c16d2..394f24892f9 100644
--- a/crates/editor/src/editor_settings.rs
+++ b/crates/editor/src/editor_settings.rs
@@ -5,7 +5,7 @@ use language::CursorShape;
use project::project_settings::DiagnosticSeverity;
pub use settings::{
CodeLens, CompletionDetailAlignment, CompletionMenuItemKind, CurrentLineHighlight, DelayMs,
- DiffViewStyle, DisplayIn, DocumentColorsRenderMode, DoubleClickInMultibuffer,
+ DiffViewStyle, DisplayIn, DocumentColorsRenderMode, DoubleClickInMultibuffer, GitGutterWidth,
GoToDefinitionFallback, GoToDefinitionScrollStrategy, MinimapThumb, MinimapThumbBorder,
MultiCursorModifier, OpenResultsIn, ScrollBeyondLastLine, ScrollbarDiagnostics,
SeedQuerySetting, ShowMinimap, SnippetSortOrder,
@@ -149,7 +149,7 @@ pub struct Gutter {
pub breakpoints: bool,
pub bookmarks: bool,
pub folds: bool,
- pub git_gutter_width: Option,
+ pub git_gutter_width: settings::GitGutterWidth,
}
/// Forcefully enable or disable the scrollbar for each axis
@@ -268,7 +268,7 @@ impl Settings for EditorSettings {
bookmarks: gutter.bookmarks.unwrap(),
breakpoints: gutter.breakpoints.unwrap(),
folds: gutter.folds.unwrap(),
- git_gutter_width: gutter.git_gutter_width,
+ git_gutter_width: gutter.git_gutter_width.unwrap(),
},
scroll_beyond_last_line: editor.scroll_beyond_last_line.unwrap(),
vertical_scroll_margin: editor.vertical_scroll_margin.unwrap() as f64,
diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs
index 07e81acc821..ac32816a807 100644
--- a/crates/editor/src/element.rs
+++ b/crates/editor/src/element.rs
@@ -22,8 +22,8 @@ use crate::{
HighlightKey, HighlightedChunk, ToDisplayPoint,
},
editor_settings::{
- CurrentLineHighlight, DocumentColorsRenderMode, Minimap, MinimapThumb, MinimapThumbBorder,
- ScrollBeyondLastLine, ScrollbarAxes, ScrollbarDiagnostics, ShowMinimap,
+ CurrentLineHighlight, DocumentColorsRenderMode, GitGutterWidth, Minimap, MinimapThumb,
+ MinimapThumbBorder, ScrollBeyondLastLine, ScrollbarAxes, ScrollbarDiagnostics, ShowMinimap,
},
git::blame::{BlameRenderer, GitBlame, GlobalBlameRenderer},
hover_popover::{
@@ -5321,8 +5321,8 @@ impl EditorElement {
fn gutter_strip_width(line_height: Pixels, cx: &App) -> Pixels {
match EditorSettings::get_global(cx).gutter.git_gutter_width {
- Some(width) => px(width),
- None => (0.275 * line_height).floor(),
+ GitGutterWidth::Custom(width) => px(*width),
+ GitGutterWidth::Default => (0.275 * line_height).floor(),
}
}
@@ -5362,8 +5362,8 @@ impl EditorElement {
let end_y = start_y + line_height;
let width = match EditorSettings::get_global(cx).gutter.git_gutter_width {
- Some(width) => px(width),
- None => (0.35 * line_height).floor(),
+ GitGutterWidth::Custom(width) => px(*width),
+ GitGutterWidth::Default => (0.35 * line_height).floor(),
};
let highlight_origin = gutter_bounds.origin + point(px(0.), start_y);
let highlight_size = size(width, end_y - start_y);
diff --git a/crates/git_ui/src/git_panel_settings.rs b/crates/git_ui/src/git_panel_settings.rs
index 0dbde43cfb5..6027c85bdab 100644
--- a/crates/git_ui/src/git_panel_settings.rs
+++ b/crates/git_ui/src/git_panel_settings.rs
@@ -3,12 +3,10 @@ use gpui::Pixels;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use settings::{
- GitPanelClickBehavior, GitPanelGroupBy, GitPanelSortBy, RegisterSetting, Settings, StatusStyle,
-};
-use ui::{
- px,
- scrollbars::{ScrollbarVisibility, ShowScrollbar},
+ GitPanelClickBehavior, GitPanelGroupBy, GitPanelSortBy, IntoGpui, RegisterSetting, Settings,
+ StatusStyle,
};
+use ui::scrollbars::{ScrollbarVisibility, ShowScrollbar};
use workspace::dock::DockPosition;
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
@@ -63,7 +61,7 @@ impl Settings for GitPanelSettings {
Self {
button: git_panel.button.unwrap(),
dock: git_panel.dock.unwrap().into(),
- default_width: px(git_panel.default_width.unwrap()),
+ default_width: git_panel.default_width.unwrap().into_gpui(),
status_style: git_panel.status_style.unwrap(),
file_icons: git_panel.file_icons.unwrap(),
folder_icons: git_panel.folder_icons.unwrap(),
diff --git a/crates/markdown_preview/src/markdown_preview_settings.rs b/crates/markdown_preview/src/markdown_preview_settings.rs
index bb624ad2cb8..94bd4ab597b 100644
--- a/crates/markdown_preview/src/markdown_preview_settings.rs
+++ b/crates/markdown_preview/src/markdown_preview_settings.rs
@@ -1,5 +1,5 @@
-use gpui::{Pixels, px};
-use settings::{RegisterSetting, Settings};
+use gpui::Pixels;
+use settings::{IntoGpui, RegisterSetting, Settings};
/// The settings for the markdown preview.
#[derive(Clone, Copy, Debug, Default, RegisterSetting)]
@@ -13,7 +13,7 @@ impl Settings for MarkdownPreviewSettings {
fn from_settings(content: &settings::SettingsContent) -> Self {
let content = content.markdown_preview.clone().unwrap_or_default();
let max_width = if content.limit_content_width.unwrap_or(true) {
- content.max_width.map(px)
+ content.max_width.map(IntoGpui::into_gpui)
} else {
None
};
diff --git a/crates/migrator/src/migrations.rs b/crates/migrator/src/migrations.rs
index 394b26f57ab..48588baa576 100644
--- a/crates/migrator/src/migrations.rs
+++ b/crates/migrator/src/migrations.rs
@@ -364,3 +364,9 @@ pub(crate) mod m_2026_05_04 {
pub(crate) use settings::SETTINGS_PATTERNS;
}
+
+pub(crate) mod m_2026_08_17 {
+ mod settings;
+
+ pub(crate) use settings::make_git_gutter_width_an_enum;
+}
diff --git a/crates/migrator/src/migrations/m_2026_08_17/settings.rs b/crates/migrator/src/migrations/m_2026_08_17/settings.rs
new file mode 100644
index 00000000000..4ec41fba115
--- /dev/null
+++ b/crates/migrator/src/migrations/m_2026_08_17/settings.rs
@@ -0,0 +1,32 @@
+use anyhow::Result;
+use serde_json::Value;
+
+use crate::migrations::migrate_settings;
+
+pub fn make_git_gutter_width_an_enum(value: &mut Value) -> Result<()> {
+ migrate_settings(value, &mut migrate_one)
+}
+
+fn migrate_one(obj: &mut serde_json::Map) -> Result<()> {
+ let Some(gutter) = obj
+ .get_mut("gutter")
+ .and_then(|gutter| gutter.as_object_mut())
+ else {
+ return Ok(());
+ };
+
+ let Some(git_gutter_width) = gutter.get_mut("git_gutter_width") else {
+ return Ok(());
+ };
+
+ *git_gutter_width = match git_gutter_width {
+ Value::Number(n) => {
+ serde_json::json!({
+ "custom": n
+ })
+ }
+ _ => return Ok(()),
+ };
+
+ Ok(())
+}
diff --git a/crates/migrator/src/migrator.rs b/crates/migrator/src/migrator.rs
index e1b15d98ea5..7b2dc972d8a 100644
--- a/crates/migrator/src/migrator.rs
+++ b/crates/migrator/src/migrator.rs
@@ -257,6 +257,7 @@ pub fn migrate_settings(text: &str) -> Result