Move VscodeCompletionEngineAdapter to commons
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
package org.springframework.ide.vscode.commons.yaml.completion;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
|
||||
|
||||
public abstract class ScoreableProposal implements ICompletionProposal {
|
||||
private static final double DEEMP_VALUE = 100000; // should be large enough to move deemphasized stuff to bottom of list.
|
||||
|
||||
private double deemphasizedBy = 0.0;
|
||||
|
||||
/**
|
||||
* A sorter suitable for sorting ScoreableProposals based on their score.
|
||||
*/
|
||||
public static final Comparator<ICompletionProposal> COMPARATOR = new Comparator<ICompletionProposal>() {
|
||||
public int compare(ICompletionProposal p1, ICompletionProposal p2) {
|
||||
if (p1 instanceof ScoreableProposal && p2 instanceof ScoreableProposal) {
|
||||
double s1 = ((ScoreableProposal)p1).getScore();
|
||||
double s2 = ((ScoreableProposal)p2).getScore();
|
||||
if (s1==s2) {
|
||||
String name1 = ((ScoreableProposal)p1).getLabel();
|
||||
String name2 = ((ScoreableProposal)p2).getLabel();
|
||||
return name1.compareTo(name2);
|
||||
} else {
|
||||
return Double.compare(s2, s1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
public abstract double getBaseScore();
|
||||
public final double getScore() {
|
||||
return getBaseScore() - deemphasizedBy;
|
||||
}
|
||||
public ScoreableProposal deemphasize() {
|
||||
deemphasizedBy+= DEEMP_VALUE;
|
||||
return this;
|
||||
}
|
||||
public boolean isDeemphasized() {
|
||||
return deemphasizedBy > 0;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean isAutoInsertable() {
|
||||
// return !isDeemphasized();
|
||||
// }
|
||||
|
||||
// public StyledString getStyledDisplayString() {
|
||||
// StyledString result = new StyledString();
|
||||
// highlightPattern(getHighlightPattern(), getBaseDisplayString(), result);
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// private void highlightPattern(String pattern, String data, StyledString result) {
|
||||
// Styler highlightStyle = CompletionFactory.HIGHLIGHT;
|
||||
// Styler plainStyle = isDeemphasized()?CompletionFactory.DEEMPHASIZE:CompletionFactory.NULL_STYLER;
|
||||
// if (isDeprecated()) {
|
||||
// highlightStyle = CompletionFactory.compose(highlightStyle, CompletionFactory.DEPRECATE);
|
||||
// plainStyle = CompletionFactory.compose(plainStyle, CompletionFactory.DEPRECATE);
|
||||
// }
|
||||
// if (StringUtils.hasText(pattern)) {
|
||||
// int dataPos = 0; int dataLen = data.length();
|
||||
// int patternPos = 0; int patternLen = pattern.length();
|
||||
//
|
||||
// while (dataPos<dataLen && patternPos<patternLen) {
|
||||
// int pChar = pattern.charAt(patternPos++);
|
||||
// int highlightPos = data.indexOf(pChar, dataPos);
|
||||
// if (dataPos<highlightPos) {
|
||||
// result.append(data.substring(dataPos, highlightPos), plainStyle);
|
||||
// }
|
||||
// result.append(data.charAt(highlightPos), highlightStyle);
|
||||
// dataPos = highlightPos+1;
|
||||
// }
|
||||
// if (dataPos<dataLen) {
|
||||
// result.append(data.substring(dataPos), plainStyle);
|
||||
// }
|
||||
// } else { //no pattern to highlight
|
||||
// result.append(data, plainStyle);
|
||||
// }
|
||||
// }
|
||||
|
||||
// protected abstract boolean isDeprecated();
|
||||
// protected abstract String getHighlightPattern();
|
||||
// protected abstract String getBaseDisplayString();
|
||||
|
||||
// @Override
|
||||
// public String getAdditionalProposalInfo() {
|
||||
// HoverInfo hoverInfo = getAdditionalProposalInfo(new NullProgressMonitor());
|
||||
// if (hoverInfo!=null) {
|
||||
// return hoverInfo.getHtml();
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
// @Override
|
||||
// public abstract HoverInfo getAdditionalProposalInfo(IProgressMonitor monitor);
|
||||
|
||||
// @Override
|
||||
// public CharSequence getPrefixCompletionText(IDocument document, int completionOffset) {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public int getPrefixCompletionStart(IDocument document, int completionOffset) {
|
||||
// return completionOffset;
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -8,15 +8,15 @@ import java.util.concurrent.CompletableFuture;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits.TextReplace;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionEngine;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits.TextReplace;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.TextDocument;
|
||||
import org.springframework.ide.vscode.commons.util.Futures;
|
||||
import org.springframework.ide.vscode.commons.yaml.completion.DefaultCompletionFactory;
|
||||
import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.yaml.completion.ScoreableProposal;
|
||||
|
||||
import io.typefox.lsapi.CompletionItem;
|
||||
import io.typefox.lsapi.CompletionList;
|
||||
@@ -54,7 +54,7 @@ public class VscodeCompletionEngineAdapter implements VscodeCompletionEngine {
|
||||
if (doc!=null) {
|
||||
int offset = doc.toOffset(params.getPosition());
|
||||
List<ICompletionProposal> completions = new ArrayList<>(engine.getCompletions(doc, offset));
|
||||
Collections.sort(completions, DefaultCompletionFactory.COMPARATOR);
|
||||
Collections.sort(completions, ScoreableProposal.COMPARATOR);
|
||||
CompletionListImpl list = new CompletionListImpl();
|
||||
list.setIncomplete(false);
|
||||
List<CompletionItemImpl> items = new ArrayList<>(completions.size());
|
||||
@@ -105,7 +105,7 @@ public class VscodeCompletionEngineAdapter implements VscodeCompletionEngine {
|
||||
//Vscode applies some magic indent to a multi-line edit text. We do everything ourself so we have adjust for the magic
|
||||
// and do some kind of 'inverse magic' here.
|
||||
int vscodeMagicIndent = start.getCharacter();
|
||||
return YamlStructureParser.stripIndentation(vscodeMagicIndent, newText);
|
||||
return StringUtil.stripIndentation(vscodeMagicIndent, newText);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -131,4 +131,48 @@ public class StringUtil {
|
||||
return f.format(d);
|
||||
}
|
||||
|
||||
private static final Pattern NEWLINE = Pattern.compile("(\\n|\\r)+");
|
||||
|
||||
/**
|
||||
* Removes a given number of spaces from all lines of text in a String,
|
||||
* except for the first line.
|
||||
* <p>
|
||||
* Note: this method only deals with spaces its not suitable for strings
|
||||
* which use tabs for indentation.
|
||||
*/
|
||||
public static String stripIndentation(int indent, String indentedText) {
|
||||
StringBuilder out = new StringBuilder();
|
||||
boolean first = true;
|
||||
Matcher matcher = NEWLINE.matcher(indentedText);
|
||||
int pos = 0;
|
||||
while (matcher.find()) {
|
||||
int newline = matcher.start();
|
||||
int newline_end = matcher.end();
|
||||
String line = indentedText.substring(pos, newline);
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
line = stripIndentationFromLine(indent, line);
|
||||
}
|
||||
out.append(line);
|
||||
out.append(indentedText.substring(newline, newline_end));
|
||||
pos = newline_end;
|
||||
}
|
||||
String line = indentedText.substring(pos);
|
||||
if (!first) {
|
||||
line = stripIndentationFromLine(indent, line);
|
||||
}
|
||||
out.append(line);
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
public static String stripIndentationFromLine(int indent, String line) {
|
||||
int start = 0;
|
||||
while (start<line.length() && start < indent && line.charAt(start)==' ') {
|
||||
start++;
|
||||
}
|
||||
return line.substring(start);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package org.springframework.ide.vscode.commons.yaml.completion;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
|
||||
import org.springframework.ide.vscode.commons.languageserver.completion.ICompletionProposal;
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.IDocument;
|
||||
@@ -13,110 +11,6 @@ import io.typefox.lsapi.CompletionItemKind;
|
||||
|
||||
public class DefaultCompletionFactory implements CompletionFactory {
|
||||
|
||||
/**
|
||||
* A sorter suitable for sorting proposals created by this factory
|
||||
*/
|
||||
public static final Comparator<ICompletionProposal> COMPARATOR = new Comparator<ICompletionProposal>() {
|
||||
public int compare(ICompletionProposal p1, ICompletionProposal p2) {
|
||||
if (p1 instanceof ScoreableProposal && p2 instanceof ScoreableProposal) {
|
||||
double s1 = ((ScoreableProposal)p1).getScore();
|
||||
double s2 = ((ScoreableProposal)p2).getScore();
|
||||
if (s1==s2) {
|
||||
String name1 = ((ScoreableProposal)p1).getLabel();
|
||||
String name2 = ((ScoreableProposal)p2).getLabel();
|
||||
return name1.compareTo(name2);
|
||||
} else {
|
||||
return Double.compare(s2, s1);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public static abstract class ScoreableProposal implements ICompletionProposal {
|
||||
private static final double DEEMP_VALUE = 100000; // should be large enough to move deemphasized stuff to bottom of list.
|
||||
|
||||
private double deemphasizedBy = 0.0;
|
||||
public abstract double getBaseScore();
|
||||
public final double getScore() {
|
||||
return getBaseScore() - deemphasizedBy;
|
||||
}
|
||||
public ScoreableProposal deemphasize() {
|
||||
deemphasizedBy+= DEEMP_VALUE;
|
||||
return this;
|
||||
}
|
||||
public boolean isDeemphasized() {
|
||||
return deemphasizedBy > 0;
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean isAutoInsertable() {
|
||||
// return !isDeemphasized();
|
||||
// }
|
||||
|
||||
// public StyledString getStyledDisplayString() {
|
||||
// StyledString result = new StyledString();
|
||||
// highlightPattern(getHighlightPattern(), getBaseDisplayString(), result);
|
||||
// return result;
|
||||
// }
|
||||
|
||||
// private void highlightPattern(String pattern, String data, StyledString result) {
|
||||
// Styler highlightStyle = CompletionFactory.HIGHLIGHT;
|
||||
// Styler plainStyle = isDeemphasized()?CompletionFactory.DEEMPHASIZE:CompletionFactory.NULL_STYLER;
|
||||
// if (isDeprecated()) {
|
||||
// highlightStyle = CompletionFactory.compose(highlightStyle, CompletionFactory.DEPRECATE);
|
||||
// plainStyle = CompletionFactory.compose(plainStyle, CompletionFactory.DEPRECATE);
|
||||
// }
|
||||
// if (StringUtils.hasText(pattern)) {
|
||||
// int dataPos = 0; int dataLen = data.length();
|
||||
// int patternPos = 0; int patternLen = pattern.length();
|
||||
//
|
||||
// while (dataPos<dataLen && patternPos<patternLen) {
|
||||
// int pChar = pattern.charAt(patternPos++);
|
||||
// int highlightPos = data.indexOf(pChar, dataPos);
|
||||
// if (dataPos<highlightPos) {
|
||||
// result.append(data.substring(dataPos, highlightPos), plainStyle);
|
||||
// }
|
||||
// result.append(data.charAt(highlightPos), highlightStyle);
|
||||
// dataPos = highlightPos+1;
|
||||
// }
|
||||
// if (dataPos<dataLen) {
|
||||
// result.append(data.substring(dataPos), plainStyle);
|
||||
// }
|
||||
// } else { //no pattern to highlight
|
||||
// result.append(data, plainStyle);
|
||||
// }
|
||||
// }
|
||||
|
||||
// protected abstract boolean isDeprecated();
|
||||
// protected abstract String getHighlightPattern();
|
||||
// protected abstract String getBaseDisplayString();
|
||||
|
||||
// @Override
|
||||
// public String getAdditionalProposalInfo() {
|
||||
// HoverInfo hoverInfo = getAdditionalProposalInfo(new NullProgressMonitor());
|
||||
// if (hoverInfo!=null) {
|
||||
// return hoverInfo.getHtml();
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
// @Override
|
||||
// public abstract HoverInfo getAdditionalProposalInfo(IProgressMonitor monitor);
|
||||
|
||||
// @Override
|
||||
// public CharSequence getPrefixCompletionText(IDocument document, int completionOffset) {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public int getPrefixCompletionStart(IDocument document, int completionOffset) {
|
||||
// return completionOffset;
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static class BeanPropertyProposal extends ScoreableProposal {
|
||||
|
||||
private IDocument doc;
|
||||
|
||||
@@ -7,7 +7,6 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.ide.vscode.commons.languageserver.util.IRegion;
|
||||
@@ -691,7 +690,7 @@ public class YamlStructureParser {
|
||||
String indentedText = StringUtil.trimEnd(doc.textBetween(start, end));
|
||||
int indent = getIndent();
|
||||
if (indent>0) {
|
||||
return stripIndentation(indent, indentedText);
|
||||
return StringUtil.stripIndentation(indent, indentedText);
|
||||
}
|
||||
return indentedText;
|
||||
}
|
||||
@@ -702,39 +701,4 @@ public class YamlStructureParser {
|
||||
return keyAliases.getKeyAliases(key);
|
||||
}
|
||||
|
||||
public static String stripIndentation(int indent, String indentedText) {
|
||||
StringBuilder out = new StringBuilder();
|
||||
Pattern NEWLINE = Pattern.compile("(\\n|\\r)+");
|
||||
boolean first = true;
|
||||
Matcher matcher = NEWLINE.matcher(indentedText);
|
||||
int pos = 0;
|
||||
while (matcher.find()) {
|
||||
int newline = matcher.start();
|
||||
int newline_end = matcher.end();
|
||||
String line = indentedText.substring(pos, newline);
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
line = stripIndentationFromLine(indent, line);
|
||||
}
|
||||
out.append(line);
|
||||
out.append(indentedText.substring(newline, newline_end));
|
||||
pos = newline_end;
|
||||
}
|
||||
String line = indentedText.substring(pos);
|
||||
if (!first) {
|
||||
line = stripIndentationFromLine(indent, line);
|
||||
}
|
||||
out.append(line);
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
private static String stripIndentationFromLine(int indent, String line) {
|
||||
int start = 0;
|
||||
while (start<line.length() && start < indent && line.charAt(start)==' ') {
|
||||
start++;
|
||||
}
|
||||
return line.substring(start);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -716,7 +716,7 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
|
||||
);
|
||||
}
|
||||
|
||||
@Ignore @Test public void testContentAssistSimple() throws Exception {
|
||||
@Test public void testContentAssistSimple() throws Exception {
|
||||
defaultTestData();
|
||||
assertCompletion("port<*>",
|
||||
"server:\n"+
|
||||
|
||||
Reference in New Issue
Block a user