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.
This commit is contained in:
parent
8cb7cdfd7a
commit
aabc8af95d
@ -53,7 +53,10 @@
|
||||
filter_picker_entry,
|
||||
job::Callback,
|
||||
keymap::ReverseKeymap,
|
||||
ui::{self, overlay::overlayed, FilePicker, Picker, Popup, Prompt, PromptEvent},
|
||||
ui::{
|
||||
self, editor::InsertEvent, overlay::overlayed, FilePicker, Picker, Popup, Prompt,
|
||||
PromptEvent,
|
||||
},
|
||||
};
|
||||
|
||||
use crate::job::{self, Jobs};
|
||||
@ -4205,6 +4208,20 @@ pub fn completion(cx: &mut Context) {
|
||||
let trigger_doc = doc.id();
|
||||
let trigger_view = view.id;
|
||||
|
||||
// FIXME: The commands Context can only have a single callback
|
||||
// which means it gets overwritten when executing keybindings
|
||||
// with multiple commands or macros. This would mean that completion
|
||||
// might be incorrectly applied when repeating the insertmode action
|
||||
//
|
||||
// TODO: to solve this either make cx.callback a Vec of callbacks or
|
||||
// alternatively move `last_insert` to `helix_view::Editor`
|
||||
cx.callback = Some(Box::new(
|
||||
move |compositor: &mut Compositor, _cx: &mut compositor::Context| {
|
||||
let ui = compositor.find::<ui::EditorView>().unwrap();
|
||||
ui.last_insert.1.push(InsertEvent::RequestCompletion);
|
||||
},
|
||||
));
|
||||
|
||||
cx.callback(
|
||||
future,
|
||||
move |editor, compositor, response: Option<lsp::CompletionResponse>| {
|
||||
|
@ -21,14 +21,14 @@
|
||||
visual_offset_from_block, Position, Range, Selection, Transaction,
|
||||
};
|
||||
use helix_view::{
|
||||
document::{Mode, SCRATCH_BUFFER_NAME},
|
||||
document::{Mode, SavePoint, SCRATCH_BUFFER_NAME},
|
||||
editor::{CompleteAction, CursorShapeConfig},
|
||||
graphics::{Color, CursorKind, Modifier, Rect, Style},
|
||||
input::{KeyEvent, MouseButton, MouseEvent, MouseEventKind},
|
||||
keyboard::{KeyCode, KeyModifiers},
|
||||
Document, Editor, Theme, View,
|
||||
};
|
||||
use std::{num::NonZeroUsize, path::PathBuf, rc::Rc};
|
||||
use std::{mem::take, num::NonZeroUsize, path::PathBuf, rc::Rc, sync::Arc};
|
||||
|
||||
use tui::buffer::Buffer as Surface;
|
||||
|
||||
@ -39,7 +39,7 @@ pub struct EditorView {
|
||||
pub keymaps: Keymaps,
|
||||
on_next_key: Option<OnKeyCallback>,
|
||||
pseudo_pending: Vec<KeyEvent>,
|
||||
last_insert: (commands::MappableCommand, Vec<InsertEvent>),
|
||||
pub(crate) last_insert: (commands::MappableCommand, Vec<InsertEvent>),
|
||||
pub(crate) completion: Option<Completion>,
|
||||
spinners: ProgressSpinners,
|
||||
}
|
||||
@ -49,6 +49,7 @@ pub enum InsertEvent {
|
||||
Key(KeyEvent),
|
||||
CompletionApply(CompleteAction),
|
||||
TriggerCompletion,
|
||||
RequestCompletion,
|
||||
}
|
||||
|
||||
impl Default for EditorView {
|
||||
@ -891,6 +892,8 @@ fn command_mode(&mut self, mode: Mode, cxt: &mut commands::Context, event: KeyEv
|
||||
for _ in 0..cxt.editor.count.map_or(1, NonZeroUsize::into) {
|
||||
// first execute whatever put us into insert mode
|
||||
self.last_insert.0.execute(cxt);
|
||||
let mut last_savepoint = None;
|
||||
let mut last_request_savepoint = None;
|
||||
// then replay the inputs
|
||||
for key in self.last_insert.1.clone() {
|
||||
match key {
|
||||
@ -898,7 +901,9 @@ fn command_mode(&mut self, mode: Mode, cxt: &mut commands::Context, event: KeyEv
|
||||
InsertEvent::CompletionApply(compl) => {
|
||||
let (view, doc) = current!(cxt.editor);
|
||||
|
||||
doc.restore(view);
|
||||
if let Some(last_savepoint) = last_savepoint.as_deref() {
|
||||
doc.restore(view, last_savepoint);
|
||||
}
|
||||
|
||||
let text = doc.text().slice(..);
|
||||
let cursor = doc.selection(view.id).primary().cursor(text);
|
||||
@ -915,8 +920,11 @@ fn command_mode(&mut self, mode: Mode, cxt: &mut commands::Context, event: KeyEv
|
||||
doc.apply(&tx, view.id);
|
||||
}
|
||||
InsertEvent::TriggerCompletion => {
|
||||
last_savepoint = take(&mut last_request_savepoint);
|
||||
}
|
||||
InsertEvent::RequestCompletion => {
|
||||
let (view, doc) = current!(cxt.editor);
|
||||
doc.savepoint(view);
|
||||
last_request_savepoint = Some(doc.savepoint(view));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user