Z 1200/replace in buffer (#2922)
This is still WIP, mostly pending styling. I added a pretty rudimentary text field and no buttons whatsoever other than that. I am targeting a Preview of 09.13, as I am gonna be on PTO for the next week. I dislike the current implementation slightly because of `regex`'s crate syntax and lack of support of backreferences. What strikes me as odd wrt to syntax is that it will just replace a capture name with empty string if that capture is missing from the regex. While this is perfectly fine behaviour for conditionally-matched capture groups (e.g. `(foo)?`), I think it should still error out if there's no group with a given name (conditional or not). Release Notes: - Added "Replace" functionality to buffer search.
This commit is contained in:
parent
c545788168
commit
4cb8647702
11 changed files with 471 additions and 96 deletions
|
@ -7,6 +7,7 @@ use language::{char_kind, BufferSnapshot};
|
|||
use regex::{Regex, RegexBuilder};
|
||||
use smol::future::yield_now;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
io::{BufRead, BufReader, Read},
|
||||
ops::Range,
|
||||
path::{Path, PathBuf},
|
||||
|
@ -35,6 +36,7 @@ impl SearchInputs {
|
|||
pub enum SearchQuery {
|
||||
Text {
|
||||
search: Arc<AhoCorasick<usize>>,
|
||||
replacement: Option<String>,
|
||||
whole_word: bool,
|
||||
case_sensitive: bool,
|
||||
inner: SearchInputs,
|
||||
|
@ -42,7 +44,7 @@ pub enum SearchQuery {
|
|||
|
||||
Regex {
|
||||
regex: Regex,
|
||||
|
||||
replacement: Option<String>,
|
||||
multiline: bool,
|
||||
whole_word: bool,
|
||||
case_sensitive: bool,
|
||||
|
@ -95,6 +97,7 @@ impl SearchQuery {
|
|||
};
|
||||
Self::Text {
|
||||
search: Arc::new(search),
|
||||
replacement: None,
|
||||
whole_word,
|
||||
case_sensitive,
|
||||
inner,
|
||||
|
@ -130,6 +133,7 @@ impl SearchQuery {
|
|||
};
|
||||
Ok(Self::Regex {
|
||||
regex,
|
||||
replacement: None,
|
||||
multiline,
|
||||
whole_word,
|
||||
case_sensitive,
|
||||
|
@ -156,7 +160,21 @@ impl SearchQuery {
|
|||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_replacement(mut self, new_replacement: Option<String>) -> Self {
|
||||
match self {
|
||||
Self::Text {
|
||||
ref mut replacement,
|
||||
..
|
||||
}
|
||||
| Self::Regex {
|
||||
ref mut replacement,
|
||||
..
|
||||
} => {
|
||||
*replacement = new_replacement;
|
||||
self
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn to_proto(&self, project_id: u64) -> proto::SearchProject {
|
||||
proto::SearchProject {
|
||||
project_id,
|
||||
|
@ -214,7 +232,20 @@ impl SearchQuery {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replacement<'a>(&self, text: &'a str) -> Option<Cow<'a, str>> {
|
||||
match self {
|
||||
SearchQuery::Text { replacement, .. } => replacement.clone().map(Cow::from),
|
||||
SearchQuery::Regex {
|
||||
regex, replacement, ..
|
||||
} => {
|
||||
if let Some(replacement) = replacement {
|
||||
Some(regex.replace(text, replacement))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pub async fn search(
|
||||
&self,
|
||||
buffer: &BufferSnapshot,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue