@@ -29,7 +29,7 @@ use helix_core::{
2929 tree_sitter::Node,
3030 unicode::width::UnicodeWidthChar,
3131 visual_offset_from_block, Deletion, LineEnding, Position, Range, Rope, RopeGraphemes,
32− RopeSlice, Selection, SmallVec, Tendril, Transaction,
32+ RopeReader, RopeSlice, Selection, SmallVec, Tendril, Transaction,
3333};
3434use helix_view::{
3535 clipboard::ClipboardType,
@@ -2062,11 +2062,16 @@ fn global_search(cx: &mut Context) {
20622062 .map(|comp| (0.., std::borrow::Cow::Owned(comp.clone())))
20632063 .collect()
20642064 },
2065− move |_editor, regex, event| {
2065+ move |editor, regex, event| {
20662066 if event != PromptEvent::Validate {
20672067 return;
20682068 }
20692069
2070+ let documents: Vec<_> = editor
2071+ .documents()
2072+ .map(|doc| (doc.path(), doc.text()))
2073+ .collect();
2074+
20702075 if let Ok(matcher) = RegexMatcherBuilder::new()
20712076 .case_smart(smart_case)
20722077 .build(regex.as_str())
@@ -2099,6 +2104,7 @@ fn global_search(cx: &mut Context) {
20992104 let mut searcher = searcher.clone();
21002105 let matcher = matcher.clone();
21012106 let all_matches_sx = all_matches_sx.clone();
2107+ let documents = &documents;
21022108 Box::new(move |entry: Result<DirEntry, ignore::Error>| -> WalkState {
21032109 let entry = match entry {
21042110 Ok(entry) => entry,
@@ -2111,17 +2117,36 @@ fn global_search(cx: &mut Context) {
21112117 _ => return WalkState::Continue,
21122118 };
21132119
2114− let result = searcher.search_path(
2115− &matcher,
2116− entry.path(),
2117− sinks::UTF8(|line_num, _| {
2118− all_matches_sx
2119− .send(FileResult::new(entry.path(), line_num as usize - 1))
2120− .unwrap();
2121−
2122− Ok(true)
2123− }),
2124− );
2120+ let sink = sinks::UTF8(|line_num, _| {
2121+ all_matches_sx
2122+ .send(FileResult::new(entry.path(), line_num as usize - 1))
2123+ .unwrap();
2124+
2125+ Ok(true)
2126+ });
2127+ let doc = documents.iter().find(|&(doc_path, _)| {
2128+ doc_path.map_or(false, |doc_path| doc_path == entry.path())
2129+ });
2130+
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)
2140+ } else {
2141+ searcher.search_reader(
2142+ &matcher,
2143+ RopeReader::new(doc.slice(..)),
2144+ sink,
2145+ )
2146+ }
2147+ } else {
2148+ searcher.search_path(&matcher, entry.path(), sink)
2149+ };
21252150
21262151 if let Err(err) = result {
21272152 log::error!(