summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJeff Zhao <jeff.no.zhao@gmail.com>2021-04-25 14:20:01 -0400
committerJeff Zhao <jeff.no.zhao@gmail.com>2021-04-25 14:20:01 -0400
commit98e7abe8b451448305a4753dcad1bc56b2892a1b (patch)
tree2480fd7123574b92d08c5e46ebf78f17492d0e69 /src
parenta0fd0d5ec9cc023674099be44a2feea08879b0e9 (diff)
add back option to string search instead of always glob search
- search will be used for string search - search_glob will be used for glob search
Diffstat (limited to 'src')
-rw-r--r--src/commands/commands.rs21
-rw-r--r--src/commands/mod.rs3
-rw-r--r--src/commands/search.rs85
-rw-r--r--src/commands/search_glob.rs54
-rw-r--r--src/commands/search_string.rs47
-rw-r--r--src/context/context.rs7
6 files changed, 151 insertions, 66 deletions
diff --git a/src/commands/commands.rs b/src/commands/commands.rs
index 096dba1..03036af 100644
--- a/src/commands/commands.rs
+++ b/src/commands/commands.rs
@@ -50,7 +50,8 @@ pub enum KeyCommand {
RenameFileAppend,
RenameFilePrepend,
- Search(String),
+ SearchGlob(String),
+ SearchString(String),
SearchNext,
SearchPrev,
@@ -106,7 +107,8 @@ impl KeyCommand {
Self::RenameFileAppend => "rename_append",
Self::RenameFilePrepend => "rename_prepend",
- Self::Search(_) => "search",
+ Self::SearchString(_) => "search",
+ Self::SearchGlob(_) => "search_glob",
Self::SearchNext => "search_next",
Self::SearchPrev => "search_prev",
@@ -251,7 +253,14 @@ impl KeyCommand {
JoshutoErrorKind::IoInvalidData,
format!("{}: Expected 1, got 0", command),
)),
- arg => Ok(Self::Search(arg.to_string())),
+ arg => Ok(Self::SearchString(arg.to_string())),
+ },
+ "search_glob" => match arg {
+ "" => Err(JoshutoError::new(
+ JoshutoErrorKind::IoInvalidData,
+ format!("{}: Expected 1, got 0", command),
+ )),
+ arg => Ok(Self::SearchGlob(arg.to_string())),
},
"search_next" => Ok(Self::SearchNext),
"search_prev" => Ok(Self::SearchPrev),
@@ -362,7 +371,8 @@ impl JoshutoRunnable for KeyCommand {
Self::RenameFile(p) => rename_file::rename_file(context, p.as_path()),
Self::RenameFileAppend => rename_file::rename_file_append(context, backend),
Self::RenameFilePrepend => rename_file::rename_file_prepend(context, backend),
- Self::Search(pattern) => search::search(context, pattern.as_str()),
+ Self::SearchGlob(pattern) => search_glob::search_glob(context, pattern.as_str()),
+ Self::SearchString(pattern) => search_string::search_string(context, pattern.as_str()),
Self::SearchNext => search::search_next(context),
Self::SearchPrev => search::search_prev(context),
@@ -397,7 +407,8 @@ impl std::fmt::Display for KeyCommand {
Self::NewDirectory(d) => write!(f, "{} {:?}", self.command(), d),
Self::RenameFile(name) => write!(f, "{} {:?}", self.command(), name),
- Self::Search(s) => write!(f, "{} {}", self.command(), s),
+ Self::SearchGlob(s) => write!(f, "{} {}", self.command(), s),
+ Self::SearchString(s) => write!(f, "{} {}", self.command(), s),
Self::SelectFiles(pattern, options) => {
write!(f, "{} {} {}", self.command(), pattern, options)
}
diff --git a/src/commands/mod.rs b/src/commands/mod.rs
index 20289f3..a03e9c5 100644
--- a/src/commands/mod.rs
+++ b/src/commands/mod.rs
@@ -12,6 +12,8 @@ pub mod quit;
pub mod reload;
pub mod rename_file;
pub mod search;
+pub mod search_glob;
+pub mod search_string;
pub mod selection;
pub mod set_mode;
pub mod shell;
@@ -25,3 +27,4 @@ pub mod commands;
pub use self::command_keybind::{CommandKeybind, JoshutoCommand, JoshutoRunnable};
pub use self::commands::KeyCommand;
+pub use self::search::SearchPattern;
diff --git a/src/commands/search.rs b/src/commands/search.rs
index 8ff33ca..8bade96 100644
--- a/src/commands/search.rs
+++ b/src/commands/search.rs
@@ -5,76 +5,45 @@ use crate::error::{JoshutoError, JoshutoErrorKind, JoshutoResult};
use crate::tab::JoshutoTab;
use super::cursor_move;
+use super::search_glob;
+use super::search_string;
-pub fn _search(curr_tab: &JoshutoTab, glob: &GlobMatcher) -> Option<usize> {
- let curr_list = curr_tab.curr_list_ref()?;
-
- let offset = curr_list.index? + 1;
- let contents_len = curr_list.len();
- for i in 0..contents_len {
- let file_name = curr_list.contents[(offset + i) % contents_len].file_name();
- if glob.is_match(file_name) {
- return Some((offset + i) % contents_len);
- }
- }
- None
+#[derive(Clone, Debug)]
+pub enum SearchPattern {
+ Glob(GlobMatcher),
+ String(String),
}
-pub fn _search_rev(curr_tab: &JoshutoTab, glob: &GlobMatcher) -> Option<usize> {
- let curr_list = curr_tab.curr_list_ref()?;
- let offset = curr_list.index?;
- let contents_len = curr_list.len();
- for i in (0..contents_len).rev() {
- let file_name = curr_list.contents[(offset + i) % contents_len].file_name();
- if glob.is_match(file_name) {
- return Some((offset + i) % contents_len);
- }
- }
- None
-}
-
-pub fn search(context: &mut JoshutoContext, pattern: &str) -> JoshutoResult<()> {
- let pattern = pattern.to_lowercase();
-
- let glob = match GlobBuilder::new(pattern.as_str())
- .case_insensitive(true)
- .build()
- {
- Ok(s) => s.compile_matcher(),
- Err(e) => {
- return Err(JoshutoError::new(
- JoshutoErrorKind::IoInvalidData,
- "Invalid glob input".to_string(),
- ));
+pub fn search_next(context: &mut JoshutoContext) -> JoshutoResult<()> {
+ if let Some(s) = context.get_search_state() {
+ let index = match s {
+ SearchPattern::Glob(s) => {
+ search_glob::search_glob_fwd(context.tab_context_ref().curr_tab_ref(), s)
+ }
+ SearchPattern::String(s) => {
+ search_string::search_string_fwd(context.tab_context_ref().curr_tab_ref(), s)
+ }
+ };
+ if let Some(index) = index {
+ let _ = cursor_move::cursor_move(index, context);
}
- };
-
- let index = _search(context.tab_context_ref().curr_tab_ref(), &glob);
- if let Some(index) = index {
- let _ = cursor_move::cursor_move(index, context);
}
- context.set_search_state(glob);
Ok(())
}
-fn search_with_func(
- context: &mut JoshutoContext,
- search_func: fn(&JoshutoTab, &GlobMatcher) -> Option<usize>,
-) {
+pub fn search_prev(context: &mut JoshutoContext) -> JoshutoResult<()> {
if let Some(s) = context.get_search_state() {
- let index = search_func(context.tab_context_ref().curr_tab_ref(), s);
+ let index = match s {
+ SearchPattern::Glob(s) => {
+ search_glob::search_glob_fwd(context.tab_context_ref().curr_tab_ref(), s)
+ }
+ SearchPattern::String(s) => {
+ search_string::search_string_rev(context.tab_context_ref().curr_tab_ref(), s)
+ }
+ };
if let Some(index) = index {
let _ = cursor_move::cursor_move(index, context);
}
}
-}
-
-pub fn search_next(context: &mut JoshutoContext) -> JoshutoResult<()> {
- search_with_func(context, _search);
- Ok(())
-}
-
-pub fn search_prev(context: &mut JoshutoContext) -> JoshutoResult<()> {
- search_with_func(context, _search_rev);
Ok(())
}
diff --git a/src/commands/search_glob.rs b/src/commands/search_glob.rs
new file mode 100644
index 0000000..bb87cf8
--- /dev/null
+++ b/src/commands/search_glob.rs
@@ -0,0 +1,54 @@
+use globset::{GlobBuilder, GlobMatcher};
+
+use crate::commands::SearchPattern;
+use crate::context::JoshutoContext;
+use crate::error::{JoshutoError, JoshutoErrorKind, JoshutoResult};
+use crate::tab::JoshutoTab;
+
+use super::cursor_move;
+
+pub fn search_glob_fwd(curr_tab: &JoshutoTab, glob: &GlobMatcher) -> Option<usize> {
+ let curr_list = curr_tab.curr_list_ref()?;
+
+ let offset = curr_list.index? + 1;
+ let contents_len = curr_list.len();
+ for i in 0..contents_len {
+ let file_name = curr_list.contents[(offset + i) % contents_len].file_name();
+ if glob.is_match(file_name) {
+ return Some((offset + i) % contents_len);
+ }
+ }
+ None
+}
+pub fn search_glob_rev(curr_tab: &JoshutoTab, glob: &GlobMatcher) -> Option<usize> {
+ let curr_list = curr_tab.curr_list_ref()?;
+
+ let offset = curr_list.index?;
+ let contents_len = curr_list.len();
+ for i in (0..contents_len).rev() {
+ let file_name = curr_list.contents[(offset + i) % contents_len].file_name();
+ if glob.is_match(file_name) {
+ return Some((offset + i) % contents_len);
+ }
+ }
+ None
+}
+
+pub fn search_glob(context: &mut JoshutoContext, pattern: &str) -> JoshutoResult<()> {
+ let glob = match GlobBuilder::new(pattern).case_insensitive(true).build() {
+ Ok(s) => s.compile_matcher(),
+ Err(e) => {
+ return Err(JoshutoError::new(
+ JoshutoErrorKind::IoInvalidData,
+ "Invalid glob input".to_string(),
+ ));
+ }
+ };
+
+ let index = search_glob_fwd(context.tab_context_ref().curr_tab_ref(), &glob);
+ if let Some(index) = index {
+ let _ = cursor_move::cursor_move(index, context);
+ }
+ context.set_search_state(SearchPattern::Glob(glob));
+ Ok(())
+}
diff --git a/src/commands/search_string.rs b/src/commands/search_string.rs
new file mode 100644
index 0000000..6cf5fa6
--- /dev/null
+++ b/src/commands/search_string.rs
@@ -0,0 +1,47 @@
+use crate::commands::SearchPattern;
+use crate::context::JoshutoContext;
+use crate::error::JoshutoResult;
+use crate::tab::JoshutoTab;
+
+use super::cursor_move;
+
+pub fn search_string_fwd(curr_tab: &JoshutoTab, pattern: &str) -> Option<usize> {
+ let curr_list = curr_tab.curr_list_ref()?;
+
+ let offset = curr_list.index? + 1;
+ let contents_len = curr_list.contents.len();
+ for i in 0..contents_len {
+ let file_name_lower = curr_list.contents[(offset + i) % contents_len]
+ .file_name()
+ .to_lowercase();
+ if file_name_lower.contains(pattern) {
+ return Some((offset + i) % contents_len);
+ }
+ }
+ None
+}
+pub fn search_string_rev(curr_tab: &JoshutoTab, pattern: &str) -> Option<usize> {
+ let curr_list = curr_tab.curr_list_ref()?;
+
+ let offset = curr_list.index?;
+ let contents_len = curr_list.contents.len();
+ for i in (0..contents_len).rev() {
+ let file_name_lower = curr_list.contents[(offset + i) % contents_len]
+ .file_name()
+ .to_lowercase();
+ if file_name_lower.contains(pattern) {
+ return Some((offset + i) % contents_len);
+ }
+ }
+ None
+}
+
+pub fn search_string(context: &mut JoshutoContext, pattern: &str) -> JoshutoResult<()> {
+ let pattern = pattern.to_lowercase();
+ let index = search_string_fwd(context.tab_context_ref().curr_tab_ref(), pattern.as_str());
+ if let Some(index) = index {
+ let _ = cursor_move::cursor_move(index, context);
+ }
+ context.set_search_state(SearchPattern::String(pattern));
+ Ok(())
+}
diff --git a/src/context/context.rs b/src/context/context.rs
index 14e262f..09e9c56 100644
--- a/src/context/context.rs
+++ b/src/context/context.rs
@@ -5,6 +5,7 @@ use std::thread;
use globset::GlobMatcher;
+use crate::commands::SearchPattern;
use crate::config;
use crate::context::{LocalStateContext, TabContext};
use crate::io::{IoWorkerObserver, IoWorkerProgress, IoWorkerThread};
@@ -16,7 +17,7 @@ pub struct JoshutoContext {
events: Events,
tab_context: TabContext,
local_state: Option<LocalStateContext>,
- search_state: Option<GlobMatcher>,
+ search_state: Option<SearchPattern>,
message_queue: VecDeque<String>,
worker_queue: VecDeque<IoWorkerThread>,
worker: Option<IoWorkerObserver>,
@@ -81,11 +82,11 @@ impl JoshutoContext {
self.local_state.take()
}
- pub fn set_search_state(&mut self, pattern: GlobMatcher) {
+ pub fn set_search_state(&mut self, pattern: SearchPattern) {
self.search_state = Some(pattern);
}
- pub fn get_search_state(&self) -> Option<&GlobMatcher> {
+ pub fn get_search_state(&self) -> Option<&SearchPattern> {
self.search_state.as_ref()
}