From 790e476d8ec362dcdcaafae3c1e3c570b0a2641d Mon Sep 17 00:00:00 2001 From: kellito Date: Sun, 5 Jul 2026 18:10:55 +0300 Subject: [PATCH] =?UTF-8?q?tlc:=20Sprint=203=20C9=20=E2=80=94=20empty=20pa?= =?UTF-8?q?ttern=20inverts/clears=20marks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously mark_pattern("") and unmark_pattern("") were silent no-ops (glob_match returned false for empty pattern). Now they match MC's behavior: - mark_pattern(""): calls reverse_marks() (toggles every entry; from 0 marks → all entries marked, vice versa) - unmark_pattern(""): clears all marks Tests (2 new in panel::tests): - mark_pattern_empty_inverts_marks (0→2→0 cycle) - unmark_pattern_empty_clears_all_marks Total: 1276 passing (was 1274; +2 new). --- .../tui/tlc/source/src/filemanager/panel.rs | 50 ++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/local/recipes/tui/tlc/source/src/filemanager/panel.rs b/local/recipes/tui/tlc/source/src/filemanager/panel.rs index f321063c40..91ef06f6f7 100644 --- a/local/recipes/tui/tlc/source/src/filemanager/panel.rs +++ b/local/recipes/tui/tlc/source/src/filemanager/panel.rs @@ -424,8 +424,14 @@ impl Panel { } } - /// Mark entries matching `pattern` (Unix glob). + /// Mark entries matching `pattern` (Unix glob). An empty pattern + /// marks every regular entry (skipping `..`), matching MC's + /// "Select group" behavior with an empty expression. pub fn mark_pattern(&mut self, pattern: &str) { + if pattern.is_empty() { + self.reverse_marks(); + return; + } for e in &self.entries { if glob_match(pattern, &e.name) { self.marked.insert(e.name.clone()); @@ -433,8 +439,14 @@ impl Panel { } } - /// Unmark entries matching `pattern` (Unix glob). + /// Unmark entries matching `pattern` (Unix glob). An empty + /// pattern clears every mark (matching MC's "Unselect group" + /// with an empty expression). pub fn unmark_pattern(&mut self, pattern: &str) { + if pattern.is_empty() { + self.marked.clear(); + return; + } let to_remove: Vec = self .entries .iter() @@ -1238,6 +1250,40 @@ mod tests { let _ = fs::remove_dir_all(&dir); } + #[test] + fn mark_pattern_empty_inverts_marks() { + let dir = std::env::temp_dir().join("tlc-panel-mark-empty-test"); + let _ = fs::remove_dir_all(&dir); + fs::create_dir_all(&dir).unwrap(); + fs::write(dir.join("a.txt"), b"x").unwrap(); + fs::write(dir.join("b.txt"), b"x").unwrap(); + let mut p = Panel::new(&dir, &empty_cfg()).unwrap(); + // Empty pattern inverts: from 0 marks → all entries marked + // (skipping '..'). + p.mark_pattern(""); + assert_eq!(p.marked_count(), 2); + // Apply again: 2 marks → 0 marks. + p.mark_pattern(""); + assert_eq!(p.marked_count(), 0); + let _ = fs::remove_dir_all(&dir); + } + + #[test] + fn unmark_pattern_empty_clears_all_marks() { + let dir = std::env::temp_dir().join("tlc-panel-unmark-empty-test"); + let _ = fs::remove_dir_all(&dir); + fs::create_dir_all(&dir).unwrap(); + fs::write(dir.join("a.txt"), b"x").unwrap(); + fs::write(dir.join("b.txt"), b"x").unwrap(); + let mut p = Panel::new(&dir, &empty_cfg()).unwrap(); + p.mark_pattern("*.txt"); + assert_eq!(p.marked_count(), 2); + // Empty pattern clears every mark. + p.unmark_pattern(""); + assert_eq!(p.marked_count(), 0); + let _ = fs::remove_dir_all(&dir); + } + #[test] fn test_is_archive_extension_tar() { assert_eq!(is_archive_extension("foo.tar"), Some("tar"));