aboutsummaryrefslogtreecommitdiff
path: root/helix-term
diff options
context:
space:
mode:
authorPascal Kuthe2023-03-09 22:08:55 +0000
committerBlaž Hrastnik2023-03-10 07:54:17 +0000
commitb1f75280909884c9621b553b43030ac39cfa47ce (patch)
treeb1491f69bb8280a2f6a5445c7ffe36ea0bfd852c /helix-term
parent2b64a64d7ea43e22ad82f97f2c118891b74c3199 (diff)
fix snippet bugs and multicursor completion edgecases
Multicursor completions may overlap and therefore overlapping completions must be dropped to avoid crashes. Furthermore, multicursor edits might simply be out of range if the word before/after the cursor is shorter. This currently leads to crashes, instead these selections are now also removed for completions. This commit also significantly refactors snippet transaction generation so that tabstops behave correctly with the above rules. Furthermore, snippet tabstops need to be carefully mapped to ensure their position is correct and consistent with our selection semantics. Finally, we now keep a partially updated Rope while creating snippet transactions so that we can fill information into snippets that depends on the position in the document.
Diffstat (limited to 'helix-term')
-rw-r--r--helix-term/src/ui/completion.rs18
1 files changed, 3 insertions, 15 deletions
diff --git a/helix-term/src/ui/completion.rs b/helix-term/src/ui/completion.rs
index 336b75cb..99c33781 100644
--- a/helix-term/src/ui/completion.rs
+++ b/helix-term/src/ui/completion.rs
@@ -118,7 +118,6 @@ impl Completion {
view_id: ViewId,
item: &CompletionItem,
offset_encoding: helix_lsp::OffsetEncoding,
- start_offset: usize,
trigger_offset: usize,
include_placeholder: bool,
) -> Transaction {
@@ -147,28 +146,18 @@ impl Completion {
None => return Transaction::new(doc.text()),
};
- (start_offset, end_offset, edit.new_text)
+ (Some((start_offset, end_offset)), edit.new_text)
} else {
let new_text = item
.insert_text
.clone()
.unwrap_or_else(|| item.label.clone());
-
// check that we are still at the correct savepoint
// we can still generate a transaction regardless but if the
// document changed (and not just the selection) then we will
// likely delete the wrong text (same if we applied an edit sent by the LS)
debug_assert!(primary_cursor == trigger_offset);
-
- // TODO: Respect editor.completion_replace?
- // Would require detecting the end of the word boundary for every cursor individually.
- // We don't do the same for normal `edits, to be consistent we would have to do it for those too
-
- (
- start_offset as i128 - primary_cursor as i128,
- trigger_offset as i128 - primary_cursor as i128,
- new_text,
- )
+ (None, Some(0), new_text)
};
if matches!(item.kind, Some(lsp::CompletionItemKind::SNIPPET))
@@ -186,6 +175,7 @@ impl Completion {
snippet,
doc.line_ending.as_str(),
include_placeholder,
+ doc.tab_width(),
),
Err(err) => {
log::error!(
@@ -232,7 +222,6 @@ impl Completion {
view.id,
item,
offset_encoding,
- start_offset,
trigger_offset,
true,
);
@@ -254,7 +243,6 @@ impl Completion {
view.id,
item,
offset_encoding,
- start_offset,
trigger_offset,
false,
);