Consistent treatment of valuhints in yaml

See: https://www.pivotaltracker.com/story/show/161964105
This commit is contained in:
Kris De Volder
2018-11-15 12:13:04 -08:00
parent f9f33b3a7c
commit f43942ed57
6 changed files with 61 additions and 26 deletions

View File

@@ -70,7 +70,7 @@ public abstract class AbstractYamlAssistContext implements YamlAssistContext {
private static PrefixFinder prefixfinder = new PrefixFinder() {
@Override
protected boolean isPrefixChar(char c) {
return !Character.isWhitespace(c);
return !(Character.isWhitespace(c) || c==',');
}
};
@@ -87,7 +87,7 @@ public abstract class AbstractYamlAssistContext implements YamlAssistContext {
valueStart++;
}
if (offset>=valueStart) {
return doc.textBetween(valueStart, offset);
return prefixfinder.getPrefix(doc.getDocument(), offset, valueStart);
} else {
//only whitespace, or nothing found upto the cursor
return "";

View File

@@ -33,6 +33,7 @@ import org.springframework.ide.vscode.commons.util.Log;
import org.springframework.ide.vscode.commons.util.text.DocumentRegion;
import org.springframework.ide.vscode.commons.util.text.LanguageId;
import org.springframework.ide.vscode.commons.util.text.TextDocument;
import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment;
public class CommonLanguageTools {
@@ -84,6 +85,15 @@ public class CommonLanguageTools {
PropertyInfo prop = index.findLongestCommonPrefixEntry(propertyName);
if (prop!=null) {
HintProvider hintProvider = prop.getHints(typeUtil, false);
if (prop.getId().length()<propertyName.length()) {
//true prefix
//TODO: properly process remaining portion of property name
try {
hintProvider = hintProvider.traverse(YamlPathSegment.valueAt(0));
} catch (Exception e) {
Log.log(e);
}
}
if (!HintProviders.isNull(hintProvider)) {
allHints.addAll(hintProvider.getValueHints(query));
}

View File

@@ -142,20 +142,12 @@ public class PropertyInfo {
return description;
}
public HintProvider getHints(TypeUtil typeUtil, boolean dimensionAware) {
public HintProvider getHints(TypeUtil typeUtil) {
Type type = TypeParser.parse(this.type);
if (TypeUtil.isMap(type)) {
return HintProviders.forMap(keyHints(typeUtil), valueHints(typeUtil), TypeUtil.getDomainType(type), dimensionAware);
return HintProviders.forMap(keyHints(typeUtil), valueHints(typeUtil), TypeUtil.getDomainType(type));
} else if (TypeUtil.isSequencable(type)) {
if (dimensionAware) {
if (TypeUtil.isSequencable(type)) {
return HintProviders.forDomainAt(valueHints(typeUtil), TypeUtil.getDimensionality(type));
} else {
return HintProviders.forHere(valueHints(typeUtil));
}
} else {
return HintProviders.forAllValueContexts(valueHints(typeUtil));
}
return HintProviders.forAllValueContexts(valueHints(typeUtil));
} else {
return HintProviders.forHere(valueHints(typeUtil));
}

View File

@@ -166,7 +166,7 @@ public class HintProviders {
return p == NULL || p==null;
}
public static HintProvider forMap(HintProvider _keyProvider, HintProvider _valueProvider, final Type valueType, final boolean dimensionAware) {
public static HintProvider forMap(HintProvider _keyProvider, HintProvider _valueProvider, final Type valueType) {
final HintProvider keyProvider = notNull(_keyProvider);
final HintProvider valueProvider = notNull(_valueProvider);
if (isNull(keyProvider) && isNull(valueProvider)) {
@@ -179,11 +179,7 @@ public class HintProviders {
switch (s.getType()) {
case VAL_AT_INDEX:
case VAL_AT_KEY:
if (dimensionAware) {
return forHere(valueProvider);
} else {
return forAllValueContexts(valueProvider);
}
return forAllValueContexts(valueProvider);
default:
return NULL;
}
@@ -191,12 +187,7 @@ public class HintProviders {
@Override
public List<StsValueHint> getValueHints(String query) {
if (dimensionAware) {
//pickier, completions only suggested in the domain of map, but not for map itself.
return ImmutableList.of();
} else {
return valueProvider.getValueHints(query);
}
return ImmutableList.of();
}
@Override

View File

@@ -515,7 +515,7 @@ public abstract class ApplicationYamlAssistContext extends AbstractYamlAssistCon
} else if (subIndex.getExactMatch()!=null) {
IndexContext asIndexContext = new IndexContext(getDocument(), documentSelector, contextPath.append(s), subIndex, completionFactory, typeUtil, conf, javaElementLocationProvider);
PropertyInfo prop = subIndex.getExactMatch();
return new TypeContext(asIndexContext, contextPath.append(s), TypeParser.parse(prop.getType()), completionFactory, typeUtil, conf, prop.getHints(typeUtil, true), javaElementLocationProvider);
return new TypeContext(asIndexContext, contextPath.append(s), TypeParser.parse(prop.getType()), completionFactory, typeUtil, conf, prop.getHints(typeUtil, false), javaElementLocationProvider);
}
}
//Unsuported navigation => no context for assist

View File

@@ -256,6 +256,48 @@ public class ApplicationYamlEditorTest extends AbstractPropsEditorTest {
);
}
@Test public void userDefinedLoggingGroupsValueCompletions() throws Exception {
useProject(createPredefinedMavenProject("empty-boot-2.1.0-app"));
assertCompletionWithLabel(
"logging:\n" +
" group:\n"+
" whatever:\n" +
" - demo<*>"
, //==============
"com.example.demo",
//=>
"logging:\n" +
" group:\n"+
" whatever:\n" +
" - com.example.demo<*>"
);
assertCompletionWithLabel(
"logging:\n" +
" group:\n"+
" whatever: demo<*>"
, //==============
"com.example.demo",
//=>
"logging:\n" +
" group:\n"+
" whatever: com.example.demo<*>"
);
assertCompletionWithLabel(
"logging:\n" +
" group:\n"+
" whatever: stuff,demo<*>"
, //==============
"com.example.demo",
//=>
"logging:\n" +
" group:\n"+
" whatever: stuff,com.example.demo<*>"
);
}
///////////////////// ported tests from old STS code base ////////////////////////////////////////////////
@Test public void testHovers() throws Exception {