on master help sign in
Implement keep_selections (filter selections on regex).
dd91090Blaž Hrastnik
helix-core/src/selection.rs+27−8
@@ -273,14 +273,33 @@ impl Selection {
273
273
274// TODO: checkSelection -> check if valid for doc length
274// TODO: checkSelection -> check if valid for doc length
275
275
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+
276pub fn select_on_matches(
295pub fn select_on_matches(
277 text: RopeSlice,
296 text: RopeSlice,
278− selections: &Selection,
297+ selection: &Selection,
279 regex: &crate::regex::Regex,
298 regex: &crate::regex::Regex,
280) -> Option<Selection> {
299) -> Option<Selection> {
281− let mut result = SmallVec::with_capacity(selections.ranges().len());
300+ let mut result = SmallVec::with_capacity(selection.ranges().len());
282
301
283− for sel in selections.ranges() {
302+ for sel in selection.ranges() {
284 // TODO: can't avoid occasional allocations since Regex can't operate on chunks yet
303 // TODO: can't avoid occasional allocations since Regex can't operate on chunks yet
285 let fragment = sel.fragment(text);
304 let fragment = sel.fragment(text);
286
305
@@ -309,12 +328,12 @@ pub fn select_on_matches(
309// TODO: support to split on capture #N instead of whole match
328// TODO: support to split on capture #N instead of whole match
310pub fn split_on_matches(
329pub fn split_on_matches(
311 text: RopeSlice,
330 text: RopeSlice,
312− selections: &Selection,
331+ selection: &Selection,
313 regex: &crate::regex::Regex,
332 regex: &crate::regex::Regex,
314) -> Selection {
333) -> Selection {
315− let mut result = SmallVec::with_capacity(selections.ranges().len());
334+ let mut result = SmallVec::with_capacity(selection.ranges().len());
316
335
317− for sel in selections.ranges() {
336+ for sel in selection.ranges() {
318 // TODO: can't avoid occasional allocations since Regex can't operate on chunks yet
337 // TODO: can't avoid occasional allocations since Regex can't operate on chunks yet
319 let fragment = sel.fragment(text);
338 let fragment = sel.fragment(text);
320
339
@@ -417,9 +436,9 @@ mod test {
417
436
418 let text = Rope::from("abcd efg wrs xyz 123 456");
437 let text = Rope::from("abcd efg wrs xyz 123 456");
419
438
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);
421
440
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());
423
442
424 assert_eq!(
443 assert_eq!(
425 result.ranges(),
444 result.ranges(),
helix-term/src/commands.rs+9−1
@@ -1156,7 +1156,15 @@ pub fn join_selections(cx: &mut Context) {
1156pub fn keep_selections(cx: &mut Context) {
1156pub fn keep_selections(cx: &mut Context) {
1157 let doc = cx.doc();
1157 let doc = cx.doc();
1158 // keep selections matching regex
1158 // 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));
1160}
1168}
1161
1169
1162//
1170//
helix-term/src/keymap.rs+1
@@ -207,6 +207,7 @@ pub fn default() -> Keymaps {
207 key!('<') => commands::unindent,
207 key!('<') => commands::unindent,
208 key!('=') => commands::format_selections,
208 key!('=') => commands::format_selections,
209 shift!('J') => commands::join_selections,
209 shift!('J') => commands::join_selections,
210+ // TODO: conflicts hover/doc
210 shift!('K') => commands::keep_selections,
211 shift!('K') => commands::keep_selections,
211
212
212 // key!('q') => commands::record_macro,
213 // key!('q') => commands::record_macro,
helix-view/src/editor.rs−1
@@ -44,7 +44,6 @@ impl Editor {
44 .and_then(|language| self.language_servers.get(language, &executor));
44 .and_then(|language| self.language_servers.get(language, &executor));
45
45
46 if let Some(language_server) = language_server {
46 if let Some(language_server) = language_server {
47− // TODO: do this everywhere
48 doc.set_language_server(Some(language_server.clone()));
47 doc.set_language_server(Some(language_server.clone()));
49
48
50 smol::block_on(language_server.text_document_did_open(
49 smol::block_on(language_server.text_document_did_open(