Skip to content

Commit 4b0c1ab

Browse files
authored
fix(completion): correct $TM_CURRENT_WORD extraction and replacement (#1346)
1 parent bec14a1 commit 4b0c1ab

2 files changed

Lines changed: 46 additions & 35 deletions

File tree

org.eclipse.lsp4e.test/src/org/eclipse/lsp4e/test/completion/CompleteCompletionTest.java

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.util.ArrayList;
2020
import java.util.Arrays;
2121
import java.util.List;
22-
import java.util.Map;
2322
import java.util.Set;
2423
import java.util.concurrent.CompletableFuture;
2524
import java.util.concurrent.ExecutionException;
@@ -393,46 +392,58 @@ public void testDuplicateVariable() throws CoreException {
393392
}
394393

395394
@Test
396-
public void testComplexSnippets() throws CoreException {
397-
Map<String, String> tests = Map.ofEntries(
395+
public void testComplexSnippets() throws CoreException {
396+
record Test(String completion, String expected, String fileContent, int caretPos, int selectionLen) {
397+
Test(String completion, String expected) {
398+
this(completion, expected, "", 0, 0);
399+
}
400+
}
401+
Test[] tests = {
398402
// Variables and escaped dollars
399-
Map.entry("$TM_LINE_NUMBER - \\$TM_LINE_NUMBER - ${TM_LINE_NUMBER} - \\${TM_LINE_NUMBER}", "1 - $TM_LINE_NUMBER - 1 - ${TM_LINE_NUMBER}"),
403+
new Test("$TM_LINE_NUMBER - \\$TM_LINE_NUMBER - ${TM_LINE_NUMBER} - \\${TM_LINE_NUMBER}",
404+
"1 - $TM_LINE_NUMBER - 1 - ${TM_LINE_NUMBER}"),
400405
// Default values for variables
401-
Map.entry("${TM_SELECTED_TEXT:defaultval}", "defaultval"),
406+
new Test("${TM_SELECTED_TEXT:defaultval}", "defaultval"),
402407
// Escaped dollars
403-
Map.entry("\\$1 and \\$", "$1 and $"),
408+
new Test("\\$1 and \\$", "$1 and $"),
404409
// Escaped escapes
405-
Map.entry("\\\\$1 and ${3:foo}", "\\ and foo"),
410+
new Test("\\\\$1 and ${3:foo}", "\\ and foo"),
406411
// Escaped values in a choice
407-
Map.entry("${2|a\\,b\\},c|}", "a,b}"),
408-
// Snippets with syntax errors: Make sure they don't cause endless loops or crashes
409-
Map.entry("$", "$"),
410-
Map.entry("${", "${"),
411-
Map.entry("$$", "$$"),
412-
Map.entry("$$TM_LINE_NUMBER", "$1"),
413-
Map.entry("${VARIABLE", "${VARIABLE"),
414-
Map.entry("${VARIABLE:", "${VARIABLE:"),
415-
Map.entry("${VARIABLE:foo", "${VARIABLE:foo"),
416-
Map.entry("${1|a", "${1|a"),
417-
Map.entry("${1|a,}", "${1|a,}")
418-
);
419-
for (Map.Entry<String, String> entry : tests.entrySet()) {
420-
CompletionItem completionItem = createCompletionItem(
421-
entry.getKey(),
422-
CompletionItemKind.Class,
423-
new Range(new Position(0, 0), new Position(0, 1))
424-
);
412+
new Test("${2|a\\,b\\},c|}", "a,b}"),
413+
// TM_CURRENT_WORD completion (caret after 'foo')
414+
new Test("${1:$TM_CURRENT_WORD}", "xx abcabc yy", "xx abc yy", 3, 0),
415+
new Test("${1:$TM_CURRENT_WORD}", "xx aabcbc yy", "xx abc yy", 4, 0),
416+
new Test("${1:$TM_CURRENT_WORD}", "xx aabc yy", "xx abc yy", 4, 2),
417+
// Snippets with syntax errors:
418+
// Make sure they don't cause endless loops or crashes
419+
new Test("$", "$"), //
420+
new Test("${", "${"), //
421+
new Test("$$", "$$"), //
422+
new Test("$$TM_LINE_NUMBER", "$1"), //
423+
new Test("${VARIABLE", "${VARIABLE"), //
424+
new Test("${VARIABLE:", "${VARIABLE:"), //
425+
new Test("${VARIABLE:foo", "${VARIABLE:foo"), //
426+
new Test("${1|a", "${1|a"), //
427+
new Test("${1|a,}", "${1|a,}"), //
428+
};
429+
for (Test test : tests) {
430+
CompletionItem completionItem = createCompletionItem( //
431+
test.completion, //
432+
CompletionItemKind.Class, //
433+
new Range(new Position(0, test.caretPos()),
434+
new Position(0, test.caretPos() + test.selectionLen())));
425435
completionItem.setInsertTextFormat(InsertTextFormat.Snippet);
426436
MockLanguageServer.INSTANCE.setCompletionList(new CompletionList(false, List.of(completionItem)));
427-
ITextViewer viewer = TestUtils.openTextViewer(TestUtils.createUniqueTestFile(project,""));
428-
int invokeOffset = 0;
429-
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer, invokeOffset);
430-
assertEquals(1, proposals.length);
431-
((LSCompletionProposal) proposals[0]).apply(viewer, '\n', 0, invokeOffset);
432-
assertEquals(
433-
entry.getValue(),
434-
viewer.getDocument().get());
435437

438+
ITextViewer viewer = TestUtils.openTextViewer(TestUtils.createUniqueTestFile(project, test.fileContent));
439+
viewer.setSelectedRange(test.caretPos(), test.selectionLen());
440+
441+
ICompletionProposal[] proposals = contentAssistProcessor.computeCompletionProposals(viewer,
442+
test.caretPos());
443+
assertEquals("Unexpected proposals length for " + test + " - ", 1, proposals.length);
444+
445+
((LSCompletionProposal) proposals[0]).apply(viewer, '\n', 0, test.caretPos());
446+
assertEquals("Unexpected result for " + test + " - ", test.expected, viewer.getDocument().get());
436447
}
437448
}
438449

org.eclipse.lsp4e/src/org/eclipse/lsp4e/operations/completion/LSCompletionProposal.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -703,11 +703,11 @@ private String getVariableValue(String variableName) {
703703
String selectedText = document.get(viewer.getSelectedRange().x, viewer.getSelectedRange().y);
704704
int beforeSelection = viewer.getSelectedRange().x - 1;
705705
while (beforeSelection >= 0 && Character.isUnicodeIdentifierPart(document.getChar(beforeSelection))) {
706-
selectedText = beforeSelection + selectedText;
706+
selectedText = document.getChar(beforeSelection) + selectedText;
707707
beforeSelection--;
708708
}
709709
int afterSelection = viewer.getSelectedRange().x + viewer.getSelectedRange().y;
710-
while (afterSelection < document.getLength() && Character.isUnicodeIdentifierPart(afterSelection)) {
710+
while (afterSelection < document.getLength() && Character.isUnicodeIdentifierPart(document.getChar(afterSelection))) {
711711
selectedText = selectedText + document.getChar(afterSelection);
712712
afterSelection++;
713713
}

0 commit comments

Comments
 (0)