Repository: helix-editor/helix
File: helix-term/src/commands.rs (Rust)

Code before:
            doc.text(),
            &doc.selection(view.id).clone().cursors(doc.text().slice(..)),
            indent,
        );
        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)
                    }
                }
                KeyEvent {
                    code: KeyCode::Enter,
                    ..
                } => {
                    assert!(count == 1, "inserting multiple newlines not yet supported");
                    insert_newline(cx)
                }
                KeyEvent {
                    code: KeyCode::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(..);

        let contents = doc.text();
        let selection = doc.selection(view.id).clone();
        let mut ranges = SmallVec::with_capacity(selection.len());

        // TODO: this is annoying, but we need to do it to properly calculate pos after edits
        let mut global_offs = 0;

        let mut transaction = Transaction::change_by_selection(contents, &selection, |range| {
            let pos = range.cursor(text);

            let prev = if pos == 0 {

Review comment (suggestion):
Rather than a panic you can set an error in the statusline:

```rust
if count != 1 {
    cx.editor.set_error("inserting multiple newlines not yet supported");
}
```

Code after:
        let transaction = Transaction::insert(
            doc.text(),
            &doc.selection(view.id).clone().cursors(doc.text().slice(..)),
            indent,
        );
        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;
        });
    }