No indent list item completion below map key
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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).
|
||||
|
||||
Reference in New Issue
Block a user