fix: fix issue with \ preceding pattern items
With the current implementation of pattern items, it's impossible to search for strings like `\c` in buffers as, even when using `\\c`, the `\c` suffix will be interpreted as a pattern item. This commit updates the regex used to find the pattern items so as to ensure that the preceding character is never a `\` and, if it is, it's considered that the user is searching for a slash instead of trying to use a pattern item.
This commit is contained in:
parent
09470b9d57
commit
f7473c80ae
3 changed files with 28 additions and 14 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -14568,12 +14568,12 @@ dependencies = [
|
||||||
"client",
|
"client",
|
||||||
"collections",
|
"collections",
|
||||||
"editor",
|
"editor",
|
||||||
|
"fancy-regex 0.14.0",
|
||||||
"futures 0.3.31",
|
"futures 0.3.31",
|
||||||
"gpui",
|
"gpui",
|
||||||
"language",
|
"language",
|
||||||
"menu",
|
"menu",
|
||||||
"project",
|
"project",
|
||||||
"regex",
|
|
||||||
"schemars",
|
"schemars",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
|
|
@ -42,7 +42,7 @@ util.workspace = true
|
||||||
workspace.workspace = true
|
workspace.workspace = true
|
||||||
zed_actions.workspace = true
|
zed_actions.workspace = true
|
||||||
workspace-hack.workspace = true
|
workspace-hack.workspace = true
|
||||||
regex.workspace = true
|
fancy-regex.workspace = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
client = { workspace = true, features = ["test-support"] }
|
client = { workspace = true, features = ["test-support"] }
|
||||||
|
|
|
@ -13,6 +13,7 @@ use editor::{
|
||||||
DisplayPoint, Editor, EditorSettings,
|
DisplayPoint, Editor, EditorSettings,
|
||||||
actions::{Backtab, Tab},
|
actions::{Backtab, Tab},
|
||||||
};
|
};
|
||||||
|
use fancy_regex::Regex;
|
||||||
use futures::channel::oneshot;
|
use futures::channel::oneshot;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
Action, App, ClickEvent, Context, Entity, EventEmitter, Focusable, InteractiveElement as _,
|
Action, App, ClickEvent, Context, Entity, EventEmitter, Focusable, InteractiveElement as _,
|
||||||
|
@ -24,7 +25,6 @@ use project::{
|
||||||
search::SearchQuery,
|
search::SearchQuery,
|
||||||
search_history::{SearchHistory, SearchHistoryCursor},
|
search_history::{SearchHistory, SearchHistoryCursor},
|
||||||
};
|
};
|
||||||
use regex::Regex;
|
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
|
@ -54,8 +54,8 @@ const MAX_BUFFER_SEARCH_HISTORY_SIZE: usize = 50;
|
||||||
// TODO: Should this be updated to an HashMap so we can easily determine the
|
// TODO: Should this be updated to an HashMap so we can easily determine the
|
||||||
// search option for a given pattern?
|
// search option for a given pattern?
|
||||||
static PATTERN_ITEMS: [(&str, &SearchOptions, bool); 2] = [
|
static PATTERN_ITEMS: [(&str, &SearchOptions, bool); 2] = [
|
||||||
("\\c", &SearchOptions::CASE_SENSITIVE, false),
|
("c", &SearchOptions::CASE_SENSITIVE, false),
|
||||||
("\\C", &SearchOptions::CASE_SENSITIVE, true),
|
("C", &SearchOptions::CASE_SENSITIVE, true),
|
||||||
];
|
];
|
||||||
|
|
||||||
/// Opens the buffer search interface with the specified configuration.
|
/// Opens the buffer search interface with the specified configuration.
|
||||||
|
@ -661,13 +661,13 @@ impl BufferSearchBar {
|
||||||
.detach_and_log_err(cx);
|
.detach_and_log_err(cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
let pattern_items_regex = Regex::new(
|
let pattern_items_regex = Regex::new(&format!(
|
||||||
&PATTERN_ITEMS
|
r"(?<!\\)(\\[{}])",
|
||||||
|
PATTERN_ITEMS
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(pattern, _, _)| regex::escape(pattern))
|
.map(|(pattern, _, _)| *pattern)
|
||||||
.collect::<Vec<_>>()
|
.collect::<String>()
|
||||||
.join("|"),
|
))
|
||||||
)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
@ -1528,13 +1528,16 @@ impl BufferSearchBar {
|
||||||
let mut pattern_item_options = Vec::new();
|
let mut pattern_item_options = Vec::new();
|
||||||
let query = self.raw_query(cx);
|
let query = self.raw_query(cx);
|
||||||
|
|
||||||
|
// TODO: Maybe avoid so many unwrap/expect calls here.
|
||||||
self.pattern_items_regex
|
self.pattern_items_regex
|
||||||
.captures_iter(&query)
|
.captures_iter(&query)
|
||||||
.map(|capture| capture.extract())
|
.map(|capture| capture.unwrap())
|
||||||
.map(|(str, [])| {
|
.map(|capture| {
|
||||||
|
let pattern_item = capture.get(1).unwrap().as_str();
|
||||||
|
|
||||||
PATTERN_ITEMS
|
PATTERN_ITEMS
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(pattern, _, _)| *pattern == str)
|
.find(|(pattern, _, _)| pattern_item.ends_with(*pattern))
|
||||||
.expect("should only capture valid pattern items")
|
.expect("should only capture valid pattern items")
|
||||||
})
|
})
|
||||||
.for_each(|(_, search_option, value)| {
|
.for_each(|(_, search_option, value)| {
|
||||||
|
@ -3079,6 +3082,17 @@ mod tests {
|
||||||
"Should have case sensitivity enabled when all pattern items are removed and original search options are restored"
|
"Should have case sensitivity enabled when all pattern items are removed and original search options are restored"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
cx.simulate_input("\\\\c");
|
||||||
|
cx.run_until_parked();
|
||||||
|
search_bar.update(cx, |search_bar, cx| {
|
||||||
|
assert_eq!(search_bar.raw_query(cx), "test\\\\c");
|
||||||
|
assert_eq!(
|
||||||
|
search_bar.search_options,
|
||||||
|
SearchOptions::REGEX | SearchOptions::CASE_SENSITIVE,
|
||||||
|
"Should still have case sensitivity enabled when pattern item is preceded by another \\"
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_search_settings(search_settings: SearchSettings, cx: &mut TestAppContext) {
|
fn update_search_settings(search_settings: SearchSettings, cx: &mut TestAppContext) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue