Unnamed repository; edit this file 'description' to name the repository.
add `insert_character_interactive` command (#11411)
jyn 7 months ago
parent 1941f0b · commit c8224bc
-rw-r--r--helix-term/src/commands.rs53
1 files changed, 51 insertions, 2 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index a3417ea1..7f2e7ce9 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -472,6 +472,8 @@ 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",
+ append_char_interactive, "Append an interactively-chosen char",
delete_char_backward, "Delete previous char",
delete_char_forward, "Delete next char",
delete_word_backward, "Delete previous word",
@@ -4104,7 +4106,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<Transaction>;
@@ -4183,11 +4185,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(..)),
@@ -4196,6 +4202,49 @@ pub mod insert {
doc.apply(&transaction, view.id);
}
+ pub fn append_char_interactive(cx: &mut Context) {
+ // Save the current mode, so we can restore it later.
+ let mode = cx.editor.mode;
+ append_mode(cx);
+ insert_selection_interactive(cx, mode);
+ }
+
+ pub fn insert_char_interactive(cx: &mut Context) {
+ let mode = cx.editor.mode;
+ insert_mode(cx);
+ insert_selection_interactive(cx, mode);
+ }
+
+ fn insert_selection_interactive(cx: &mut Context, old_mode: Mode) {
+ 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),
+ _ => (),
+ };
+ // Restore the old mode.
+ cx.editor.mode = old_mode;
+ });
+ }
+
pub fn insert_newline(cx: &mut Context) {
let config = cx.editor.config();
let (view, doc) = current_ref!(cx.editor);