From 1b179da90e2f47c628ca4c31320a56a465197134 Mon Sep 17 00:00:00 2001 From: Kris De Volder Date: Wed, 2 Aug 2017 17:09:37 -0700 Subject: [PATCH] Indentation related bugfix for completions that jump to next line --- .../ide/vscode/bosh/BoshEditorTest.java | 2 +- .../yaml/completion/YTypeAssistContext.java | 24 +++++++++++++------ .../yaml/completion/YamlPathEdits.java | 12 ++-------- .../commons/yaml/util/YamlIndentUtil.java | 10 ++++++++ 4 files changed, 30 insertions(+), 18 deletions(-) diff --git a/headless-services/bosh-language-server/src/test/java/org/springframework/ide/vscode/bosh/BoshEditorTest.java b/headless-services/bosh-language-server/src/test/java/org/springframework/ide/vscode/bosh/BoshEditorTest.java index c49ede0e2..575e258ae 100644 --- a/headless-services/bosh-language-server/src/test/java/org/springframework/ide/vscode/bosh/BoshEditorTest.java +++ b/headless-services/bosh-language-server/src/test/java/org/springframework/ide/vscode/bosh/BoshEditorTest.java @@ -1828,7 +1828,7 @@ public class BoshEditorTest { ); } - @Test @Ignore public void keyCompletionThatNeedsANewline() throws Exception { + @Test public void keyCompletionThatNeedsANewline() throws Exception { Editor editor = harness.newEditor( "name: foo\n" + "update: canwa<*>" diff --git a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/YTypeAssistContext.java b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/YTypeAssistContext.java index 8361a1157..66963f72b 100644 --- a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/YTypeAssistContext.java +++ b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/YTypeAssistContext.java @@ -34,6 +34,7 @@ import org.springframework.ide.vscode.commons.util.Log; import org.springframework.ide.vscode.commons.util.PartialCollection; import org.springframework.ide.vscode.commons.util.Renderable; import org.springframework.ide.vscode.commons.util.ValueParseException; +import org.springframework.ide.vscode.commons.yaml.completion.DefaultCompletionFactory.ValueProposal; import org.springframework.ide.vscode.commons.yaml.hover.YPropertyInfoTemplates; import org.springframework.ide.vscode.commons.yaml.path.YamlPath; import org.springframework.ide.vscode.commons.yaml.path.YamlPathSegment; @@ -49,6 +50,7 @@ import org.springframework.ide.vscode.commons.yaml.snippet.Snippet; import org.springframework.ide.vscode.commons.yaml.snippet.TypeBasedSnippetProvider; import org.springframework.ide.vscode.commons.yaml.structure.YamlDocument; import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SNode; +import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SNodeType; import org.springframework.ide.vscode.commons.yaml.util.YamlIndentUtil; import com.google.common.base.Strings; @@ -99,7 +101,7 @@ public class YTypeAssistContext extends AbstractYamlAssistContext { String query = getPrefix(doc, node, offset); List completions = getValueCompletions(doc, node, offset, query); if (completions.isEmpty()) { - completions = getKeyCompletions(doc, offset, query); + completions = getKeyCompletions(doc, node, offset, query); TypeBasedSnippetProvider snippetProvider = typeUtil.getSnippetProvider(); if (snippetProvider!=null) { Collection snippets = snippetProvider.getSnippets(type); @@ -130,7 +132,7 @@ public class YTypeAssistContext extends AbstractYamlAssistContext { return completions; } - public List getKeyCompletions(YamlDocument doc, int offset, String query) throws Exception { + public List getKeyCompletions(YamlDocument doc, SNode node, int offset, String query) throws Exception { int queryOffset = offset - query.length(); DynamicSchemaContext dynamicCtxt = getSchemaContext(); List allProperties = typeUtil.getProperties(type); @@ -153,13 +155,20 @@ public class YTypeAssistContext extends AbstractYamlAssistContext { YType YType = p.getType(); edits.delete(queryOffset, query); int referenceIndent = doc.getColumn(queryOffset); - if (queryOffset>0 && !Character.isWhitespace(doc.getChar(queryOffset-1))) { + boolean needNewline = node.getNodeType()==SNodeType.KEY; + StringBuilder snippet = new StringBuilder(); + if (needNewline) { + snippet.append("\n"); + referenceIndent = YamlIndentUtil.getNewChildKeyIndent(node); + } else if (queryOffset>0 && !Character.isWhitespace(doc.getChar(queryOffset-1))) { //See https://www.pivotaltracker.com/story/show/137722057 - edits.insert(queryOffset, " "); + snippet.append(" "); referenceIndent++; } - String snippet = p.getName()+":" +appendTextFor(YType); - edits.insert(queryOffset, indenter.applyIndentation(snippet, referenceIndent)); + snippet.append(p.getName()); + snippet.append(":"); + snippet.append(appendTextFor(YType)); + edits.insert(queryOffset, indenter.applyIndentation(snippet.toString(), referenceIndent)); ICompletionProposal completion = completionFactory().beanProperty(doc.getDocument(), contextPath.toPropString(), getType(), query, p, score, edits, typeUtil); @@ -429,7 +438,8 @@ public class YTypeAssistContext extends AbstractYamlAssistContext { // its not required for them. So we should add it along with the dash. try { Integer insertAt = textEdit.getFirstEditStart(); - if (insertAt!=null) { + if (insertAt!=null && c instanceof ValueProposal) { + //Value proposals don't automatically get newline added (because they don't require it), so we dmust add it here. return !"".equals(doc.getLineTextBefore(insertAt).trim()); } } catch (Exception e) { diff --git a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/YamlPathEdits.java b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/YamlPathEdits.java index 43f869273..864446897 100644 --- a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/YamlPathEdits.java +++ b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/completion/YamlPathEdits.java @@ -88,7 +88,7 @@ public class YamlPathEdits extends DocumentEdits { } private void createNewPath(SChildBearingNode parent, YamlPath path, String appendText) throws Exception { - int indent = getChildIndent(parent); + int indent = YamlIndentUtil.getNewChildKeyIndent(parent); int insertionPoint = getNewPathInsertionOffset(parent); boolean startOnNewLine = true; insert(insertionPoint, createPathInsertionText(path, indent, startOnNewLine, appendText)); @@ -112,14 +112,6 @@ public class YamlPathEdits extends DocumentEdits { return buf.toString(); } - private int getChildIndent(SNode parent) { - if (parent.getNodeType()==SNodeType.DOC) { - return parent.getIndent(); - } else { - return parent.getIndent()+YamlIndentUtil.INDENT_BY; - } - } - private int getNewPathInsertionOffset(SChildBearingNode parent) throws Exception { int insertAfterLine = doc.getLineOfOffset(parent.getTreeEnd()); while (insertAfterLine>=0 && doc.getLineIndentation(insertAfterLine)==-1) { @@ -142,7 +134,7 @@ public class YamlPathEdits extends DocumentEdits { } public void createPathInPlace(SNode contextNode, YamlPath relativePath, int insertionPoint, String appendText) throws Exception { - int indent = getChildIndent(contextNode); + int indent = YamlIndentUtil.getNewChildKeyIndent(contextNode); insert(insertionPoint, createPathInsertionText(relativePath, indent, needNewline(contextNode, insertionPoint), appendText)); } diff --git a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/util/YamlIndentUtil.java b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/util/YamlIndentUtil.java index 51f44e002..a358489d3 100644 --- a/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/util/YamlIndentUtil.java +++ b/headless-services/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/util/YamlIndentUtil.java @@ -14,6 +14,8 @@ import org.springframework.ide.vscode.commons.util.Assert; import org.springframework.ide.vscode.commons.util.StringUtil; import org.springframework.ide.vscode.commons.util.text.IDocument; import org.springframework.ide.vscode.commons.yaml.structure.YamlDocument; +import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SNode; +import org.springframework.ide.vscode.commons.yaml.structure.YamlStructureParser.SNodeType; import com.google.common.base.Strings; @@ -125,6 +127,14 @@ public class YamlIndentUtil { return text.replaceAll("\\n", "\n"+indentStr); } + public static int getNewChildKeyIndent(SNode parent) { + if (parent.getNodeType()==SNodeType.DOC) { + return parent.getIndent(); + } else { + return parent.getIndent()+INDENT_BY; + } + } + /** * Increase offset by indentation. Take care when 'indent' is -1 (unkownn) to * just return offset unmodified.