Improve readability of files in the git changes panel (#41857)
Closes _unknown_ <img width="1212" height="463" alt="image" src="https://github.com/user-attachments/assets/ec00fcf0-7eb9-4291-b1e2-66e014dc30ac" /> This PR places the file_name before the file_path so that when the panel is slim it is still usable, mirrors the behaviour of the file picker (cmd+P) Release Notes: - Improved readability of files in the git changes panel
This commit is contained in:
@@ -1316,7 +1316,10 @@
|
||||
// "hunk_style": "staged_hollow"
|
||||
// 2. Show unstaged hunks hollow and staged hunks filled:
|
||||
// "hunk_style": "unstaged_hollow"
|
||||
"hunk_style": "staged_hollow"
|
||||
"hunk_style": "staged_hollow",
|
||||
// Should the name or path be displayed first in the git view.
|
||||
// "path_style": "file_name_first" or "file_path_first"
|
||||
"path_style": "file_name_first"
|
||||
},
|
||||
// The list of custom Git hosting providers.
|
||||
"git_hosting_providers": [
|
||||
|
||||
@@ -51,6 +51,7 @@ use panel::{
|
||||
use project::{
|
||||
Fs, Project, ProjectPath,
|
||||
git_store::{GitStoreEvent, Repository, RepositoryEvent, RepositoryId, pending_op},
|
||||
project_settings::{GitPathStyle, ProjectSettings},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use settings::{Settings, SettingsStore, StatusStyle};
|
||||
@@ -3954,6 +3955,7 @@ impl GitPanel {
|
||||
cx: &Context<Self>,
|
||||
) -> AnyElement {
|
||||
let path_style = self.project.read(cx).path_style(cx);
|
||||
let git_path_style = ProjectSettings::get_global(cx).git.path_style;
|
||||
let display_name = entry.display_name(path_style);
|
||||
|
||||
let selected = self.selected_entry == Some(ix);
|
||||
@@ -4053,7 +4055,6 @@ impl GitPanel {
|
||||
} else {
|
||||
cx.theme().colors().ghost_element_active
|
||||
};
|
||||
|
||||
h_flex()
|
||||
.id(id)
|
||||
.h(self.list_item_height())
|
||||
@@ -4151,28 +4152,70 @@ impl GitPanel {
|
||||
h_flex()
|
||||
.items_center()
|
||||
.flex_1()
|
||||
// .overflow_hidden()
|
||||
.when_some(entry.parent_dir(path_style), |this, parent| {
|
||||
if !parent.is_empty() {
|
||||
this.child(
|
||||
self.entry_label(
|
||||
format!("{parent}{}", path_style.separator()),
|
||||
path_color,
|
||||
)
|
||||
.when(status.is_deleted(), |this| this.strikethrough()),
|
||||
)
|
||||
} else {
|
||||
this
|
||||
}
|
||||
})
|
||||
.child(
|
||||
self.entry_label(display_name, label_color)
|
||||
.when(status.is_deleted(), |this| this.strikethrough()),
|
||||
),
|
||||
.child(h_flex().items_center().flex_1().map(|this| {
|
||||
self.path_formatted(
|
||||
this,
|
||||
entry.parent_dir(path_style),
|
||||
path_color,
|
||||
display_name,
|
||||
label_color,
|
||||
path_style,
|
||||
git_path_style,
|
||||
status.is_deleted(),
|
||||
)
|
||||
})),
|
||||
)
|
||||
.into_any_element()
|
||||
}
|
||||
|
||||
fn path_formatted(
|
||||
&self,
|
||||
parent: Div,
|
||||
directory: Option<String>,
|
||||
path_color: Color,
|
||||
file_name: String,
|
||||
label_color: Color,
|
||||
path_style: PathStyle,
|
||||
git_path_style: GitPathStyle,
|
||||
strikethrough: bool,
|
||||
) -> Div {
|
||||
parent
|
||||
.when(git_path_style == GitPathStyle::FileNameFirst, |this| {
|
||||
this.child(
|
||||
self.entry_label(
|
||||
match directory.as_ref().is_none_or(|d| d.is_empty()) {
|
||||
true => file_name.clone(),
|
||||
false => format!("{file_name} "),
|
||||
},
|
||||
label_color,
|
||||
)
|
||||
.when(strikethrough, Label::strikethrough),
|
||||
)
|
||||
})
|
||||
.when_some(directory, |this, dir| {
|
||||
match (
|
||||
!dir.is_empty(),
|
||||
git_path_style == GitPathStyle::FileNameFirst,
|
||||
) {
|
||||
(true, true) => this.child(
|
||||
self.entry_label(dir, path_color)
|
||||
.when(strikethrough, Label::strikethrough),
|
||||
),
|
||||
(true, false) => this.child(
|
||||
self.entry_label(format!("{dir}{}", path_style.separator()), path_color)
|
||||
.when(strikethrough, Label::strikethrough),
|
||||
),
|
||||
_ => this,
|
||||
}
|
||||
})
|
||||
.when(git_path_style == GitPathStyle::FilePathFirst, |this| {
|
||||
this.child(
|
||||
self.entry_label(file_name, label_color)
|
||||
.when(strikethrough, Label::strikethrough),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn has_write_access(&self, cx: &App) -> bool {
|
||||
!self.project.read(cx).is_read_only(cx)
|
||||
}
|
||||
|
||||
@@ -348,6 +348,26 @@ pub struct GitSettings {
|
||||
///
|
||||
/// Default: staged_hollow
|
||||
pub hunk_style: settings::GitHunkStyleSetting,
|
||||
/// How file paths are displayed in the git gutter.
|
||||
///
|
||||
/// Default: file_name_first
|
||||
pub path_style: GitPathStyle,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Default)]
|
||||
pub enum GitPathStyle {
|
||||
#[default]
|
||||
FileNameFirst,
|
||||
FilePathFirst,
|
||||
}
|
||||
|
||||
impl From<settings::GitPathStyle> for GitPathStyle {
|
||||
fn from(style: settings::GitPathStyle) -> Self {
|
||||
match style {
|
||||
settings::GitPathStyle::FileNameFirst => GitPathStyle::FileNameFirst,
|
||||
settings::GitPathStyle::FilePathFirst => GitPathStyle::FilePathFirst,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
@@ -501,6 +521,7 @@ impl Settings for ProjectSettings {
|
||||
}
|
||||
},
|
||||
hunk_style: git.hunk_style.unwrap(),
|
||||
path_style: git.path_style.unwrap().into(),
|
||||
};
|
||||
Self {
|
||||
context_servers: project
|
||||
|
||||
@@ -311,6 +311,10 @@ pub struct GitSettings {
|
||||
///
|
||||
/// Default: staged_hollow
|
||||
pub hunk_style: Option<GitHunkStyleSetting>,
|
||||
/// How file paths are displayed in the git gutter.
|
||||
///
|
||||
/// Default: file_name_first
|
||||
pub path_style: Option<GitPathStyle>,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
@@ -406,6 +410,28 @@ pub enum GitHunkStyleSetting {
|
||||
UnstagedHollow,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Copy,
|
||||
Clone,
|
||||
Debug,
|
||||
PartialEq,
|
||||
Default,
|
||||
Serialize,
|
||||
Deserialize,
|
||||
JsonSchema,
|
||||
MergeFrom,
|
||||
strum::VariantArray,
|
||||
strum::VariantNames,
|
||||
)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum GitPathStyle {
|
||||
/// Show file name first, then path
|
||||
#[default]
|
||||
FileNameFirst,
|
||||
/// Show full path first
|
||||
FilePathFirst,
|
||||
}
|
||||
|
||||
#[skip_serializing_none]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize, JsonSchema, MergeFrom)]
|
||||
pub struct DiagnosticsSettingsContent {
|
||||
|
||||
@@ -5494,6 +5494,19 @@ pub(crate) fn settings_data(cx: &App) -> Vec<SettingsPage> {
|
||||
metadata: None,
|
||||
files: USER,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Path Style",
|
||||
description: "Should the name or path be displayed first in the git view.",
|
||||
field: Box::new(SettingField {
|
||||
json_path: Some("git.path_style"),
|
||||
pick: |settings_content| settings_content.git.as_ref()?.path_style.as_ref(),
|
||||
write: |settings_content, value| {
|
||||
settings_content.git.get_or_insert_default().path_style = value;
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
files: USER,
|
||||
}),
|
||||
],
|
||||
},
|
||||
SettingsPage {
|
||||
|
||||
@@ -452,6 +452,7 @@ fn init_renderers(cx: &mut App) {
|
||||
.add_basic_renderer::<settings::DockPosition>(render_dropdown)
|
||||
.add_basic_renderer::<settings::GitGutterSetting>(render_dropdown)
|
||||
.add_basic_renderer::<settings::GitHunkStyleSetting>(render_dropdown)
|
||||
.add_basic_renderer::<settings::GitPathStyle>(render_dropdown)
|
||||
.add_basic_renderer::<settings::DiagnosticSeverityContent>(render_dropdown)
|
||||
.add_basic_renderer::<settings::SeedQuerySetting>(render_dropdown)
|
||||
.add_basic_renderer::<settings::DoubleClickInMultibuffer>(render_dropdown)
|
||||
|
||||
Reference in New Issue
Block a user