More tweaking to relaxed context assist

This commit is contained in:
Kris De Volder
2017-04-26 14:00:52 -07:00
parent 17ce903577
commit 66704bec00
4 changed files with 85 additions and 11 deletions

View File

@@ -10,11 +10,12 @@
*******************************************************************************/
package org.springframework.ide.vscode.commons.yaml.completion;
import static org.springframework.ide.vscode.commons.languageserver.completion.ScoreableProposal.DEEMP_INDENTED_PROPOSAL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -23,6 +24,7 @@ import org.springframework.ide.vscode.commons.languageserver.completion.IComplet
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
import org.springframework.ide.vscode.commons.languageserver.completion.ScoreableProposal;
import org.springframework.ide.vscode.commons.util.Assert;
import org.springframework.ide.vscode.commons.util.Log;
import org.springframework.ide.vscode.commons.util.text.IDocument;
import org.springframework.ide.vscode.commons.yaml.path.YamlPath;
import org.springframework.ide.vscode.commons.yaml.structure.YamlDocument;
@@ -34,8 +36,6 @@ import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureProvider;
import org.springframework.ide.vscode.commons.yaml.util.YamlIndentUtil;
import static org.springframework.ide.vscode.commons.languageserver.completion.ScoreableProposal.*;
/**
* Implements {@link ICompletionEngine} for .yml file, based on a YamlAssistContextProvider
* which has to to be injected into engine via its contructor.
@@ -106,7 +106,10 @@ public class YamlCompletionEngine implements ICompletionEngine {
return transformed;
}
private Collection<? extends ICompletionProposal> getDashedCompletions(int offset, YamlDocument doc, SNode preciseContextNode, SNode currentNode) throws Exception {
private Collection<? extends ICompletionProposal> getDashedCompletions(
int offset, YamlDocument doc,
SNode preciseContextNode, SNode currentNode
) throws Exception {
SNode contextNode = getContextNode(doc, currentNode, offset, "- ");
if (preciseContextNode!=contextNode) {
return getBaseCompletions(offset, doc, currentNode, contextNode, true);
@@ -129,10 +132,23 @@ public class YamlCompletionEngine implements ICompletionEngine {
private boolean isIndentRelaxable(SNode contextNode) throws Exception {
return contextNode!=null && (
isBarrenKey(contextNode) ||
contextNode.getNodeType()==SNodeType.SEQ
isBarrenSeq(contextNode)
);
}
private boolean isBarrenSeq(SNode node) {
try {
if (node.getNodeType()==SNodeType.SEQ) {
SSeqNode seqNode = (SSeqNode) node;
String value = seqNode.getTextWithoutChildren();
return "-".equals(value.trim());
}
} catch (Exception e) {
Log.log(e);
}
return false;
}
private boolean isBarrenKey(SNode node) throws Exception {
if (node.getNodeType()==SNodeType.KEY) {
SKeyNode keyNode = (SKeyNode) node;
@@ -213,7 +229,7 @@ public class YamlCompletionEngine implements ICompletionEngine {
while (node.getNodeType()!=SNodeType.DOC && (
nodeIndent==-1 ||
nodeIndent>currentIndent ||
nodeIndent==currentIndent && node.getNodeType()==SNodeType.SEQ
nodeIndent==currentIndent && (node.getNodeType()==SNodeType.SEQ || node.getNodeType() == SNodeType.RAW)
)) {
node = node.getParent();
nodeIndent = node.getIndent();

View File

@@ -17,6 +17,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.regex.Pattern;
import java.util.stream.Stream;
@@ -579,7 +580,6 @@ public class YamlStructureParser {
public abstract class SLeafNode extends SNode {
public SLeafNode(SChildBearingNode parent, YamlDocument doc,
int indent, int start, int end) {
super(parent, doc, indent, start, end);
@@ -735,6 +735,15 @@ public class YamlStructureParser {
return offset>=getStart()+dashLen
&& offset <= getTreeEnd();
}
public String getTextWithoutChildren() {
int end = getNodeEnd();
Optional<SNode> child = getChildren().stream().findFirst();
if (child.isPresent()) {
end = Math.min(end, child.get().getStart());
}
return doc.textBetween(getStart(), end);
}
}
public class SKeyNode extends SChildBearingNode {

View File

@@ -46,6 +46,7 @@ import org.eclipse.lsp4j.TextDocumentPositionParams;
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.junit.Assert;
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
import org.springframework.ide.vscode.commons.util.text.LanguageId;
import com.google.common.collect.ImmutableList;
@@ -290,6 +291,10 @@ public class Editor {
}
public List<CompletionItem> assertCompletions(String... expectTextAfter) throws Exception {
return assertCompletions((item) -> true, expectTextAfter);
}
public List<CompletionItem> assertCompletions(Predicate<CompletionItem> filter, String... expectTextAfter) throws Exception {
StringBuilder expect = new StringBuilder();
StringBuilder actual = new StringBuilder();
for (String after : expectTextAfter) {
@@ -299,10 +304,12 @@ public class Editor {
List<CompletionItem> completions = getCompletions();
for (CompletionItem completion : completions) {
Editor editor = this.clone();
editor.apply(completion);
actual.append(editor.getText());
actual.append("\n-------------------\n");
if (filter.test(completion)) {
Editor editor = this.clone();
editor.apply(completion);
actual.append(editor.getText());
actual.append("\n-------------------\n");
}
}
assertEquals(expect.toString(), actual.toString());
return completions;

View File

@@ -1148,6 +1148,28 @@ public class ManifestYamlEditorTest {
when(service.getName()).thenReturn("my-service");
when(service.getPlan()).thenReturn("cheap-plan");
editor = harness.newEditor(
"services:\n"+
"- blah\n"+
"ser<*>"
);
editor.assertCompletionWithLabel((s) -> s.startsWith("- "),
"services:\n"+
"- blah\n"+
"- my-service<*>"
);
editor = harness.newEditor(
"services:\n"+
"- blah\n"+
"<*>"
);
editor.assertCompletionWithLabel((s) -> s.startsWith("- "),
"services:\n"+
"- blah\n"+
"- my-service<*>"
);
editor = harness.newEditor(
"applications:\n" +
"- name: foo\n" +
@@ -1201,6 +1223,26 @@ public class ManifestYamlEditorTest {
);
}
@Test public void noRelaxedValueCompletionsInListItemContexts() throws Exception {
//See: https://www.pivotaltracker.com/story/show/144393355
CFServiceInstance service = mock(CFServiceInstance.class);
when(cloudfoundry.client.getServices()).thenReturn(ImmutableList.of(service));
when(service.getName()).thenReturn("my-service");
when(service.getPlan()).thenReturn("cheap-plan");
Editor editor = harness.newEditor(
"services:\n" +
"- some-service\n" +
"<*>"
);
editor.assertCompletions((c) -> c.getLabel().contains("my-service"),
"services:\n" +
"- some-service\n" +
"- my-service<*>"
);
}
//////////////////////////////////////////////////////////////////////////////
private List<CompletionItem> assertCompletions(String textBefore, String... textAfter) throws Exception {