@@ -29,7 +29,7 @@ use helix_core::{
29 tree_sitter::Node,
29 tree_sitter::Node,
30 unicode::width::UnicodeWidthChar,
30 unicode::width::UnicodeWidthChar,
31 visual_offset_from_block, Deletion, LineEnding, Position, Range, Rope, RopeGraphemes,
31 visual_offset_from_block, Deletion, LineEnding, Position, Range, Rope, RopeGraphemes,
32− RopeSlice, Selection, SmallVec, Tendril, Transaction,
32+ RopeReader, RopeSlice, Selection, SmallVec, Tendril, Transaction,
34use helix_view::{
34use helix_view::{
35 clipboard::ClipboardType,
35 clipboard::ClipboardType,
@@ -2062,11 +2062,16 @@ fn global_search(cx: &mut Context) {
2062 .map(|comp| (0.., std::borrow::Cow::Owned(comp.clone())))
2062 .map(|comp| (0.., std::borrow::Cow::Owned(comp.clone())))
2063 .collect()
2063 .collect()
2065− move |_editor, regex, event| {
2065+ move |editor, regex, event| {
2066 if event != PromptEvent::Validate {
2066 if event != PromptEvent::Validate {
2070+ let documents: Vec<_> = editor
2072+ .map(|doc| (doc.path(), doc.text()))
2070 if let Ok(matcher) = RegexMatcherBuilder::new()
2075 if let Ok(matcher) = RegexMatcherBuilder::new()
2071 .case_smart(smart_case)
2076 .case_smart(smart_case)
2072 .build(regex.as_str())
2077 .build(regex.as_str())
@@ -2099,6 +2104,7 @@ fn global_search(cx: &mut Context) {
2099 let mut searcher = searcher.clone();
2104 let mut searcher = searcher.clone();
2100 let matcher = matcher.clone();
2105 let matcher = matcher.clone();
2101 let all_matches_sx = all_matches_sx.clone();
2106 let all_matches_sx = all_matches_sx.clone();
2107+ let documents = &documents;
2102 Box::new(move |entry: Result<DirEntry, ignore::Error>| -> WalkState {
2108 Box::new(move |entry: Result<DirEntry, ignore::Error>| -> WalkState {
2103 let entry = match entry {
2109 let entry = match entry {
2104 Ok(entry) => entry,
2110 Ok(entry) => entry,
@@ -2111,17 +2117,36 @@ fn global_search(cx: &mut Context) {
2111 _ => return WalkState::Continue,
2117 _ => return WalkState::Continue,
2114− let result = searcher.search_path(
2117− sinks::UTF8(|line_num, _| {
2120+ let sink = sinks::UTF8(|line_num, _| {
2118− all_matches_sx
2121+ all_matches_sx
2119− .send(FileResult::new(entry.path(), line_num as usize - 1))
2122+ .send(FileResult::new(entry.path(), line_num as usize - 1))
2120− .unwrap();
2123+ .unwrap();
2122− Ok(true)
2125+ Ok(true)
2127+ let doc = documents.iter().find(|&(doc_path, _)| {
2128+ doc_path.map_or(false, |doc_path| doc_path == entry.path())
2131+ let result = if let Some((_, doc)) = doc {
2132+ // there is already a buffer for this file
2133+ // search the buffer instead of the file because it's faster
2134+ // and captures new edits without requireing a save
2135+ if searcher.multi_line_with_matcher(&matcher) {
2136+ // in this case a continous buffer is required
2137+ // convert the rope to a string
2138+ let text = doc.to_string();
2139+ searcher.search_slice(&matcher, text.as_bytes(), sink)
2141+ searcher.search_reader(
2143+ RopeReader::new(doc.slice(..)),
2148+ searcher.search_path(&matcher, entry.path(), sink)
2126 if let Err(err) = result {
2151 if let Err(err) = result {
2127 log::error!(
2152 log::error!(