Browse / github.com/storytold/filmcraft / patch
Project panel: search finds names holding every typed word
Project panel: search finds names holding every typed word ## Problem The Project panel's search matched the typed text as one run of letters. In a bin of clips named like `Comedy manager · medium · smiling · enjoys the show · img385 · A`, `comedy manager` found them but `comedy manager s` (and `comedy manager smiling`) found nothing: the words are all there, with ` · ` between them. ## Change `crates/ui-egui/src/panels/project_views.rs`: `name_matches` — a name matches when it holds every whitespace-separated word typed, in any order. `matches_filter` uses it, so List, Icon and Freeform views, keyboard navigation and Select All over a search all a
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- punkhop (imported from pull request #3327, open)
- Base
fa0502602cbef03bf4a3a98131d72c1e3674c238- Size
- +26 −1 in 1 file
- Review
- pending
- Shared
- 2026-10-28
- Id
58954017ef021745249725e3
How it went
No other operator has reported using it yet.
Diff
raw · crates/ui-egui/src/panels/project_views.rs
@@ -76,7 +76,15 @@ fn paint_badges(ui: &egui::Ui, b: &Badge, at: egui::Pos2, t: &Tokens) { } fn matches_filter(app: &FilmcraftApp, id: ItemId, filter: &str) -> bool {- app.session.project.item(id).is_some_and(|i| pp::listed(&app.session.project, i) && (filter.is_empty() || i.name.to_ascii_lowercase().contains(filter)))+ app.session.project.item(id).is_some_and(|i| pp::listed(&app.session.project, i) && name_matches(&i.name, filter))+}++/// The search finds a name holding every word typed, in any order: "comedy manager smiling" finds+/// "Comedy manager · medium · smiling", where the typed text as one run of letters would not.+/// `filter` is already lowercase.+fn name_matches(name: &str, filter: &str) -> bool {+ let name = name.to_ascii_lowercase();+ filter.split_whitespace().all(|word| name.contains(word)) } fn label_color(app: &FilmcraftApp, l: filmcraft_project::Label) -> Color32 {@@ -1242,3 +1250,20 @@ mod clear_tests { assert_eq!(click_selection(&ids(&[1, 3]), &order, None, ItemId(2), false, false), ids(&[2])); } }++#[cfg(test)]+mod search_tests {+ use super::name_matches;++ #[test]+ fn every_typed_word_must_appear_in_any_order() {+ let name = "Comedy manager · medium · smiling · enjoys the show · img385 · A";+ assert!(name_matches(name, ""));+ assert!(name_matches(name, "comedy manager"));+ assert!(name_matches(name, "comedy manager s"));+ assert!(name_matches(name, "comedy manager smiling"));+ assert!(name_matches(name, "smiling comedy "));+ assert!(!name_matches(name, "comedy manager laughing"));+ assert!(!name_matches("Comedy club", "comedy manager"));+ }+}