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

Code before:
                text.push(' ');
            }
        }

        let text = text.repeat(count);

        // calculate new selection ranges
        let pos = offs + line_end_index + line_end_offset_width;
        for i in 0..count {
            // pos                    -> beginning of reference line,
            // + (i * (1+indent_len)) -> beginning of i'th line from pos
            // + indent_len ->        -> indent for i'th line
            ranges.push(Range::point(pos + (i * (1 + indent_len)) + indent_len));
        }

        offs += text.chars().count();

        (line_end_index, line_end_index, Some(text.into()))
    });

    transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index()));

    doc.apply(&transaction, view.id);

    // Since we might have added a comment token, move to the end of the line.
    goto_line_end_newline(cx);
}

// o inserts a new line after each line with a selection
fn open_below(cx: &mut Context) {
    open(cx, Open::Below)
}

// O inserts a new line before each line with a selection
fn open_above(cx: &mut Context) {
    open(cx, Open::Above)
}

fn normal_mode(cx: &mut Context) {
    cx.editor.enter_normal_mode();
}

// Store a jump on the jumplist.
fn push_jump(view: &mut View, doc: &Document) {
    let jump = (doc.id(), doc.selection(view.id).clone());
    view.jumps.push(jump);
}

fn goto_line(cx: &mut Context) {
    if cx.count.is_some() {
        let (view, doc) = current!(cx.editor);

Review comment (suggestion):
Rather than jumping to the end of the line we should update the selection ranges based on how much we're inserting in the block above with the "calculate new selection ranges" comment. I think the final formula there should be `pos + (i * (1 + indent_len + comment_len)) + indent_len + comment_len` where `comment_len` is

```rust
let comment_len = continue_comment_token.map(|token| token.len() + 1).unwrap_or_default();
```

(+ 1 for the extra space added).

Code after:
            .map(|token| token.len() + 1) // `+ 1` for the extra space added
            .unwrap_or_default();
        for i in 0..count {
            // pos                    -> beginning of reference line,
            // + (i * (1+indent_len + comment_len)) -> beginning of i'th line from pos (possibly including comment token)
            // + indent_len + comment_len ->        -> indent for i'th line
            ranges.push(Range::point(
                pos + (i * (1 + indent_len + comment_len)) + indent_len + comment_len,
            ));
        }

        offs += text.chars().count();

        (line_end_index, line_end_index, Some(text.into()))
    });

    transaction = transaction.with_selection(Selection::new(ranges, selection.primary_index()));

    doc.apply(&transaction, view.id);
}

// o inserts a new line after each line with a selection
fn open_below(cx: &mut Context) {
    open(cx, Open::Below)
}

// O inserts a new line before each line with a selection
fn open_above(cx: &mut Context) {
    open(cx, Open::Above)
}

fn normal_mode(cx: &mut Context) {
    cx.editor.enter_normal_mode();
}

// Store a jump on the jumplist.
fn push_jump(view: &mut View, doc: &Document) {
    let jump = (doc.id(), doc.selection(view.id).clone());
    view.jumps.push(jump);
}

fn goto_line(cx: &mut Context) {
    if cx.count.is_some() {
        let (view, doc) = current!(cx.editor);
        push_jump(view, doc);

        goto_line_without_jumplist(cx.editor, cx.count);
    }
}

fn goto_line_without_jumplist(editor: &mut Editor, count: Option<NonZeroUsize>) {