Skip to content

Commit aabc8af

Browse files
pascalkuthearchseer
authored andcommitted
correctly store snapshots when repeating insert-mode actions
Repeating completions currently crates a savepoint when a completion popup was triggered (so after the request completed). Just like for normal completions the savepoint must be created at the request. The occurrence of the completion request was previously not saved in `last_insert`. To that end a new `InsertEvent::RequestCompletion` variant has been added. When replayed this event creates a snapshot that is "actived" by the `TriggerCompletion` event and subsequently used during any `InsertEvent::CompletiuonApply` events.
1 parent 8cb7cdf commit aabc8af

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

helix-term/src/commands.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ use crate::{
5353
filter_picker_entry,
5454
job::Callback,
5555
keymap::ReverseKeymap,
56-
ui::{self, overlay::overlayed, FilePicker, Picker, Popup, Prompt, PromptEvent},
56+
ui::{
57+
self, editor::InsertEvent, overlay::overlayed, FilePicker, Picker, Popup, Prompt,
58+
PromptEvent,
59+
},
5760
};
5861

5962
use crate::job::{self, Jobs};
@@ -4205,6 +4208,20 @@ pub fn completion(cx: &mut Context) {
42054208
let trigger_doc = doc.id();
42064209
let trigger_view = view.id;
42074210

4211+
// FIXME: The commands Context can only have a single callback
4212+
// which means it gets overwritten when executing keybindings
4213+
// with multiple commands or macros. This would mean that completion
4214+
// might be incorrectly applied when repeating the insertmode action
4215+
//
4216+
// TODO: to solve this either make cx.callback a Vec of callbacks or
4217+
// alternatively move `last_insert` to `helix_view::Editor`
4218+
cx.callback = Some(Box::new(
4219+
move |compositor: &mut Compositor, _cx: &mut compositor::Context| {
4220+
let ui = compositor.find::<ui::EditorView>().unwrap();
4221+
ui.last_insert.1.push(InsertEvent::RequestCompletion);
4222+
},
4223+
));
4224+
42084225
cx.callback(
42094226
future,
42104227
move |editor, compositor, response: Option<lsp::CompletionResponse>| {

helix-term/src/ui/editor.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ use helix_core::{
2121
visual_offset_from_block, Position, Range, Selection, Transaction,
2222
};
2323
use helix_view::{
24-
document::{Mode, SCRATCH_BUFFER_NAME},
24+
document::{Mode, SavePoint, SCRATCH_BUFFER_NAME},
2525
editor::{CompleteAction, CursorShapeConfig},
2626
graphics::{Color, CursorKind, Modifier, Rect, Style},
2727
input::{KeyEvent, MouseButton, MouseEvent, MouseEventKind},
2828
keyboard::{KeyCode, KeyModifiers},
2929
Document, Editor, Theme, View,
3030
};
31-
use std::{num::NonZeroUsize, path::PathBuf, rc::Rc};
31+
use std::{mem::take, num::NonZeroUsize, path::PathBuf, rc::Rc, sync::Arc};
3232

3333
use tui::buffer::Buffer as Surface;
3434

@@ -39,7 +39,7 @@ pub struct EditorView {
3939
pub keymaps: Keymaps,
4040
on_next_key: Option<OnKeyCallback>,
4141
pseudo_pending: Vec<KeyEvent>,
42-
last_insert: (commands::MappableCommand, Vec<InsertEvent>),
42+
pub(crate) last_insert: (commands::MappableCommand, Vec<InsertEvent>),
4343
pub(crate) completion: Option<Completion>,
4444
spinners: ProgressSpinners,
4545
}
@@ -49,6 +49,7 @@ pub enum InsertEvent {
4949
Key(KeyEvent),
5050
CompletionApply(CompleteAction),
5151
TriggerCompletion,
52+
RequestCompletion,
5253
}
5354

5455
impl Default for EditorView {
@@ -891,14 +892,18 @@ impl EditorView {
891892
for _ in 0..cxt.editor.count.map_or(1, NonZeroUsize::into) {
892893
// first execute whatever put us into insert mode
893894
self.last_insert.0.execute(cxt);
895+
let mut last_savepoint = None;
896+
let mut last_request_savepoint = None;
894897
// then replay the inputs
895898
for key in self.last_insert.1.clone() {
896899
match key {
897900
InsertEvent::Key(key) => self.insert_mode(cxt, key),
898901
InsertEvent::CompletionApply(compl) => {
899902
let (view, doc) = current!(cxt.editor);
900903

901-
doc.restore(view);
904+
if let Some(last_savepoint) = last_savepoint.as_deref() {
905+
doc.restore(view, last_savepoint);
906+
}
902907

903908
let text = doc.text().slice(..);
904909
let cursor = doc.selection(view.id).primary().cursor(text);
@@ -915,8 +920,11 @@ impl EditorView {
915920
doc.apply(&tx, view.id);
916921
}
917922
InsertEvent::TriggerCompletion => {
923+
last_savepoint = take(&mut last_request_savepoint);
924+
}
925+
InsertEvent::RequestCompletion => {
918926
let (view, doc) = current!(cxt.editor);
919-
doc.savepoint(view);
927+
last_request_savepoint = Some(doc.savepoint(view));
920928
}
921929
}
922930
}

0 commit comments

Comments
 (0)