From 7d7e67a20a541d4061e38c34ccf3459afb9907cd Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Wed, 17 Sep 2025 00:47:53 -0600 Subject: [PATCH] WIP --- crates/git_ui/src/branch_picker.rs | 1 - crates/git_ui/src/git_panel.rs | 13 ++- crates/git_ui/src/git_panel_settings.rs | 121 ++++++++++-------------- crates/settings/src/settings_content.rs | 56 +++++++++++ crates/workspace/src/dock.rs | 10 ++ 5 files changed, 121 insertions(+), 80 deletions(-) diff --git a/crates/git_ui/src/branch_picker.rs b/crates/git_ui/src/branch_picker.rs index 42558b7b79bca1892b9d36ae4b39bb3cdb196d4f..f425af646d6c38227bb82b3185ab7b0192fdea6c 100644 --- a/crates/git_ui/src/branch_picker.rs +++ b/crates/git_ui/src/branch_picker.rs @@ -556,7 +556,6 @@ impl PickerDelegate for BranchListDelegate { let show_author_name = ProjectSettings::get_global(cx) .git .branch_picker - .unwrap_or_default() .show_author_name; subject.map_or("no commits found".into(), |subject| { diff --git a/crates/git_ui/src/git_panel.rs b/crates/git_ui/src/git_panel.rs index 3063206723021d00aa21e0f8163b4fe3b941fcb7..4f626ee7e83b89ab863cdcadcb0a32471905c4c7 100644 --- a/crates/git_ui/src/git_panel.rs +++ b/crates/git_ui/src/git_panel.rs @@ -2439,8 +2439,9 @@ impl GitPanel { let workspace = workspace.read(cx); let fs = workspace.app_state().fs.clone(); cx.update_global::(|store, _cx| { - store.update_settings_file::(fs, move |settings, _cx| { - settings.sort_by_path = Some(!current_setting); + store.update_settings_file(fs, move |settings, _cx| { + settings.git_panel.get_or_insert_default().sort_by_path = + Some(!current_setting); }); }); } @@ -4353,11 +4354,9 @@ impl Panel for GitPanel { } fn set_position(&mut self, position: DockPosition, _: &mut Window, cx: &mut Context) { - settings::update_settings_file::( - self.fs.clone(), - cx, - move |settings, _| settings.dock = Some(position), - ); + settings::update_settings_file(self.fs.clone(), cx, move |settings, _| { + settings.git_panel.get_or_insert_default().dock = Some(position.into()) + }); } fn size(&self, _: &Window, cx: &App) -> Pixels { diff --git a/crates/git_ui/src/git_panel_settings.rs b/crates/git_ui/src/git_panel_settings.rs index be26061b0d2cbeee9a0a75f52daf56fb9fcb94f4..9b389945b90fbae5e2ada0a64ee7b3d463c98a5f 100644 --- a/crates/git_ui/src/git_panel_settings.rs +++ b/crates/git_ui/src/git_panel_settings.rs @@ -2,8 +2,12 @@ use editor::EditorSettings; use gpui::Pixels; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use settings::{Settings, SettingsKey, SettingsSources, SettingsUi}; -use ui::scrollbars::{ScrollbarVisibility, ShowScrollbar}; +use settings::{Settings, SettingsContent, SettingsKey, SettingsSources, SettingsUi, StatusStyle}; +use ui::{ + px, + scrollbars::{ScrollbarVisibility, ShowScrollbar}, +}; +use util::MergeFrom; use workspace::dock::DockPosition; #[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] @@ -19,67 +23,7 @@ pub struct ScrollbarSettings { pub show: Option, } -#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] -#[serde(rename_all = "snake_case")] -// Style of the git status indicator in the panel. -// -// Default: icon -pub enum StatusStyleContent { - Icon, - LabelColor, -} - -#[derive(Default, Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] -#[serde(rename_all = "snake_case")] -pub enum StatusStyle { - #[default] - Icon, - LabelColor, -} - -#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug, SettingsUi, SettingsKey)] -#[settings_key(key = "git_panel")] -pub struct GitPanelSettingsContent { - /// Whether to show the panel button in the status bar. - /// - /// Default: true - pub button: Option, - /// Where to dock the panel. - /// - /// Default: left - pub dock: Option, - /// Default width of the panel in pixels. - /// - /// Default: 360 - pub default_width: Option, - /// How entry statuses are displayed. - /// - /// Default: icon - pub status_style: Option, - /// How and when the scrollbar should be displayed. - /// - /// Default: inherits editor scrollbar settings - pub scrollbar: Option, - - /// What the default branch name should be when - /// `init.defaultBranch` is not set in git - /// - /// Default: main - pub fallback_branch_name: Option, - - /// Whether to sort entries in the panel by path - /// or by status (the default). - /// - /// Default: false - pub sort_by_path: Option, - - /// Whether to collapse untracked files in the diff panel. - /// - /// Default: false - pub collapse_untracked_diff: Option, -} - -#[derive(Deserialize, Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq)] pub struct GitPanelSettings { pub button: bool, pub dock: DockPosition, @@ -108,17 +52,50 @@ impl ScrollbarVisibility for GitPanelSettings { } impl Settings for GitPanelSettings { - type FileContent = GitPanelSettingsContent; + fn from_defaults(content: &settings::SettingsContent, _cx: &mut ui::App) -> Self { + let git_panel = content.git_panel.clone().unwrap(); + Self { + button: git_panel.button.unwrap(), + dock: git_panel.dock.unwrap().into(), + default_width: px(git_panel.default_width.unwrap()), + status_style: git_panel.status_style.unwrap(), + scrollbar: ScrollbarSettings { + show: git_panel.scrollbar.unwrap().show.map(Into::into), + }, + fallback_branch_name: git_panel.fallback_branch_name.unwrap(), + sort_by_path: git_panel.sort_by_path.unwrap(), + collapse_untracked_diff: git_panel.collapse_untracked_diff.unwrap(), + } + } - fn load( - sources: SettingsSources, - _: &mut gpui::App, - ) -> anyhow::Result { - sources.json_merge() + fn refine(&mut self, content: &settings::SettingsContent, _cx: &mut ui::App) { + let Some(git_panel) = &content.git_panel else { + return; + }; + self.button.merge_from(&git_panel.button); + self.dock.merge_from(&git_panel.dock.map(Into::into)); + self.default_width + .merge_from(&git_panel.default_width.map(px)); + self.status_style.merge_from(&git_panel.status_style); + self.fallback_branch_name + .merge_from(&git_panel.fallback_branch_name); + self.sort_by_path.merge_from(&git_panel.sort_by_path); + self.collapse_untracked_diff + .merge_from(&git_panel.collapse_untracked_diff); + if let Some(show) = git_panel.scrollbar.as_ref().and_then(|s| s.show) { + self.scrollbar.show = Some(show.into()) + } } - fn import_from_vscode(vscode: &settings::VsCodeSettings, current: &mut Self::FileContent) { - vscode.bool_setting("git.enabled", &mut current.button); - vscode.string_setting("git.defaultBranchName", &mut current.fallback_branch_name); + fn import_from_vscode(vscode: &settings::VsCodeSettings, current: &mut SettingsContent) { + if let Some(git_enabled) = vscode.read_bool("git.enabled") { + current.git_panel.get_or_insert_default().button = Some(git_enabled); + } + if let Some(default_branch) = vscode.read_string("git.defaultBranchName") { + current + .git_panel + .get_or_insert_default() + .fallback_branch_name = Some(default_branch.to_string()); + } } } diff --git a/crates/settings/src/settings_content.rs b/crates/settings/src/settings_content.rs index c01253d8b98884b430a44b194416c2d9c07279b3..8d0d99b49ed9e53a30490ee6c01a425b4ac98ba9 100644 --- a/crates/settings/src/settings_content.rs +++ b/crates/settings/src/settings_content.rs @@ -41,6 +41,8 @@ pub struct SettingsContent { #[serde(flatten)] pub editor: EditorSettingsContent, + pub git_panel: Option, + pub tabs: Option, pub tab_bar: Option, @@ -364,3 +366,57 @@ pub struct ExtensionSettingsContent { #[serde(default)] pub auto_update_extensions: HashMap, bool>, } + +#[derive(Clone, PartialEq, Default, Serialize, Deserialize, JsonSchema, Debug)] +pub struct GitPanelSettingsContent { + /// Whether to show the panel button in the status bar. + /// + /// Default: true + pub button: Option, + /// Where to dock the panel. + /// + /// Default: left + pub dock: Option, + /// Default width of the panel in pixels. + /// + /// Default: 360 + pub default_width: Option, + /// How entry statuses are displayed. + /// + /// Default: icon + pub status_style: Option, + /// How and when the scrollbar should be displayed. + /// + /// Default: inherits editor scrollbar settings + pub scrollbar: Option, + + /// What the default branch name should be when + /// `init.defaultBranch` is not set in git + /// + /// Default: main + pub fallback_branch_name: Option, + + /// Whether to sort entries in the panel by path + /// or by status (the default). + /// + /// Default: false + pub sort_by_path: Option, + + /// Whether to collapse untracked files in the diff panel. + /// + /// Default: false + pub collapse_untracked_diff: Option, +} + +#[derive(Default, Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] +#[serde(rename_all = "snake_case")] +pub enum StatusStyle { + #[default] + Icon, + LabelColor, +} + +#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)] +pub struct ScrollbarSettings { + pub show: Option, +} diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index 09fa6f068f92dda29beac98eff0dcf41e93dc1bf..ec33b9af59c2cb070866c0a1c4a5b8670a8d58e6 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -225,6 +225,16 @@ impl From for DockPosition { } } +impl Into for DockPosition { + fn into(self) -> settings::DockPosition { + match self { + Self::Left => settings::DockPosition::Left, + Self::Bottom => settings::DockPosition::Bottom, + Self::Right => settings::DockPosition::Right, + } + } +} + impl DockPosition { fn label(&self) -> &'static str { match self {