aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--helix-term/src/commands.rs19
-rw-r--r--helix-term/src/ui/editor.rs18
2 files changed, 31 insertions, 6 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 574e1edf..6817bc5c 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -53,7 +53,10 @@ use crate::{
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>| {
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index 859176fb..4abbe01e 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -21,14 +21,14 @@ use helix_core::{
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 @@ impl EditorView {
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 @@ impl EditorView {
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 @@ impl EditorView {
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));
}
}
}