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

Code before:
                        } else {
                            from
                        }
                    } else {
                        let to = primary_selection.to();
                        if range.anchor > to {
                            range.anchor
                        } else {
                            to
                        }
                    };
                    range = Range::new(anchor, range.head);
                }
                doc_mut!(cx.editor, &doc).set_selection(view, range.into());
            }
        });
    });
}

fn jump_to_word(cx: &mut Context, extend: bool) {
    // Calculate the jump candidates: ranges for any visible words with two or
    // more characters.
    let alphabet = &cx.editor.config().jump_label_alphabet;
    let jump_label_limit = alphabet.len() * alphabet.len();
    let mut words = Vec::with_capacity(jump_label_limit);
    let (view, doc) = current!(cx.editor);
    let text = doc.text().slice(..);

    // This is not necessarily exact if there is virtual text like soft wrap.
    // It's ok though because the extra jump labels will not be rendered.
    let start = text.line_to_char(text.char_to_line(view.offset.anchor));
    let end = text.line_to_char(view.estimate_last_doc_line(doc) + 1);

    let primary_selection = doc.selection(view.id).primary();
    let cursor = primary_selection.cursor(text);
    let cursor_fwd = movement::move_prev_word_start(text, Range::point(cursor), 1);
    let mut cursor_fwd = if cursor_fwd.anchor == cursor {
        Range::point(cursor_fwd.head)
    } else {
        Range::point(cursor)
    };
    let mut cursor_rev = cursor_fwd;
    loop {
        let mut changed = false;
        if cursor_fwd.head < end {
            cursor_fwd = movement::move_next_word_end(text, cursor_fwd, 1);
            let range = movement::move_prev_word_start(text, cursor_fwd, 1);
            // The cursor is on a word longer than 2 characters.
            if RopeGraphemes::new(text.slice(range.head..))
                .take(2)
                .all(|g| g.chars().all(char_is_word))

Review comment (suggestion):
```suggestion
    let (view, doc) = current_ref!(cx.editor);
```

Code after:
    let alphabet_char = |i| {
        let mut res = Tendril::new();
        res.push(alphabet[i]);
        res
    };

    // Add label for each jump candidate to the View as virtual text.
    let text = doc.text().slice(..);
    let mut overlays: Vec<_> = labels
        .iter()
        .enumerate()
        .flat_map(|(i, range)| {
            [
                Overlay::new(range.from(), alphabet_char(i / alphabet.len())),
                Overlay::new(
                    graphemes::next_grapheme_boundary(text, range.from()),
                    alphabet_char(i % alphabet.len()),
                ),
            ]
        })
        .collect();
    overlays.sort_unstable_by_key(|overlay| overlay.char_idx);
    let (view, doc) = current!(cx.editor);
    doc.set_jump_labels(view.id, overlays);

    // Accept two characters matching a visible label. Jump to the candidate
    // for that label if it exists.
    let primary_selection = doc.selection(view.id).primary();
    let view = view.id;
    let doc = doc.id();
    cx.on_next_key(move |cx, event| {
        let alphabet = &cx.editor.config().jump_label_alphabet;
        let Some(i ) = event.char().and_then(|ch| alphabet.iter().position(|&it| it == ch)) else {
            doc_mut!(cx.editor, &doc).remove_jump_labels(view);
            return;
        };
        let outer = i * alphabet.len();
        // Bail if the given character cannot be a jump label.
        if outer > labels.len() {
            doc_mut!(cx.editor, &doc).remove_jump_labels(view);
            return;
        }
        cx.on_next_key(move |cx, event| {
            doc_mut!(cx.editor, &doc).remove_jump_labels(view);
            let alphabet = &cx.editor.config().jump_label_alphabet;
            let Some(inner ) = event.char().and_then(|ch| alphabet.iter().position(|&it| it == ch)) else {
                return;
            };
            if let Some(mut range) = labels.get(outer + inner).copied() {
                range = if behaviour == Movement::Extend {
                    let anchor = if range.anchor < range.head {