Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion assets/settings/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,9 @@
// 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.
"hide_root": false
"hide_root": false,
// Whether to hide the hidden entries in the project panel.
"hide_hidden": false
},
"outline_panel": {
// Whether to show the outline panel button in the status bar
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ CREATE TABLE "worktree_entries" (
"is_external" BOOL NOT NULL,
"is_ignored" BOOL NOT NULL,
"is_deleted" BOOL NOT NULL,
"is_hidden" BOOL NOT NULL,
"git_status" INTEGER,
"is_fifo" BOOL NOT NULL,
PRIMARY KEY (project_id, worktree_id, id),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE "worktree_entries"
ADD "is_hidden" BOOL NOT NULL DEFAULT FALSE;
3 changes: 3 additions & 0 deletions crates/collab/src/db/queries/projects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ impl Database {
git_status: ActiveValue::set(None),
is_external: ActiveValue::set(entry.is_external),
is_deleted: ActiveValue::set(false),
is_hidden: ActiveValue::set(entry.is_hidden),
scan_id: ActiveValue::set(update.scan_id as i64),
is_fifo: ActiveValue::set(entry.is_fifo),
}
Expand All @@ -300,6 +301,7 @@ impl Database {
worktree_entry::Column::MtimeNanos,
worktree_entry::Column::CanonicalPath,
worktree_entry::Column::IsIgnored,
worktree_entry::Column::IsHidden,
worktree_entry::Column::ScanId,
])
.to_owned(),
Expand Down Expand Up @@ -905,6 +907,7 @@ impl Database {
canonical_path: db_entry.canonical_path,
is_ignored: db_entry.is_ignored,
is_external: db_entry.is_external,
is_hidden: db_entry.is_hidden,
// This is only used in the summarization backlog, so if it's None,
// that just means we won't be able to detect when to resummarize
// based on total number of backlogged bytes - instead, we'd go
Expand Down
1 change: 1 addition & 0 deletions crates/collab/src/db/queries/rooms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ impl Database {
canonical_path: db_entry.canonical_path,
is_ignored: db_entry.is_ignored,
is_external: db_entry.is_external,
is_hidden: db_entry.is_hidden,
// This is only used in the summarization backlog, so if it's None,
// that just means we won't be able to detect when to resummarize
// based on total number of backlogged bytes - instead, we'd go
Expand Down
1 change: 1 addition & 0 deletions crates/collab/src/db/tables/worktree_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub struct Model {
pub is_ignored: bool,
pub is_external: bool,
pub is_deleted: bool,
pub is_hidden: bool,
pub scan_id: i64,
pub is_fifo: bool,
pub canonical_path: Option<String>,
Expand Down
1 change: 1 addition & 0 deletions crates/project_panel/benches/sorting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ fn load_linux_repo_snapshot() -> Vec<GitEntry> {
is_always_included: false,
is_external: false,
is_private: false,
is_hidden: false,
char_bag: Default::default(),
is_fifo: false,
};
Expand Down
14 changes: 12 additions & 2 deletions crates/project_panel/src/project_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,9 @@ impl ProjectPanel {
if project_panel_settings.hide_root != new_settings.hide_root {
this.update_visible_entries(None, false, false, window, cx);
}
if project_panel_settings.hide_hidden != new_settings.hide_hidden {
this.update_visible_entries(None, false, false, window, cx);
}
if project_panel_settings.sticky_scroll && !new_settings.sticky_scroll {
this.sticky_items_count = 0;
}
Expand Down Expand Up @@ -3172,6 +3175,7 @@ impl ProjectPanel {
mtime: parent_entry.mtime,
size: parent_entry.size,
is_ignored: parent_entry.is_ignored,
is_hidden: parent_entry.is_hidden,
is_external: false,
is_private: false,
is_always_included: parent_entry.is_always_included,
Expand Down Expand Up @@ -3212,6 +3216,7 @@ impl ProjectPanel {
.map(|worktree| worktree.read(cx).snapshot())
.collect();
let hide_root = settings.hide_root && visible_worktrees.len() == 1;
let hide_hidden = settings.hide_hidden;
self.update_visible_entries_task = cx.spawn_in(window, async move |this, cx| {
let new_state = cx
.background_spawn(async move {
Expand Down Expand Up @@ -3303,7 +3308,9 @@ impl ProjectPanel {
}
}
auto_folded_ancestors.clear();
if !hide_gitignore || !entry.is_ignored {
if (!hide_gitignore || !entry.is_ignored)
&& (!hide_hidden || !entry.is_hidden)
{
visible_worktree_entries.push(entry.to_owned());
}
let precedes_new_entry = if let Some(new_entry_id) = new_entry_parent_id
Expand All @@ -3316,7 +3323,10 @@ impl ProjectPanel {
} else {
false
};
if precedes_new_entry && (!hide_gitignore || !entry.is_ignored) {
if precedes_new_entry
&& (!hide_gitignore || !entry.is_ignored)
&& (!hide_hidden || !entry.is_hidden)
{
visible_worktree_entries.push(Self::create_new_git_entry(
entry.entry,
entry.git_summary,
Expand Down
2 changes: 2 additions & 0 deletions crates/project_panel/src/project_panel_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub struct ProjectPanelSettings {
pub scrollbar: ScrollbarSettings,
pub show_diagnostics: ShowDiagnostics,
pub hide_root: bool,
pub hide_hidden: bool,
pub drag_and_drop: bool,
}

Expand Down Expand Up @@ -79,6 +80,7 @@ impl Settings for ProjectPanelSettings {
},
show_diagnostics: project_panel.show_diagnostics.unwrap(),
hide_root: project_panel.hide_root.unwrap(),
hide_hidden: project_panel.hide_hidden.unwrap(),
drag_and_drop: project_panel.drag_and_drop.unwrap(),
}
}
Expand Down
136 changes: 136 additions & 0 deletions crates/project_panel/src/project_panel_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6678,6 +6678,142 @@ async fn test_compare_files_context_menu(cx: &mut gpui::TestAppContext) {
}
}

#[gpui::test]
async fn test_hide_hidden_entries(cx: &mut gpui::TestAppContext) {
init_test(cx);

let fs = FakeFs::new(cx.executor());
fs.insert_tree(
"/root",
json!({
".hidden-file.txt": "hidden file content",
"visible-file.txt": "visible file content",
".hidden-parent-dir": {
"nested-dir": {
"file.txt": "file content",
}
},
"visible-dir": {
"file-in-visible.txt": "file content",
"nested": {
".hidden-nested-dir": {
".double-hidden-dir": {
"deep-file-1.txt": "deep content 1",
"deep-file-2.txt": "deep content 2"
},
"hidden-nested-file-1.txt": "hidden nested 1",
"hidden-nested-file-2.txt": "hidden nested 2"
},
"visible-nested-file.txt": "visible nested content"
}
}
}),
)
.await;

let project = Project::test(fs.clone(), ["/root".as_ref()], cx).await;
let workspace = cx.add_window(|window, cx| Workspace::test_new(project.clone(), window, cx));
let cx = &mut VisualTestContext::from_window(*workspace, cx);

cx.update(|_, cx| {
let settings = *ProjectPanelSettings::get_global(cx);
ProjectPanelSettings::override_global(
ProjectPanelSettings {
hide_hidden: false,
..settings
},
cx,
);
});

let panel = workspace.update(cx, ProjectPanel::new).unwrap();
cx.run_until_parked();

toggle_expand_dir(&panel, "root/.hidden-parent-dir", cx);
toggle_expand_dir(&panel, "root/.hidden-parent-dir/nested-dir", cx);
toggle_expand_dir(&panel, "root/visible-dir", cx);
toggle_expand_dir(&panel, "root/visible-dir/nested", cx);
toggle_expand_dir(&panel, "root/visible-dir/nested/.hidden-nested-dir", cx);
toggle_expand_dir(
&panel,
"root/visible-dir/nested/.hidden-nested-dir/.double-hidden-dir",
cx,
);

let expanded = [
"v root",
" v .hidden-parent-dir",
" v nested-dir",
" file.txt",
" v visible-dir",
" v nested",
" v .hidden-nested-dir",
" v .double-hidden-dir <== selected",
" deep-file-1.txt",
" deep-file-2.txt",
" hidden-nested-file-1.txt",
" hidden-nested-file-2.txt",
" visible-nested-file.txt",
" file-in-visible.txt",
" .hidden-file.txt",
" visible-file.txt",
];

assert_eq!(
visible_entries_as_strings(&panel, 0..30, cx),
&expanded,
"With hide_hidden=false, contents of hidden nested directory should be visible"
);

cx.update(|_, cx| {
let settings = *ProjectPanelSettings::get_global(cx);
ProjectPanelSettings::override_global(
ProjectPanelSettings {
hide_hidden: true,
..settings
},
cx,
);
});

panel.update_in(cx, |panel, window, cx| {
panel.update_visible_entries(None, false, false, window, cx);
});
cx.run_until_parked();

assert_eq!(
visible_entries_as_strings(&panel, 0..30, cx),
&[
"v root",
" v visible-dir",
" v nested",
" visible-nested-file.txt",
" file-in-visible.txt",
" visible-file.txt",
],
"With hide_hidden=false, contents of hidden nested directory should be visible"
);

panel.update_in(cx, |panel, window, cx| {
let settings = *ProjectPanelSettings::get_global(cx);
ProjectPanelSettings::override_global(
ProjectPanelSettings {
hide_hidden: false,
..settings
},
cx,
);
panel.update_visible_entries(None, false, false, window, cx);
});
cx.run_until_parked();

assert_eq!(
visible_entries_as_strings(&panel, 0..30, cx),
&expanded,
"With hide_hidden=false, deeply nested hidden directories and their contents should be visible"
);
}

fn select_path(panel: &Entity<ProjectPanel>, path: &str, cx: &mut VisualTestContext) {
let path = rel_path(path);
panel.update_in(cx, |panel, window, cx| {
Expand Down
1 change: 1 addition & 0 deletions crates/proto/proto/worktree.proto
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ message Entry {
bool is_fifo = 10;
optional uint64 size = 11;
optional string canonical_path = 12;
bool is_hidden = 13;
}

message AddWorktree {
Expand Down
4 changes: 4 additions & 0 deletions crates/settings/src/settings_content/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,10 @@ pub struct ProjectPanelSettingsContent {
///
/// Default: false
pub hide_root: Option<bool>,
/// Whether to hide the hidden entries in the project panel.
///
/// Default: false
pub hide_hidden: Option<bool>,
/// Whether to stick parent directories at top of the project panel.
///
/// Default: true
Expand Down
21 changes: 21 additions & 0 deletions crates/settings_ui/src/page_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2686,6 +2686,27 @@ pub(crate) fn settings_data() -> Vec<SettingsPage> {
metadata: None,
files: USER,
}),
SettingsPageItem::SettingItem(SettingItem {
title: "Hide Hidden",
description: "Whether to hide the hidden entries in the project panel",
field: Box::new(SettingField {
pick: |settings_content| {
if let Some(project_panel) = &settings_content.project_panel {
&project_panel.hide_hidden
} else {
&None
}
},
pick_mut: |settings_content| {
&mut settings_content
.project_panel
.get_or_insert_default()
.hide_hidden
},
}),
metadata: None,
files: USER,
}),
SettingsPageItem::SectionHeader("Terminal Panel"),
SettingsPageItem::SettingItem(SettingItem {
title: "Terminal Dock",
Expand Down
Loading
Loading