on master help sign in
Implement keep_selections (filter selections on regex).
commitdd91090a1ae931a604c51b9c6d7d8c9b46761af4 authorBlaž Hrastnik <blaz@mxxn.io> dateMon 15 Mar 2021, 17:09 (6 years ago) parent872d770
4 files changed+37−10
helix-core/src/selection.rs+27−8 helix-term/src/commands.rs+9−1 helix-term/src/keymap.rs+1 helix-view/src/editor.rs−1
helix-core/src/selection.rs+27−8
@@ -273,14 +273,33 @@ impl Selection {
273273
274274// TODO: checkSelection -> check if valid for doc length
275275
276+pub fn keep_matches(
277+ text: RopeSlice,
278+ selection: &Selection,
279+ regex: &crate::regex::Regex,
280+) -> Option<Selection> {
281+ let result: SmallVec<_> = selection
282+ .ranges()
283+ .iter()
284+ .filter(|range| regex.is_match(&range.fragment(text)))
285+ .copied()
286+ .collect();
287+
288+ // TODO: figure out a new primary index
289+ if !result.is_empty() {
290+ return Some(Selection::new(result, 0));
291+ }
292+ None
293+}
294+
276295pub fn select_on_matches(
277296 text: RopeSlice,
278− selections: &Selection,
297+ selection: &Selection,
279298 regex: &crate::regex::Regex,
280299) -> Option<Selection> {
281− let mut result = SmallVec::with_capacity(selections.ranges().len());
300+ let mut result = SmallVec::with_capacity(selection.ranges().len());
282301
283− for sel in selections.ranges() {
302+ for sel in selection.ranges() {
284303 // TODO: can't avoid occasional allocations since Regex can't operate on chunks yet
285304 let fragment = sel.fragment(text);
286305
@@ -309,12 +328,12 @@ pub fn select_on_matches(
309328// TODO: support to split on capture #N instead of whole match
310329pub fn split_on_matches(
311330 text: RopeSlice,
312− selections: &Selection,
331+ selection: &Selection,
313332 regex: &crate::regex::Regex,
314333) -> Selection {
315− let mut result = SmallVec::with_capacity(selections.ranges().len());
334+ let mut result = SmallVec::with_capacity(selection.ranges().len());
316335
317− for sel in selections.ranges() {
336+ for sel in selection.ranges() {
318337 // TODO: can't avoid occasional allocations since Regex can't operate on chunks yet
319338 let fragment = sel.fragment(text);
320339
@@ -417,9 +436,9 @@ mod test {
417436
418437 let text = Rope::from("abcd efg wrs xyz 123 456");
419438
420− let selections = Selection::new(smallvec![Range::new(0, 8), Range::new(10, 19),], 0);
439+ let selection = Selection::new(smallvec![Range::new(0, 8), Range::new(10, 19),], 0);
421440
422− let result = split_on_matches(text.slice(..), &selections, &Regex::new(r"\s+").unwrap());
441+ let result = split_on_matches(text.slice(..), &selection, &Regex::new(r"\s+").unwrap());
423442
424443 assert_eq!(
425444 result.ranges(),
helix-term/src/commands.rs+9−1
@@ -1156,7 +1156,15 @@ pub fn join_selections(cx: &mut Context) {
11561156pub fn keep_selections(cx: &mut Context) {
11571157 let doc = cx.doc();
11581158 // keep selections matching regex
1159− // and another method for inverse
1159+ let prompt = ui::regex_prompt(cx, "keep:".to_string(), |doc, regex| {
1160+ let text = doc.text().slice(..);
1161+
1162+ if let Some(selection) = selection::keep_matches(text, doc.selection(), &regex) {
1163+ doc.set_selection(selection);
1164+ }
1165+ });
1166+
1167+ cx.push_layer(Box::new(prompt));
11601168}
11611169
11621170//
helix-term/src/keymap.rs+1
@@ -207,6 +207,7 @@ pub fn default() -> Keymaps {
207207 key!('<') => commands::unindent,
208208 key!('=') => commands::format_selections,
209209 shift!('J') => commands::join_selections,
210+ // TODO: conflicts hover/doc
210211 shift!('K') => commands::keep_selections,
211212
212213 // key!('q') => commands::record_macro,
helix-view/src/editor.rs−1
@@ -44,7 +44,6 @@ impl Editor {
4444 .and_then(|language| self.language_servers.get(language, &executor));
4545
4646 if let Some(language_server) = language_server {
47− // TODO: do this everywhere
4847 doc.set_language_server(Some(language_server.clone()));
4948
5049 smol::block_on(language_server.text_document_did_open(