Highlight file finder entries according to their git status (#31469)
Configure this with the ```json5 "file_finder": { "git_status": true } ``` settings value. Before: <img width="864" alt="before" src="https://github.com/user-attachments/assets/5943e30f-1105-445e-9398-ea6dd35877c8" /> After: <img width="864" alt="image" src="https://github.com/user-attachments/assets/56b2fad6-8cdc-4f28-b238-920745231b1f" /> After with search matches: <img width="577" alt="image" src="https://github.com/user-attachments/assets/8c414575-7daf-43a8-89c2-98137d52b7a0" /> Release Notes: - Start highlighting file finder entries according to their git status
This commit is contained in:
parent
24809c4219
commit
e84463648a
3 changed files with 54 additions and 10 deletions
|
@ -954,7 +954,9 @@
|
||||||
// "skip_focus_for_active_in_search": false
|
// "skip_focus_for_active_in_search": false
|
||||||
//
|
//
|
||||||
// Default: true
|
// Default: true
|
||||||
"skip_focus_for_active_in_search": true
|
"skip_focus_for_active_in_search": true,
|
||||||
|
// Whether to show the git status in the file finder.
|
||||||
|
"git_status": true
|
||||||
},
|
},
|
||||||
// Whether or not to remove any trailing whitespace from lines of a buffer
|
// Whether or not to remove any trailing whitespace from lines of a buffer
|
||||||
// before saving it.
|
// before saving it.
|
||||||
|
|
|
@ -11,7 +11,7 @@ use futures::future::join_all;
|
||||||
pub use open_path_prompt::OpenPathDelegate;
|
pub use open_path_prompt::OpenPathDelegate;
|
||||||
|
|
||||||
use collections::HashMap;
|
use collections::HashMap;
|
||||||
use editor::Editor;
|
use editor::{Editor, items::entry_git_aware_label_color};
|
||||||
use file_finder_settings::{FileFinderSettings, FileFinderWidth};
|
use file_finder_settings::{FileFinderSettings, FileFinderWidth};
|
||||||
use file_icons::FileIcons;
|
use file_icons::FileIcons;
|
||||||
use fuzzy::{CharBag, PathMatch, PathMatchCandidate};
|
use fuzzy::{CharBag, PathMatch, PathMatchCandidate};
|
||||||
|
@ -1418,23 +1418,58 @@ impl PickerDelegate for FileFinderDelegate {
|
||||||
cx: &mut Context<Picker<Self>>,
|
cx: &mut Context<Picker<Self>>,
|
||||||
) -> Option<Self::ListItem> {
|
) -> Option<Self::ListItem> {
|
||||||
let settings = FileFinderSettings::get_global(cx);
|
let settings = FileFinderSettings::get_global(cx);
|
||||||
|
let path_match = self.matches.get(ix)?;
|
||||||
|
|
||||||
let path_match = self
|
let git_status_color = if settings.git_status {
|
||||||
.matches
|
let (entry, project_path) = match path_match {
|
||||||
.get(ix)
|
Match::History { path, .. } => {
|
||||||
.expect("Invalid matches state: no element for index {ix}");
|
let project = self.project.read(cx);
|
||||||
|
let project_path = path.project.clone();
|
||||||
|
let entry = project.entry_for_path(&project_path, cx)?;
|
||||||
|
Some((entry, project_path))
|
||||||
|
}
|
||||||
|
Match::Search(mat) => {
|
||||||
|
let project = self.project.read(cx);
|
||||||
|
let project_path = ProjectPath {
|
||||||
|
worktree_id: WorktreeId::from_usize(mat.0.worktree_id),
|
||||||
|
path: mat.0.path.clone(),
|
||||||
|
};
|
||||||
|
let entry = project.entry_for_path(&project_path, cx)?;
|
||||||
|
Some((entry, project_path))
|
||||||
|
}
|
||||||
|
}?;
|
||||||
|
|
||||||
let history_icon = match &path_match {
|
let git_status = self
|
||||||
|
.project
|
||||||
|
.read(cx)
|
||||||
|
.project_path_git_status(&project_path, cx)
|
||||||
|
.map(|status| status.summary())
|
||||||
|
.unwrap_or_default();
|
||||||
|
Some(entry_git_aware_label_color(
|
||||||
|
git_status,
|
||||||
|
entry.is_ignored,
|
||||||
|
selected,
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let history_icon = match path_match {
|
||||||
Match::History { .. } => Icon::new(IconName::HistoryRerun)
|
Match::History { .. } => Icon::new(IconName::HistoryRerun)
|
||||||
.color(Color::Muted)
|
|
||||||
.size(IconSize::Small)
|
.size(IconSize::Small)
|
||||||
|
.color(Color::Muted)
|
||||||
.into_any_element(),
|
.into_any_element(),
|
||||||
Match::Search(_) => v_flex()
|
Match::Search(_) => v_flex()
|
||||||
.flex_none()
|
.flex_none()
|
||||||
.size(IconSize::Small.rems())
|
.size(IconSize::Small.rems())
|
||||||
.into_any_element(),
|
.into_any_element(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let (file_name_label, full_path_label) = self.labels_for_match(path_match, window, cx, ix);
|
let (file_name_label, full_path_label) = self.labels_for_match(path_match, window, cx, ix);
|
||||||
|
let file_name_label = match git_status_color {
|
||||||
|
Some(git_status_color) => file_name_label.color(git_status_color),
|
||||||
|
None => file_name_label,
|
||||||
|
};
|
||||||
|
|
||||||
let file_icon = maybe!({
|
let file_icon = maybe!({
|
||||||
if !settings.file_icons {
|
if !settings.file_icons {
|
||||||
|
@ -1442,7 +1477,7 @@ impl PickerDelegate for FileFinderDelegate {
|
||||||
}
|
}
|
||||||
let file_name = path_match.path().file_name()?;
|
let file_name = path_match.path().file_name()?;
|
||||||
let icon = FileIcons::get_icon(file_name.as_ref(), cx)?;
|
let icon = FileIcons::get_icon(file_name.as_ref(), cx)?;
|
||||||
Some(Icon::from_path(icon).color(Color::Muted))
|
Some(Icon::from_path(icon).color(git_status_color.unwrap_or(Color::Muted)))
|
||||||
});
|
});
|
||||||
|
|
||||||
Some(
|
Some(
|
||||||
|
|
|
@ -8,6 +8,7 @@ pub struct FileFinderSettings {
|
||||||
pub file_icons: bool,
|
pub file_icons: bool,
|
||||||
pub modal_max_width: Option<FileFinderWidth>,
|
pub modal_max_width: Option<FileFinderWidth>,
|
||||||
pub skip_focus_for_active_in_search: bool,
|
pub skip_focus_for_active_in_search: bool,
|
||||||
|
pub git_status: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug)]
|
#[derive(Clone, Default, Serialize, Deserialize, JsonSchema, Debug)]
|
||||||
|
@ -24,6 +25,10 @@ pub struct FileFinderSettingsContent {
|
||||||
///
|
///
|
||||||
/// Default: true
|
/// Default: true
|
||||||
pub skip_focus_for_active_in_search: Option<bool>,
|
pub skip_focus_for_active_in_search: Option<bool>,
|
||||||
|
/// Determines whether to show the git status in the file finder
|
||||||
|
///
|
||||||
|
/// Default: true
|
||||||
|
pub git_status: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Settings for FileFinderSettings {
|
impl Settings for FileFinderSettings {
|
||||||
|
@ -35,7 +40,9 @@ impl Settings for FileFinderSettings {
|
||||||
sources.json_merge()
|
sources.json_merge()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import_from_vscode(_vscode: &settings::VsCodeSettings, _current: &mut Self::FileContent) {}
|
fn import_from_vscode(vscode: &settings::VsCodeSettings, current: &mut Self::FileContent) {
|
||||||
|
vscode.bool_setting("git.decorations.enabled", &mut current.git_status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Default, Serialize, Deserialize, JsonSchema)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy, Default, Serialize, Deserialize, JsonSchema)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue