diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs index e9d3a28ff..995ca9e2a 100644 --- a/helix-term/src/commands.rs +++ b/helix-term/src/commands.rs @@ -397,6 +397,7 @@ impl MappableCommand { smart_tab, "Insert tab if all cursors have all whitespace to their left; otherwise, run a separate command.", insert_tab, "Insert tab char", insert_newline, "Insert newline char", + insert_char_interactive, "Insert an interactively-chosen char", delete_char_backward, "Delete previous char", delete_char_forward, "Delete next char", delete_word_backward, "Delete previous word", @@ -3727,7 +3728,7 @@ fn hunk_range(hunk: Hunk, text: RopeSlice) -> Range { } pub mod insert { - use crate::events::PostInsertChar; + use crate::{events::PostInsertChar, key}; use super::*; pub type Hook = fn(&Rope, &Selection, char) -> Option; @@ -3802,11 +3803,15 @@ pub mod insert { } pub fn insert_tab(cx: &mut Context) { + insert_tab_impl(cx, 1) + } + + fn insert_tab_impl(cx: &mut Context, count: usize) { let (view, doc) = current!(cx.editor); // TODO: round out to nearest indentation level (for example a line with 3 spaces should // indent by one to reach 4 spaces). - let indent = Tendril::from(doc.indent_style.as_str()); + let indent = Tendril::from(doc.indent_style.as_str().repeat(count)); let transaction = Transaction::insert( doc.text(), &doc.selection(view.id).clone().cursors(doc.text().slice(..)), @@ -3815,6 +3820,34 @@ pub mod insert { doc.apply(&transaction, view.id); } + pub fn insert_char_interactive(cx: &mut Context) { + let count = cx.count(); + + // need to wait for next key + cx.on_next_key(move |cx, event| { + match event { + KeyEvent { + code: KeyCode::Char(ch), + .. + } => { + for _ in 0..count { + insert::insert_char(cx, ch) + } + } + key!(Enter) => { + if count != 1 { + cx.editor + .set_error("inserting multiple newlines not yet supported"); + return; + } + insert_newline(cx) + } + key!(Tab) => insert_tab_impl(cx, count), + _ => (), + }; + }); + } + pub fn insert_newline(cx: &mut Context) { let (view, doc) = current_ref!(cx.editor); let text = doc.text().slice(..);