mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
project_panel: Add Git status indicators (#50216)
This PR adds Git status badges next to file names in the Project Panel, following my older PR #49802 These are enabled by having "git_status" true. Screenshot <img width="343" height="320" alt="image" src="https://github.com/user-attachments/assets/b2c208bf-5027-4947-a5ee-eeb74fadb02b" /> I'd love to hear feedback about any of this :) Especially feedback on these: - File name colour is determined only by Git status, the diagnostic badges remain separate. Should diagnostics also affect the filename colour? - (Unstaged) Modified files and staged modifications share the same colour, in vscode staged modifications use a brownish colour by default which I could not find the colours. I think differentiating them is definetely something to add. Release Notes - Added git status indicators in Project Panel. It can be enabled by setting `git_status_indicator` to `true` in `project_panel` settings. --------- Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
This commit is contained in:
parent
9f58770392
commit
9973a349a4
6 changed files with 83 additions and 7 deletions
|
|
@ -782,6 +782,8 @@
|
|||
"sort_mode": "directories_first",
|
||||
// Whether to show error and warning count badges next to file names in the project panel.
|
||||
"diagnostic_badges": false,
|
||||
// Whether to show the git status indicator next to file names in the project panel.
|
||||
"git_status_indicator": false,
|
||||
// Whether to enable drag-and-drop operations in the project panel.
|
||||
"drag_and_drop": true,
|
||||
// Whether to hide the root entry when only one folder is open in the window;
|
||||
|
|
|
|||
|
|
@ -61,9 +61,9 @@ use std::{
|
|||
use theme::ThemeSettings;
|
||||
use ui::{
|
||||
Color, ContextMenu, ContextMenuEntry, DecoratedIcon, Divider, Icon, IconDecoration,
|
||||
IconDecorationKind, IndentGuideColors, IndentGuideLayout, KeyBinding, Label, LabelSize,
|
||||
ListItem, ListItemSpacing, ScrollAxes, ScrollableHandle, Scrollbars, StickyCandidate, Tooltip,
|
||||
WithScrollbar, prelude::*, v_flex,
|
||||
IconDecorationKind, IndentGuideColors, IndentGuideLayout, Indicator, KeyBinding, Label,
|
||||
LabelSize, ListItem, ListItemSpacing, ScrollAxes, ScrollableHandle, Scrollbars,
|
||||
StickyCandidate, Tooltip, WithScrollbar, prelude::*, v_flex,
|
||||
};
|
||||
use util::{
|
||||
ResultExt, TakeUntilExt, TryFutureExt, maybe,
|
||||
|
|
@ -5352,6 +5352,10 @@ impl ProjectPanel {
|
|||
false
|
||||
}
|
||||
};
|
||||
let git_indicator = settings
|
||||
.git_status_indicator
|
||||
.then(|| git_status_indicator(details.git_status))
|
||||
.flatten();
|
||||
|
||||
let id: ElementId = if is_sticky {
|
||||
SharedString::from(format!("project_panel_sticky_item_{}", entry_id.to_usize())).into()
|
||||
|
|
@ -5696,7 +5700,9 @@ impl ProjectPanel {
|
|||
})
|
||||
.selectable(false)
|
||||
.when(
|
||||
canonical_path.is_some() || diagnostic_count.is_some(),
|
||||
canonical_path.is_some()
|
||||
|| diagnostic_count.is_some()
|
||||
|| git_indicator.is_some(),
|
||||
|this| {
|
||||
let symlink_element = canonical_path.map(|path| {
|
||||
div()
|
||||
|
|
@ -5739,6 +5745,20 @@ impl ProjectPanel {
|
|||
},
|
||||
)
|
||||
})
|
||||
.when_some(git_indicator, |this, (label, color)| {
|
||||
let git_indicator = if kind.is_dir() {
|
||||
Indicator::dot()
|
||||
.color(Color::Custom(color.color(cx).opacity(0.5)))
|
||||
.into_any_element()
|
||||
} else {
|
||||
Label::new(label)
|
||||
.size(LabelSize::Small)
|
||||
.color(color)
|
||||
.into_any_element()
|
||||
};
|
||||
|
||||
this.child(git_indicator)
|
||||
})
|
||||
.when_some(symlink_element, |this, el| this.child(el))
|
||||
.into_any_element(),
|
||||
)
|
||||
|
|
@ -7286,5 +7306,30 @@ pub fn par_sort_worktree_entries_with_mode(
|
|||
entries.par_sort_by(|lhs, rhs| cmp_with_mode(lhs, rhs, &mode));
|
||||
}
|
||||
|
||||
fn git_status_indicator(git_status: GitSummary) -> Option<(&'static str, Color)> {
|
||||
if git_status.conflict > 0 {
|
||||
return Some(("!", Color::Conflict));
|
||||
}
|
||||
if git_status.untracked > 0 {
|
||||
return Some(("U", Color::Created));
|
||||
}
|
||||
if git_status.worktree.deleted > 0 {
|
||||
return Some(("D", Color::Deleted));
|
||||
}
|
||||
if git_status.worktree.modified > 0 {
|
||||
return Some(("M", Color::Warning));
|
||||
}
|
||||
if git_status.index.deleted > 0 {
|
||||
return Some(("D", Color::Deleted));
|
||||
}
|
||||
if git_status.index.modified > 0 {
|
||||
return Some(("M", Color::Modified));
|
||||
}
|
||||
if git_status.index.added > 0 {
|
||||
return Some(("A", Color::Created));
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod project_panel_tests;
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ pub struct ProjectPanelSettings {
|
|||
pub auto_open: AutoOpenSettings,
|
||||
pub sort_mode: ProjectPanelSortMode,
|
||||
pub diagnostic_badges: bool,
|
||||
pub git_status_indicator: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
|
|
@ -137,6 +138,7 @@ impl Settings for ProjectPanelSettings {
|
|||
},
|
||||
sort_mode: project_panel.sort_mode.unwrap(),
|
||||
diagnostic_badges: project_panel.diagnostic_badges.unwrap(),
|
||||
git_status_indicator: project_panel.git_status_indicator.unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -808,6 +808,7 @@ impl VsCodeSettings {
|
|||
sticky_scroll: None,
|
||||
auto_open: None,
|
||||
diagnostic_badges: None,
|
||||
git_status_indicator: None,
|
||||
};
|
||||
|
||||
if let (Some(false), Some(false)) = (
|
||||
|
|
|
|||
|
|
@ -741,8 +741,12 @@ pub struct ProjectPanelSettingsContent {
|
|||
pub sort_mode: Option<ProjectPanelSortMode>,
|
||||
/// Whether to show error and warning count badges next to file names in the project panel.
|
||||
///
|
||||
/// Default: true
|
||||
/// Default: false
|
||||
pub diagnostic_badges: Option<bool>,
|
||||
/// Whether to show a git status indicator next to file names in the project panel.
|
||||
///
|
||||
/// Default: false
|
||||
pub git_status_indicator: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
|
|
|
|||
|
|
@ -4349,7 +4349,7 @@ fn window_and_layout_page() -> SettingsPage {
|
|||
}
|
||||
|
||||
fn panels_page() -> SettingsPage {
|
||||
fn project_panel_section() -> [SettingsPageItem; 23] {
|
||||
fn project_panel_section() -> [SettingsPageItem; 24] {
|
||||
[
|
||||
SettingsPageItem::SectionHeader("Project Panel"),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
|
|
@ -4697,6 +4697,28 @@ fn panels_page() -> SettingsPage {
|
|||
metadata: None,
|
||||
files: USER,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Git Status Indicator",
|
||||
description: "Show a git status indicator next to file names in the project panel.",
|
||||
field: Box::new(SettingField {
|
||||
json_path: Some("project_panel.git_status_indicator"),
|
||||
pick: |settings_content| {
|
||||
settings_content
|
||||
.project_panel
|
||||
.as_ref()?
|
||||
.git_status_indicator
|
||||
.as_ref()
|
||||
},
|
||||
write: |settings_content, value| {
|
||||
settings_content
|
||||
.project_panel
|
||||
.get_or_insert_default()
|
||||
.git_status_indicator = value;
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
files: USER,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Sticky Scroll",
|
||||
description: "Whether to stick parent directories at top of the project panel.",
|
||||
|
|
@ -4771,7 +4793,7 @@ fn panels_page() -> SettingsPage {
|
|||
title: "Hide Root",
|
||||
description: "Whether to hide the root entry when only one folder is open in the window.",
|
||||
field: Box::new(SettingField {
|
||||
json_path: Some("project_panel.drag_and_drop"),
|
||||
json_path: Some("project_panel.hide_root"),
|
||||
pick: |settings_content| {
|
||||
settings_content.project_panel.as_ref()?.hide_root.as_ref()
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue