on master help sign in
Add `remove_selections` command (#1065)
bf95a9eOmnikar
book/src/keymap.md+1
@@ -101,6 +101,7 @@
101| | Expand selection to parent syntax node TODO: pick a key | `expand_selection` |
101| | Expand selection to parent syntax node TODO: pick a key | `expand_selection` |
102| `J` | Join lines inside selection | `join_selections` |
102| `J` | Join lines inside selection | `join_selections` |
103| `K` | Keep selections matching the regex | `keep_selections` |
103| `K` | Keep selections matching the regex | `keep_selections` |
104+| `Alt-K` | Remove selections matching the regex | `remove_selections` |
104| `$` | Pipe each selection into shell command, keep selections where command returned 0 | `shell_keep_pipe` |
105| `$` | Pipe each selection into shell command, keep selections where command returned 0 | `shell_keep_pipe` |
105| `Ctrl-c` | Comment/uncomment the selections | `toggle_comments` |
106| `Ctrl-c` | Comment/uncomment the selections | `toggle_comments` |
106
107
helix-core/src/selection.rs+3−2
@@ -528,14 +528,15 @@ impl<'a> IntoIterator for &'a Selection {
528
528
529// TODO: checkSelection -> check if valid for doc length && sorted
529// TODO: checkSelection -> check if valid for doc length && sorted
530
530
531−pub fn keep_matches(
531+pub fn keep_or_remove_matches(
532 text: RopeSlice,
532 text: RopeSlice,
533 selection: &Selection,
533 selection: &Selection,
534 regex: &crate::regex::Regex,
534 regex: &crate::regex::Regex,
535+ remove: bool,
535) -> Option<Selection> {
536) -> Option<Selection> {
536 let result: SmallVec<_> = selection
537 let result: SmallVec<_> = selection
537 .iter()
538 .iter()
538− .filter(|range| regex.is_match(&range.fragment(text)))
539+ .filter(|range| regex.is_match(&range.fragment(text)) ^ remove)
539 .copied()
540 .copied()
540 .collect();
541 .collect();
541
542
helix-term/src/commands.rs+15−4
@@ -302,6 +302,7 @@ impl Command {
302 format_selections, "Format selection",
302 format_selections, "Format selection",
303 join_selections, "Join lines inside selection",
303 join_selections, "Join lines inside selection",
304 keep_selections, "Keep selections matching regex",
304 keep_selections, "Keep selections matching regex",
305+ remove_selections, "Remove selections matching regex",
305 keep_primary_selection, "Keep primary selection",
306 keep_primary_selection, "Keep primary selection",
306 remove_primary_selection, "Remove primary selection",
307 remove_primary_selection, "Remove primary selection",
307 completion, "Invoke completion popup",
308 completion, "Invoke completion popup",
@@ -4320,12 +4321,12 @@ fn join_selections(cx: &mut Context) {
4320 doc.append_changes_to_history(view.id);
4321 doc.append_changes_to_history(view.id);
4321}
4322}
4322
4323
4323−fn keep_selections(cx: &mut Context) {
4324+fn keep_or_remove_selections_impl(cx: &mut Context, remove: bool) {
4324− // keep selections matching regex
4325+ // keep or remove selections matching regex
4325 let reg = cx.register.unwrap_or('/');
4326 let reg = cx.register.unwrap_or('/');
4326 let prompt = ui::regex_prompt(
4327 let prompt = ui::regex_prompt(
4327 cx,
4328 cx,
4328− "keep:".into(),
4329+ if !remove { "keep:" } else { "remove:" }.into(),
4329 Some(reg),
4330 Some(reg),
4330 |_input: &str| Vec::new(),
4331 |_input: &str| Vec::new(),
4331 move |view, doc, regex, event| {
4332 move |view, doc, regex, event| {
@@ -4334,7 +4335,9 @@ fn keep_selections(cx: &mut Context) {
4334 }
4335 }
4335 let text = doc.text().slice(..);
4336 let text = doc.text().slice(..);
4336
4337
4338+ if let Some(selection) =
4337− if let Some(selection) = selection::keep_matches(text, doc.selection(view.id), &regex) {
4339+ selection::keep_or_remove_matches(text, doc.selection(view.id), &regex, remove)
4340+ {
4338 doc.set_selection(view.id, selection);
4341 doc.set_selection(view.id, selection);
4339 }
4342 }
4340 },
4343 },
@@ -4343,6 +4346,14 @@ fn keep_selections(cx: &mut Context) {
4343 cx.push_layer(Box::new(prompt));
4346 cx.push_layer(Box::new(prompt));
4344}
4347}
4345
4348
4349+fn keep_selections(cx: &mut Context) {
4350+ keep_or_remove_selections_impl(cx, false)
4351+}
4352+
4353+fn remove_selections(cx: &mut Context) {
4354+ keep_or_remove_selections_impl(cx, true)
4355+}
4356+
4346fn keep_primary_selection(cx: &mut Context) {
4357fn keep_primary_selection(cx: &mut Context) {
4347 let (view, doc) = current!(cx.editor);
4358 let (view, doc) = current!(cx.editor);
4348 // TODO: handle count
4359 // TODO: handle count
helix-term/src/keymap.rs+1−1
@@ -577,7 +577,7 @@ impl Default for Keymaps {
577 "=" => format_selections,
577 "=" => format_selections,
578 "J" => join_selections,
578 "J" => join_selections,
579 "K" => keep_selections,
579 "K" => keep_selections,
580− // TODO: and another method for inverse
580+ "A-K" => remove_selections,
581
581
582 "," => keep_primary_selection,
582 "," => keep_primary_selection,
583 "A-," => remove_primary_selection,
583 "A-," => remove_primary_selection,