From c68fe1f2a3a40c37969c1f5d18e3134320a0c773 Mon Sep 17 00:00:00 2001 From: Gokul Soumya Date: Sat, 3 Jul 2021 06:37:49 +0530 Subject: Add object selection (textobjects) (#385) * Add textobjects for word * Add textobjects for surround characters * Apply clippy lints * Remove ThisWordPrevBound in favor of PrevWordEnd It's the same as PrevWordEnd except for taking the current char into account, so use a "flag" to capture that usecase * Add tests for PrevWordEnd movement * Remove ThisWord* movements They did not preserve anchor positions and were only used for textobject boundary search anyway so replace them with simple position finding functions * Rewrite tests of word textobject * Add tests for surround textobject * Add textobject docs * Refactor textobject word position functions * Apply clippy lints on textobject * Fix overflow error with textobjects--- helix-term/src/commands.rs | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'helix-term/src') diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index 860d8e22..d198b803 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -3502,6 +3502,9 @@ fn right_bracket_mode(cx: &mut Context) { }) } +use helix_core::surround; +use helix_core::textobject; + fn match_mode(cx: &mut Context) { let count = cx.count; cx.on_next_key(move |cx, event| { @@ -3517,13 +3520,40 @@ fn match_mode(cx: &mut Context) { 's' => surround_add(cx), 'r' => surround_replace(cx), 'd' => surround_delete(cx), + 'a' => select_textobject(cx, textobject::TextObject::Around), + 'i' => select_textobject(cx, textobject::TextObject::Inside), _ => (), } } }) } -use helix_core::surround; +fn select_textobject(cx: &mut Context, objtype: textobject::TextObject) { + let count = cx.count(); + cx.on_next_key(move |cx, event| { + if let KeyEvent { + code: KeyCode::Char(ch), + .. + } = event + { + let (view, doc) = current!(cx.editor); + let text = doc.text().slice(..); + + let selection = doc.selection(view.id).transform(|range| { + match ch { + 'w' => textobject::textobject_word(text, range, objtype, count), + // TODO: cancel new ranges if inconsistent surround matches across lines + ch if !ch.is_ascii_alphanumeric() => { + textobject::textobject_surround(text, range, objtype, ch, count) + } + _ => range, + } + }); + + doc.set_selection(view.id, selection); + } + }) +} fn surround_add(cx: &mut Context) { cx.on_next_key(move |cx, event| { -- cgit v1.2.3-70-g09d2