Amp-like jump: remove not relevant overlays after keypress

This commit is contained in:
Roman Perehonchuk 2024-04-01 13:11:05 +01:00
parent 88d455afeb
commit d0c5784faf

View File

@ -5940,28 +5940,10 @@ fn jump_to_label(cx: &mut Context, labels: Vec<Range>, behaviour: Movement) {
if labels.is_empty() {
return;
}
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 overlays = labels_to_overlays(labels.iter(), alphabet, text, None);
let (view, doc) = current!(cx.editor);
doc.set_jump_labels(view.id, overlays);
@ -5982,6 +5964,15 @@ fn jump_to_label(cx: &mut Context, labels: Vec<Range>, behaviour: Movement) {
doc_mut!(cx.editor, &doc).remove_jump_labels(view);
return;
}
if let Some(ch) = event.char() {
let mut grapheme = Tendril::new();
grapheme.push(ch);
let doc = doc_mut!(cx.editor, &doc);
let text = doc.text().slice(..);
let overlays = labels_to_overlays(labels.iter().skip(outer).take(alphabet.len()), alphabet, text, Some(grapheme));
doc.set_jump_labels(view, overlays);
}
cx.on_next_key(move |cx, event| {
doc_mut!(cx.editor, &doc).remove_jump_labels(view);
let alphabet = &cx.editor.config().jump_label_alphabet;
@ -6015,6 +6006,39 @@ fn jump_to_label(cx: &mut Context, labels: Vec<Range>, behaviour: Movement) {
});
}
fn alphabet_char(alphabet: &[char], index: usize) -> Tendril {
let mut res = Tendril::new();
res.push(alphabet[index]);
res
}
fn labels_to_overlays<'a>(
it: impl Iterator<Item = &'a Range>,
alphabet: &[char],
text: RopeSlice,
grapheme: Option<Tendril>,
) -> Vec<Overlay> {
let mut overlays: Vec<_> = it
.enumerate()
.flat_map(|(i, range)| {
[
Overlay::new(
range.from(),
grapheme
.clone()
.unwrap_or_else(|| alphabet_char(alphabet, i / alphabet.len())),
),
Overlay::new(
graphemes::next_grapheme_boundary(text, range.from()),
alphabet_char(alphabet, i % alphabet.len()),
),
]
})
.collect();
overlays.sort_unstable_by_key(|overlay| overlay.char_idx);
overlays
}
fn jump_to_word(cx: &mut Context, behaviour: Movement) {
// Calculate the jump candidates: ranges for any visible words with two or
// more characters.