aboutsummaryrefslogtreecommitdiff
path: root/helix-term
diff options
context:
space:
mode:
authorPascal Kuthe2023-03-02 20:56:55 +0000
committerBlaž Hrastnik2023-03-09 04:01:02 +0000
commite8898fd9a8ac8120827fb2d6f4752b3cb2431a62 (patch)
treebc6abc2aa663c7c31fa006bf14d3a59cc9269191 /helix-term
parent2588fa3710921683c16a84ffd91103a0823a033b (diff)
store multiple snapshots on the document at once
Fixing autocomplete required moving the document savepoint before the asynchronous completion request. However, this in turn causes new bugs: If the completion popup is open, the savepoint is restored when the popup closes (or another entry is selected). However, at that point a new completion request might already have been created which would have replaced the new savepoint (therefore leading to incorrectly applied complies). This commit fixes that bug by allowing in arbitrary number of savepoints to be tracked on the document. The savepoints are reference counted and therefore remain valid as long as any reference to them remains. Weak reference are stored on the document and any reference that can not be upgraded anymore (hence no strong reference remain) are automatically discarded.
Diffstat (limited to 'helix-term')
-rw-r--r--helix-term/src/commands.rs3
-rw-r--r--helix-term/src/ui/completion.rs8
-rw-r--r--helix-term/src/ui/editor.rs14
3 files changed, 16 insertions, 9 deletions
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index bc0e8ebe..01673c89 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -4181,7 +4181,7 @@ pub fn completion(cx: &mut Context) {
iter.reverse();
let offset = iter.take_while(|ch| chars::char_is_word(*ch)).count();
let start_offset = cursor.saturating_sub(offset);
- doc.savepoint(&view);
+ let savepoint = doc.savepoint(view);
cx.callback(
future,
@@ -4209,6 +4209,7 @@ pub fn completion(cx: &mut Context) {
let ui = compositor.find::<ui::EditorView>().unwrap();
ui.set_completion(
editor,
+ savepoint,
items,
offset_encoding,
start_offset,
diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs
index 179a8cf8..ef88938f 100644
--- a/helix-term/src/ui/completion.rs
+++ b/helix-term/src/ui/completion.rs
@@ -1,12 +1,13 @@
use crate::compositor::{Component, Context, Event, EventResult};
use helix_view::{
+ document::SavePoint,
editor::CompleteAction,
theme::{Modifier, Style},
ViewId,
};
use tui::{buffer::Buffer as Surface, text::Span};
-use std::borrow::Cow;
+use std::{borrow::Cow, sync::Arc};
use helix_core::{Change, Transaction};
use helix_view::{graphics::Rect, Document, Editor};
@@ -101,6 +102,7 @@ impl Completion {
pub fn new(
editor: &Editor,
+ savepoint: Arc<SavePoint>,
mut items: Vec<CompletionItem>,
offset_encoding: helix_lsp::OffsetEncoding,
start_offset: usize,
@@ -213,11 +215,10 @@ impl Completion {
let (view, doc) = current!(editor);
// if more text was entered, remove it
- doc.restore(view);
+ doc.restore(view, &savepoint);
match event {
PromptEvent::Abort => {
- doc.restore(view);
editor.last_completion = None;
}
PromptEvent::Update => {
@@ -235,7 +236,6 @@ impl Completion {
);
// initialize a savepoint
- doc.savepoint(&view);
doc.apply(&transaction, view.id);
editor.last_completion = Some(CompleteAction {
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index 62f04cc9..c81ae635 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -940,17 +940,25 @@ impl EditorView {
}
}
+ #[allow(clippy::too_many_arguments)]
pub fn set_completion(
&mut self,
editor: &mut Editor,
+ savepoint: Arc<SavePoint>,
items: Vec<helix_lsp::lsp::CompletionItem>,
offset_encoding: helix_lsp::OffsetEncoding,
start_offset: usize,
trigger_offset: usize,
size: Rect,
) {
- let mut completion =
- Completion::new(editor, items, offset_encoding, start_offset, trigger_offset);
+ let mut completion = Completion::new(
+ editor,
+ savepoint,
+ items,
+ offset_encoding,
+ start_offset,
+ trigger_offset,
+ );
if completion.is_empty() {
// skip if we got no completion results
@@ -969,8 +977,6 @@ impl EditorView {
self.completion = None;
// Clear any savepoints
- let doc = doc_mut!(editor);
- doc.savepoint = None;
editor.clear_idle_timer(); // don't retrigger
}