aboutsummaryrefslogtreecommitdiff
path: root/helix-term
diff options
context:
space:
mode:
authorPascal Kuthe2023-07-11 12:26:11 +0000
committerGitHub2023-07-11 12:26:11 +0000
commit1adb19464f002926e1042027b41acef4c81585f6 (patch)
tree39f72c0907426f9cb0c36135cae751ac255167bf /helix-term
parent541d2b76d6e5d4518e1a9d903a39738a5c08b228 (diff)
search buffer contents during global search (#5652)
Diffstat (limited to 'helix-term')
-rw-r--r--helix-term/src/commands.rs51
1 files changed, 38 insertions, 13 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index b90f418a..ae715887 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -29,7 +29,7 @@ use helix_core::{
tree_sitter::Node,
unicode::width::UnicodeWidthChar,
visual_offset_from_block, Deletion, LineEnding, Position, Range, Rope, RopeGraphemes,
- RopeSlice, Selection, SmallVec, Tendril, Transaction,
+ RopeReader, RopeSlice, Selection, SmallVec, Tendril, Transaction,
};
use helix_view::{
clipboard::ClipboardType,
@@ -2062,11 +2062,16 @@ fn global_search(cx: &mut Context) {
.map(|comp| (0.., std::borrow::Cow::Owned(comp.clone())))
.collect()
},
- move |_editor, regex, event| {
+ move |editor, regex, event| {
if event != PromptEvent::Validate {
return;
}
+ let documents: Vec<_> = editor
+ .documents()
+ .map(|doc| (doc.path(), doc.text()))
+ .collect();
+
if let Ok(matcher) = RegexMatcherBuilder::new()
.case_smart(smart_case)
.build(regex.as_str())
@@ -2099,6 +2104,7 @@ fn global_search(cx: &mut Context) {
let mut searcher = searcher.clone();
let matcher = matcher.clone();
let all_matches_sx = all_matches_sx.clone();
+ let documents = &documents;
Box::new(move |entry: Result<DirEntry, ignore::Error>| -> WalkState {
let entry = match entry {
Ok(entry) => entry,
@@ -2111,17 +2117,36 @@ fn global_search(cx: &mut Context) {
_ => return WalkState::Continue,
};
- let result = searcher.search_path(
- &matcher,
- entry.path(),
- sinks::UTF8(|line_num, _| {
- all_matches_sx
- .send(FileResult::new(entry.path(), line_num as usize - 1))
- .unwrap();
-
- Ok(true)
- }),
- );
+ let sink = sinks::UTF8(|line_num, _| {
+ all_matches_sx
+ .send(FileResult::new(entry.path(), line_num as usize - 1))
+ .unwrap();
+
+ Ok(true)
+ });
+ let doc = documents.iter().find(|&(doc_path, _)| {
+ doc_path.map_or(false, |doc_path| doc_path == entry.path())
+ });
+
+ let result = if let Some((_, doc)) = doc {
+ // there is already a buffer for this file
+ // search the buffer instead of the file because it's faster
+ // and captures new edits without requireing a save
+ if searcher.multi_line_with_matcher(&matcher) {
+ // in this case a continous buffer is required
+ // convert the rope to a string
+ let text = doc.to_string();
+ searcher.search_slice(&matcher, text.as_bytes(), sink)
+ } else {
+ searcher.search_reader(
+ &matcher,
+ RopeReader::new(doc.slice(..)),
+ sink,
+ )
+ }
+ } else {
+ searcher.search_path(&matcher, entry.path(), sink)
+ };
if let Err(err) = result {
log::error!(