From 2a1ce22628199427b3dc1c6b5cf0464d692367f3 Mon Sep 17 00:00:00 2001 From: Nguyen Duc Toan Date: Tue, 3 Oct 2023 22:56:48 +0700 Subject: [PATCH] add --smart-case and --ignore-case flags to find command, enable --smart-case by default --- app/src/executor.rs | 11 +++++++++-- config/preset/keymap.toml | 4 ++-- core/src/manager/finder.rs | 19 ++++++++++++++++--- core/src/manager/tab.rs | 12 ++++++++---- 4 files changed, 35 insertions(+), 11 deletions(-) diff --git a/app/src/executor.rs b/app/src/executor.rs index d4dd0b21..afc17a08 100644 --- a/app/src/executor.rs +++ b/app/src/executor.rs @@ -1,4 +1,4 @@ -use core::{emit, files::FilesSorter, input::InputMode}; +use core::{emit, files::FilesSorter, input::InputMode, manager::FinderCase}; use config::{keymap::{Control, Exec, Key, KeymapLayer}, manager::SortBy, KEYMAP}; use shared::{optional_bool, Url}; @@ -154,7 +154,14 @@ impl Executor { "find" => { let query = exec.args.get(0).map(|s| s.as_str()); let prev = exec.named.contains_key("previous"); - cx.manager.active_mut().find(query, prev) + let smart_case = exec.named.contains_key("smart-case"); + let ingore_case = exec.named.contains_key("ignore-case"); + let case = match (smart_case, ingore_case) { + (false, false) => FinderCase::CaseSensitive, + (false, true) => FinderCase::CaseInsensitive, + (true, _) => FinderCase::SmartCase, // prioritize smart-case over ignore-case + }; + cx.manager.active_mut().find(query, prev, case) } "find_arrow" => cx.manager.active_mut().find_arrow(exec.named.contains_key("previous")), diff --git a/config/preset/keymap.toml b/config/preset/keymap.toml index b1f5598c..4ac415a9 100644 --- a/config/preset/keymap.toml +++ b/config/preset/keymap.toml @@ -73,8 +73,8 @@ keymap = [ { on = [ "c", "n" ], exec = "copy name_without_ext", desc = "Copy the name of the file without the extension" }, # Find - { on = [ "/" ], exec = "find" }, - { on = [ "?" ], exec = "find --previous" }, + { on = [ "/" ], exec = "find --smart-case" }, + { on = [ "?" ], exec = "find --previous --smart-case" }, { on = [ "n" ], exec = "find_arrow" }, { on = [ "N" ], exec = "find_arrow --previous" }, diff --git a/core/src/manager/finder.rs b/core/src/manager/finder.rs index 84df7688..d438082f 100644 --- a/core/src/manager/finder.rs +++ b/core/src/manager/finder.rs @@ -6,6 +6,13 @@ use shared::Url; use crate::files::Files; +#[derive(Debug, PartialEq, Eq)] +pub enum FinderCase { + CaseSensitive, + CaseInsensitive, + SmartCase, +} + pub struct Finder { query: Regex, matched: BTreeMap, @@ -13,9 +20,15 @@ pub struct Finder { } impl Finder { - pub(super) fn new(s: &str) -> Result { - let uppercase = s.chars().any(|c| c.is_uppercase()); - let query = RegexBuilder::new(s).case_insensitive(!uppercase).build()?; + pub(super) fn new(s: &str, case: FinderCase) -> Result { + let query = match case { + FinderCase::CaseSensitive => Regex::new(s)?, + FinderCase::CaseInsensitive => RegexBuilder::new(s).case_insensitive(true).build()?, + FinderCase::SmartCase => { + let uppercase = s.chars().any(|c| c.is_uppercase()); + RegexBuilder::new(s).case_insensitive(!uppercase).build()? + }, + }; Ok(Self { query, matched: Default::default(), version: 0 }) } diff --git a/core/src/manager/tab.rs b/core/src/manager/tab.rs index d522d902..5c4b2c84 100644 --- a/core/src/manager/tab.rs +++ b/core/src/manager/tab.rs @@ -6,7 +6,7 @@ use shared::{Debounce, Defer, InputError, Url}; use tokio::{pin, task::JoinHandle}; use tokio_stream::{wrappers::UnboundedReceiverStream, StreamExt}; -use super::{Backstack, Finder, Folder, Mode, Preview, PreviewLock}; +use super::{Backstack, Finder, Folder, Mode, Preview, PreviewLock, FinderCase}; use crate::{emit, external::{self, FzfOpt, ZoxideOpt}, files::{File, FilesOp, FilesSorter}, input::InputOpt, Event, Step, BLOCKER}; pub struct Tab { @@ -267,9 +267,9 @@ impl Tab { false } - pub fn find(&mut self, query: Option<&str>, prev: bool) -> bool { + pub fn find(&mut self, query: Option<&str>, prev: bool, case: FinderCase) -> bool { if let Some(query) = query { - let Ok(finder) = Finder::new(query) else { + let Ok(finder) = Finder::new(query, case) else { return false; }; @@ -297,7 +297,11 @@ impl Tab { while let Some(Ok(s)) | Some(Err(InputError::Typed(s))) = rx.next().await { emit!(Call( - Exec::call("find", vec![s]).with_bool("previous", prev).vec(), + Exec::call("find", vec![s]) + .with_bool("previous", prev) + .with_bool("smart-case", case == FinderCase::SmartCase) + .with_bool("ignore-case", case == FinderCase::CaseInsensitive) + .vec(), KeymapLayer::Manager )); }