aboutsummaryrefslogtreecommitdiff
path: root/helix-term
diff options
context:
space:
mode:
authorMichael Davis2022-12-06 01:29:40 +0000
committerGitHub2022-12-06 01:29:40 +0000
commit2077f5e26a4cdaadde4b505fc64eadb9e6849c0d (patch)
treeb3b274e5efcc12cbe57b090d08d590aceab833f2 /helix-term
parent7210c58a51a16c0ae3c9d77211ed1a25e039bd9e (diff)
Apply completion edits to all cursors (#4496)
Completion edits - either basic `insert_text` strings or structured `text_edit`s - are assumed by the LSP spec to apply to the current cursor (or at least the trigger point). We can use the range (if any) and text given by the Language Server to create a transaction that changes all ranges in the current selection though, allowing auto- complete to affect multiple cursors.
Diffstat (limited to 'helix-term')
-rw-r--r--helix-term/src/ui/completion.rs31
1 files changed, 24 insertions, 7 deletions
diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs
index ebb4fb46..c54990e8 100644
--- a/helix-term/src/ui/completion.rs
+++ b/helix-term/src/ui/completion.rs
@@ -1,5 +1,5 @@
use crate::compositor::{Component, Context, Event, EventResult};
-use helix_view::{apply_transaction, editor::CompleteAction};
+use helix_view::{apply_transaction, editor::CompleteAction, ViewId};
use tui::buffer::Buffer as Surface;
use tui::text::Spans;
@@ -107,6 +107,7 @@ impl Completion {
let menu = Menu::new(items, (), move |editor: &mut Editor, item, event| {
fn item_to_transaction(
doc: &Document,
+ view_id: ViewId,
item: &CompletionItem,
offset_encoding: helix_lsp::OffsetEncoding,
start_offset: usize,
@@ -121,9 +122,10 @@ impl Completion {
}
};
- util::generate_transaction_from_edits(
+ util::generate_transaction_from_completion_edit(
doc.text(),
- vec![edit],
+ doc.selection(view_id),
+ edit,
offset_encoding, // TODO: should probably transcode in Client
)
} else {
@@ -132,10 +134,23 @@ impl Completion {
// in these cases we need to check for a common prefix and remove it
let prefix = Cow::from(doc.text().slice(start_offset..trigger_offset));
let text = text.trim_start_matches::<&str>(&prefix);
- Transaction::change(
- doc.text(),
- vec![(trigger_offset, trigger_offset, Some(text.into()))].into_iter(),
- )
+
+ // TODO: this needs to be true for the numbers to work out correctly
+ // in the closure below. It's passed in to a callback as this same
+ // formula, but can the value change between the LSP request and
+ // response? If it does, can we recover?
+ debug_assert!(
+ doc.selection(view_id)
+ .primary()
+ .cursor(doc.text().slice(..))
+ == trigger_offset
+ );
+
+ Transaction::change_by_selection(doc.text(), doc.selection(view_id), |range| {
+ let cursor = range.cursor(doc.text().slice(..));
+
+ (cursor, cursor, Some(text.into()))
+ })
};
transaction
@@ -164,6 +179,7 @@ impl Completion {
let transaction = item_to_transaction(
doc,
+ view.id,
item,
offset_encoding,
start_offset,
@@ -185,6 +201,7 @@ impl Completion {
let transaction = item_to_transaction(
doc,
+ view.id,
item,
offset_encoding,
start_offset,