Closes #4533 (partly at least) Release Notes: - Added `project_panel.sort_mode` option to control explorer file sort (directories first, mixed, files first) ## Summary Adds three sorting modes for the project panel to give users more control over how files and directories are displayed: - **`directories_first`** (default): Current behaviour - directories grouped before files - **`mixed`**: Files and directories sorted together alphabetically - **`files_first`**: filed grouped before directories ## Motivation Users coming from different editors and file managers have different expectations for file sorting. Some prefer directories grouped at the top (traditional), while others prefer the macOS Finder-style mixed sorting where "Apple1/", "apple2.tsx" and "Apple3/" appear alphabetically mixed together. ### Screenshots New sort options in settings: <img width="515" height="160" alt="image" src="https://github.com/user-attachments/assets/8f4e6668-6989-4881-a9bd-ed1f4f0beb40" /> Directories first | Mixed | Files first -------------|-----|----- <img width="328" height="888" alt="image" src="https://github.com/user-attachments/assets/308e5c7a-6e6a-46ba-813d-6e268222925c" /> | <img width="327" height="891" alt="image" src="https://github.com/user-attachments/assets/8274d8ca-b60f-456e-be36-e35a3259483c" /> | <img width="328" height="890" alt="image" src="https://github.com/user-attachments/assets/3c3b1332-cf08-4eaf-9bed-527c00b41529" /> ### Agent usage Copilot-cli/claude-code/codex-cli helped out a lot. I'm not from a rust background, but really wanted this solved, and it gave me a chance to play with some of the coding agents I'm not permitted to use for work stuff --------- Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
84 lines
2.6 KiB
Rust
84 lines
2.6 KiB
Rust
use criterion::{Criterion, criterion_group, criterion_main};
|
|
use project::{Entry, EntryKind, GitEntry, ProjectEntryId};
|
|
use project_panel::par_sort_worktree_entries_with_mode;
|
|
use settings::ProjectPanelSortMode;
|
|
use std::sync::Arc;
|
|
use util::rel_path::RelPath;
|
|
|
|
fn load_linux_repo_snapshot() -> Vec<GitEntry> {
|
|
let file = std::fs::read_to_string(concat!(
|
|
env!("CARGO_MANIFEST_DIR"),
|
|
"/benches/linux_repo_snapshot.txt"
|
|
))
|
|
.expect("Failed to read file");
|
|
file.lines()
|
|
.filter_map(|line| {
|
|
let kind = match line.chars().next() {
|
|
Some('f') => EntryKind::File,
|
|
Some('d') => EntryKind::Dir,
|
|
_ => return None,
|
|
};
|
|
|
|
let entry = Entry {
|
|
kind,
|
|
path: Arc::from(RelPath::unix(&(line.trim_end()[2..])).unwrap()),
|
|
id: ProjectEntryId::default(),
|
|
size: 0,
|
|
inode: 0,
|
|
mtime: None,
|
|
canonical_path: None,
|
|
is_ignored: false,
|
|
is_always_included: false,
|
|
is_external: false,
|
|
is_private: false,
|
|
is_hidden: false,
|
|
char_bag: Default::default(),
|
|
is_fifo: false,
|
|
};
|
|
Some(GitEntry {
|
|
entry,
|
|
git_summary: Default::default(),
|
|
})
|
|
})
|
|
.collect()
|
|
}
|
|
fn criterion_benchmark(c: &mut Criterion) {
|
|
let snapshot = load_linux_repo_snapshot();
|
|
|
|
c.bench_function("Sort linux worktree snapshot", |b| {
|
|
b.iter_batched(
|
|
|| snapshot.clone(),
|
|
|mut snapshot| {
|
|
par_sort_worktree_entries_with_mode(
|
|
&mut snapshot,
|
|
ProjectPanelSortMode::DirectoriesFirst,
|
|
)
|
|
},
|
|
criterion::BatchSize::LargeInput,
|
|
);
|
|
});
|
|
|
|
c.bench_function("Sort linux worktree snapshot (Mixed)", |b| {
|
|
b.iter_batched(
|
|
|| snapshot.clone(),
|
|
|mut snapshot| {
|
|
par_sort_worktree_entries_with_mode(&mut snapshot, ProjectPanelSortMode::Mixed)
|
|
},
|
|
criterion::BatchSize::LargeInput,
|
|
);
|
|
});
|
|
|
|
c.bench_function("Sort linux worktree snapshot (FilesFirst)", |b| {
|
|
b.iter_batched(
|
|
|| snapshot.clone(),
|
|
|mut snapshot| {
|
|
par_sort_worktree_entries_with_mode(&mut snapshot, ProjectPanelSortMode::FilesFirst)
|
|
},
|
|
criterion::BatchSize::LargeInput,
|
|
);
|
|
});
|
|
}
|
|
|
|
criterion_group!(benches, criterion_benchmark);
|
|
criterion_main!(benches);
|