Implement keep_selections (filter selections on regex).

pull/8/head
Blaž Hrastnik 4 years ago
parent 872d770753
commit dd91090a1a

@ -273,14 +273,33 @@ impl Selection {
// TODO: checkSelection -> check if valid for doc length // TODO: checkSelection -> check if valid for doc length
pub fn keep_matches(
text: RopeSlice,
selection: &Selection,
regex: &crate::regex::Regex,
) -> Option<Selection> {
let result: SmallVec<_> = selection
.ranges()
.iter()
.filter(|range| regex.is_match(&range.fragment(text)))
.copied()
.collect();
// TODO: figure out a new primary index
if !result.is_empty() {
return Some(Selection::new(result, 0));
}
None
}
pub fn select_on_matches( pub fn select_on_matches(
text: RopeSlice, text: RopeSlice,
selections: &Selection, selection: &Selection,
regex: &crate::regex::Regex, regex: &crate::regex::Regex,
) -> Option<Selection> { ) -> Option<Selection> {
let mut result = SmallVec::with_capacity(selections.ranges().len()); let mut result = SmallVec::with_capacity(selection.ranges().len());
for sel in selections.ranges() { for sel in selection.ranges() {
// TODO: can't avoid occasional allocations since Regex can't operate on chunks yet // TODO: can't avoid occasional allocations since Regex can't operate on chunks yet
let fragment = sel.fragment(text); let fragment = sel.fragment(text);
@ -309,12 +328,12 @@ pub fn select_on_matches(
// TODO: support to split on capture #N instead of whole match // TODO: support to split on capture #N instead of whole match
pub fn split_on_matches( pub fn split_on_matches(
text: RopeSlice, text: RopeSlice,
selections: &Selection, selection: &Selection,
regex: &crate::regex::Regex, regex: &crate::regex::Regex,
) -> Selection { ) -> Selection {
let mut result = SmallVec::with_capacity(selections.ranges().len()); let mut result = SmallVec::with_capacity(selection.ranges().len());
for sel in selections.ranges() { for sel in selection.ranges() {
// TODO: can't avoid occasional allocations since Regex can't operate on chunks yet // TODO: can't avoid occasional allocations since Regex can't operate on chunks yet
let fragment = sel.fragment(text); let fragment = sel.fragment(text);
@ -417,9 +436,9 @@ mod test {
let text = Rope::from("abcd efg wrs xyz 123 456"); let text = Rope::from("abcd efg wrs xyz 123 456");
let selections = Selection::new(smallvec![Range::new(0, 8), Range::new(10, 19),], 0); let selection = Selection::new(smallvec![Range::new(0, 8), Range::new(10, 19),], 0);
let result = split_on_matches(text.slice(..), &selections, &Regex::new(r"\s+").unwrap()); let result = split_on_matches(text.slice(..), &selection, &Regex::new(r"\s+").unwrap());
assert_eq!( assert_eq!(
result.ranges(), result.ranges(),

@ -1156,7 +1156,15 @@ pub fn join_selections(cx: &mut Context) {
pub fn keep_selections(cx: &mut Context) { pub fn keep_selections(cx: &mut Context) {
let doc = cx.doc(); let doc = cx.doc();
// keep selections matching regex // keep selections matching regex
// and another method for inverse let prompt = ui::regex_prompt(cx, "keep:".to_string(), |doc, regex| {
let text = doc.text().slice(..);
if let Some(selection) = selection::keep_matches(text, doc.selection(), &regex) {
doc.set_selection(selection);
}
});
cx.push_layer(Box::new(prompt));
} }
// //

@ -207,6 +207,7 @@ pub fn default() -> Keymaps {
key!('<') => commands::unindent, key!('<') => commands::unindent,
key!('=') => commands::format_selections, key!('=') => commands::format_selections,
shift!('J') => commands::join_selections, shift!('J') => commands::join_selections,
// TODO: conflicts hover/doc
shift!('K') => commands::keep_selections, shift!('K') => commands::keep_selections,
// key!('q') => commands::record_macro, // key!('q') => commands::record_macro,

@ -44,7 +44,6 @@ impl Editor {
.and_then(|language| self.language_servers.get(language, &executor)); .and_then(|language| self.language_servers.get(language, &executor));
if let Some(language_server) = language_server { if let Some(language_server) = language_server {
// TODO: do this everywhere
doc.set_language_server(Some(language_server.clone())); doc.set_language_server(Some(language_server.clone()));
smol::block_on(language_server.text_document_did_open( smol::block_on(language_server.text_document_did_open(

Loading…
Cancel
Save