No indent list item completion below map key

This commit is contained in:
Kris De Volder
2016-10-12 13:34:21 -07:00
parent d4439b246b
commit 47daa65afe
7 changed files with 109 additions and 110 deletions

View File

@@ -35,6 +35,7 @@ import org.springframework.ide.vscode.yaml.structure.YamlDocument;
import org.springframework.ide.vscode.yaml.structure.YamlStructureParser.SChildBearingNode;
import org.springframework.ide.vscode.yaml.structure.YamlStructureParser.SKeyNode;
import org.springframework.ide.vscode.yaml.structure.YamlStructureParser.SNode;
import org.springframework.ide.vscode.yaml.util.YamlIndentUtil;
public class YTypeAssistContext extends AbstractYamlAssistContext {
@@ -116,13 +117,14 @@ public class YTypeAssistContext extends AbstractYamlAssistContext {
*/
protected String appendTextFor(YType type) {
//Note that proper indentation after each \n" is added automatically
//so the strings created here do not need to contain indentation spaces.
//to align with the parent. The strings created here only need to contain
//indentation spaces to indent *more* than the parent node.
if (type==null) {
//Assume its some kind of pojo bean
return "\n";
return "\n"+YamlIndentUtil.INDENT_STR;
} else if (typeUtil.isMap(type)) {
//ready to enter nested map key on next line
return "\n";
return "\n"+YamlIndentUtil.INDENT_STR;
} if (typeUtil.isSequencable(type)) {
//ready to enter sequence element on next line
return "\n- ";
@@ -131,7 +133,7 @@ public class YTypeAssistContext extends AbstractYamlAssistContext {
return " ";
} else {
//Assume its some kind of pojo bean
return "\n";
return "\n"+YamlIndentUtil.INDENT_STR;
}
}

View File

@@ -94,17 +94,6 @@ public class YamlPathEdits extends DocumentEdits {
insert(insertionPoint, createPathInsertionText(path, indent, startOnNewLine, appendText));
}
/**
* Yuck! This component behaves a little differently when working in service of vscode. This is because
* when vscode applies completions it already does some magic indentation fixing (which is not really
* documented see: https://github.com/Microsoft/language-server-protocol/issues/83
* <p>
* We have to counteract the magic fixing of indentation by avoiding to do these fixings ourself. Discovering
* which things we have to counteract is trial and error and probably specific to vscode's implementation
* of LSP support only.
*/
private boolean vsCode = true;
protected String createPathInsertionText(YamlPath path, int indent, boolean startOnNewLine, String appendText) {
StringBuilder buf = new StringBuilder();
for (int i = 0; i < path.size(); i++) {
@@ -114,11 +103,9 @@ public class YamlPathEdits extends DocumentEdits {
String key = path.getSegment(i).toPropString();
buf.append(YamlUtil.stringEscape(key));
buf.append(":");
indent += YamlIndentUtil.INDENT_BY;
}
if (vsCode) {
buf.append(indentUtil.applyIndentation(appendText, YamlIndentUtil.INDENT_BY));
} else {
if (i<path.size()-1) {
indent += YamlIndentUtil.INDENT_BY;
}
buf.append(indentUtil.applyIndentation(appendText, indent));
}
return buf.toString();

View File

@@ -87,7 +87,7 @@ public class YamlStructureParser {
}
private YamlLineReader input;
private final KeyAliases keyAliases;
public static class YamlLine {
@@ -222,6 +222,7 @@ public class YamlStructureParser {
return indent;
}
@Override
public final String toString() {
StringWriter out = new StringWriter();
try {
@@ -502,6 +503,7 @@ public class YamlStructureParser {
super(parent, doc, indent, start, end);
}
@Override
public int getTreeEnd() {
return getNodeEnd();
}
@@ -683,71 +685,56 @@ public class YamlStructureParser {
* This includes all the text starting from the ':' upto the very end of this node,
* including the text for this node's children (if any).
*/
public String getValue() {
public String getValueWithRelativeIndent() {
int start = getColonOffset()+1;
int end = getTreeEnd();
String indentedText = StringUtil.trimEnd(doc.textBetween(start, end));
List<SNode> children = getChildren();
int indent = determineIndentation(children);
int indent = getIndent();
if (indent>0) {
return stripIndentation(indent, indentedText);
}
return indentedText;
}
private 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;
}
out.append(stripIndentationFromLine(indent, indentedText.substring(pos)));
return out.toString();
}
private String stripIndentationFromLine(int indent, String line) {
int start = 0;
while (start<line.length() && start < indent && line.charAt(start)==' ') {
start++;
}
return line.substring(start);
}
/**
* Determine the indentation of a block of children.
*/
private int determineIndentation(List<SNode> children) {
//The tricky bit is that the block may start with comment nodes which provide no hints about the indentation
//indicated by indentation level = -1
//So... we must take indentation from the first node that actually has one
if (children!=null) {
for (SNode c : children) {
int indent = c.getIndent();
if (indent>=0) {
return indent;
}
}
}
return -1; //Couldn't determine it.
}
}
private Iterable<String> getKeyAliases(String key) {
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);
}
}

View File

@@ -13,6 +13,8 @@ package org.springframework.ide.vscode.yaml.util;
import org.springframework.ide.vscode.util.Assert;
import org.springframework.ide.vscode.yaml.structure.YamlDocument;
import com.google.common.base.Strings;
/**
* Helper methods to manipulate indentation levels in yaml content.
*
@@ -26,6 +28,8 @@ public class YamlIndentUtil {
*/
public static final int INDENT_BY = 2;
public static final String INDENT_STR = Strings.repeat(" ", INDENT_BY);
/**
* Some functions introduce line separators and this may depend on the context (i.e. default line separator
* for the current document).