implement snippet tabstop support

This commit is contained in:
Pascal Kuthe 2024-03-03 23:23:34 +01:00 committed by Michael Davis
parent 66fb1e67c0
commit 1badd9e434
No known key found for this signature in database
11 changed files with 268 additions and 1241 deletions

View file

@ -585,6 +585,8 @@ impl MappableCommand {
command_palette, "Open command palette",
goto_word, "Jump to a two-character label",
extend_to_word, "Extend to a two-character label",
goto_next_tabstop, "goto next snippet placeholder",
goto_prev_tabstop, "goto next snippet placeholder",
);
}
@ -3948,7 +3950,11 @@ pub mod insert {
});
if !cursors_after_whitespace {
move_parent_node_end(cx);
if doc.active_snippet.is_some() {
goto_next_tabstop(cx);
} else {
move_parent_node_end(cx);
}
return;
}
}
@ -6187,6 +6193,47 @@ fn increment_impl(cx: &mut Context, increment_direction: IncrementDirection) {
}
}
fn goto_next_tabstop(cx: &mut Context) {
goto_next_tabstop_impl(cx, Direction::Forward)
}
fn goto_prev_tabstop(cx: &mut Context) {
goto_next_tabstop_impl(cx, Direction::Backward)
}
fn goto_next_tabstop_impl(cx: &mut Context, direction: Direction) {
let (view, doc) = current!(cx.editor);
let view_id = view.id;
let Some(mut snippet) = doc.active_snippet.take() else {
cx.editor.set_error("no snippet is currently active");
return;
};
let tabstop = match direction {
Direction::Forward => Some(snippet.next_tabstop(doc.selection(view_id))),
Direction::Backward => snippet
.prev_tabstop(doc.selection(view_id))
.map(|selection| (selection, false)),
};
let Some((selection, last_tabstop)) = tabstop else {
return;
};
doc.set_selection(view_id, selection);
if !last_tabstop {
doc.active_snippet = Some(snippet)
}
if cx.editor.mode() == Mode::Insert {
cx.on_next_key_fallback(|cx, key| {
if let Some(c) = key.char() {
let (view, doc) = current!(cx.editor);
if let Some(snippet) = &doc.active_snippet {
doc.apply(&snippet.delete_placeholder(doc.text()), view.id);
}
insert_char(cx, c);
}
})
}
}
fn record_macro(cx: &mut Context) {
if let Some((reg, mut keys)) = cx.editor.macro_recording.take() {
// Remove the keypress which ends the recording