Enable look-around in Project Search using fancy-regex crate (#20308)

Closes #13486 

Release Notes:

- Added support for look-around in project search

Co-authored-by: Max <max@zed.dev>
This commit is contained in:
Will Bradley 2024-11-07 09:18:09 -07:00 committed by GitHub
parent de70852497
commit daa35e98f1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 38 additions and 8 deletions

31
Cargo.lock generated
View file

@ -1588,7 +1588,7 @@ dependencies = [
"bitflags 2.6.0", "bitflags 2.6.0",
"cexpr", "cexpr",
"clang-sys", "clang-sys",
"itertools 0.10.5", "itertools 0.12.1",
"lazy_static", "lazy_static",
"lazycell", "lazycell",
"proc-macro2", "proc-macro2",
@ -1637,6 +1637,15 @@ dependencies = [
"bit-vec 0.7.0", "bit-vec 0.7.0",
] ]
[[package]]
name = "bit-set"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
dependencies = [
"bit-vec 0.8.0",
]
[[package]] [[package]]
name = "bit-vec" name = "bit-vec"
version = "0.6.3" version = "0.6.3"
@ -1649,6 +1658,12 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2c54ff287cfc0a34f38a6b832ea1bd8e448a330b3e40a50859e6488bee07f22" checksum = "d2c54ff287cfc0a34f38a6b832ea1bd8e448a330b3e40a50859e6488bee07f22"
[[package]]
name = "bit-vec"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
[[package]] [[package]]
name = "bit_field" name = "bit_field"
version = "0.10.2" version = "0.10.2"
@ -4248,6 +4263,17 @@ dependencies = [
"regex", "regex",
] ]
[[package]]
name = "fancy-regex"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e24cb5a94bcae1e5408b0effca5cd7172ea3c5755049c5f3af4cd283a165298"
dependencies = [
"bit-set 0.8.0",
"regex-automata 0.4.7",
"regex-syntax 0.8.4",
]
[[package]] [[package]]
name = "fast-srgb8" name = "fast-srgb8"
version = "1.0.0" version = "1.0.0"
@ -9044,6 +9070,7 @@ dependencies = [
"clock", "clock",
"collections", "collections",
"env_logger 0.11.5", "env_logger 0.11.5",
"fancy-regex 0.14.0",
"fs", "fs",
"futures 0.3.30", "futures 0.3.30",
"fuzzy", "fuzzy",
@ -12394,7 +12421,7 @@ dependencies = [
"anyhow", "anyhow",
"base64 0.21.7", "base64 0.21.7",
"bstr", "bstr",
"fancy-regex", "fancy-regex 0.12.0",
"lazy_static", "lazy_static",
"parking_lot", "parking_lot",
"rustc-hash 1.1.0", "rustc-hash 1.1.0",

View file

@ -350,6 +350,7 @@ ec4rs = "1.1"
emojis = "0.6.1" emojis = "0.6.1"
env_logger = "0.11" env_logger = "0.11"
exec = "0.3.1" exec = "0.3.1"
fancy-regex = "0.14.0"
fork = "0.2.0" fork = "0.2.0"
futures = "0.3" futures = "0.3"
futures-batch = "0.6.1" futures-batch = "0.6.1"

View file

@ -70,6 +70,7 @@ text.workspace = true
util.workspace = true util.workspace = true
url.workspace = true url.workspace = true
which.workspace = true which.workspace = true
fancy-regex.workspace = true
[target.'cfg(target_os = "windows")'.dependencies] [target.'cfg(target_os = "windows")'.dependencies]
windows.workspace = true windows.workspace = true

View file

@ -1,9 +1,9 @@
use aho_corasick::{AhoCorasick, AhoCorasickBuilder}; use aho_corasick::{AhoCorasick, AhoCorasickBuilder};
use anyhow::Result; use anyhow::Result;
use client::proto; use client::proto;
use fancy_regex::{Captures, Regex, RegexBuilder};
use gpui::Model; use gpui::Model;
use language::{Buffer, BufferSnapshot}; use language::{Buffer, BufferSnapshot};
use regex::{Captures, Regex, RegexBuilder};
use smol::future::yield_now; use smol::future::yield_now;
use std::{ use std::{
borrow::Cow, borrow::Cow,
@ -128,7 +128,6 @@ impl SearchQuery {
let multiline = query.contains('\n') || query.contains("\\n") || query.contains("\\s"); let multiline = query.contains('\n') || query.contains("\\n") || query.contains("\\s");
let regex = RegexBuilder::new(&query) let regex = RegexBuilder::new(&query)
.case_insensitive(!case_sensitive) .case_insensitive(!case_sensitive)
.multi_line(multiline)
.build()?; .build()?;
let inner = SearchInputs { let inner = SearchInputs {
query: initial_query, query: initial_query,
@ -222,12 +221,12 @@ impl SearchQuery {
if let Err(err) = reader.read_to_string(&mut text) { if let Err(err) = reader.read_to_string(&mut text) {
Err(err.into()) Err(err.into())
} else { } else {
Ok(regex.find(&text).is_some()) Ok(regex.find(&text)?.is_some())
} }
} else { } else {
for line in reader.lines() { for line in reader.lines() {
let line = line?; let line = line?;
if regex.find(&line).is_some() { if regex.find(&line)?.is_some() {
return Ok(true); return Ok(true);
} }
} }
@ -332,8 +331,10 @@ impl SearchQuery {
yield_now().await; yield_now().await;
} }
if let Ok(mat) = mat {
matches.push(mat.start()..mat.end()); matches.push(mat.start()..mat.end());
} }
}
} else { } else {
let mut line = String::new(); let mut line = String::new();
let mut line_offset = 0; let mut line_offset = 0;
@ -344,7 +345,7 @@ impl SearchQuery {
for (newline_ix, text) in chunk.split('\n').enumerate() { for (newline_ix, text) in chunk.split('\n').enumerate() {
if newline_ix > 0 { if newline_ix > 0 {
for mat in regex.find_iter(&line) { for mat in regex.find_iter(&line).flatten() {
let start = line_offset + mat.start(); let start = line_offset + mat.start();
let end = line_offset + mat.end(); let end = line_offset + mat.end();
matches.push(start..end); matches.push(start..end);