Merge branch 'master' of github.com:spring-projects/sts4

This commit is contained in:
Kris De Volder
2017-10-03 16:28:11 -07:00
5 changed files with 95 additions and 12 deletions

View File

@@ -14,8 +14,10 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.springframework.ide.vscode.commons.languageserver.completion.DocumentEdits;
import org.springframework.ide.vscode.commons.languageserver.completion.IndentUtil;
import org.springframework.ide.vscode.commons.languageserver.util.DocumentRegion;
import org.springframework.ide.vscode.commons.languageserver.util.SnippetBuilder;
import org.springframework.ide.vscode.commons.util.text.IDocument;
import com.google.common.base.Supplier;
@@ -34,8 +36,14 @@ public class JavaSnippetBuilder{
}
public DocumentEdits createEdit(DocumentRegion query, String template) {
DocumentEdits edit = new DocumentEdits(query.getDocument());
edit.replace(query.getStart(), query.getEnd(), createSnippet(template));
IDocument doc = query.getDocument();
IndentUtil indentUtil = new IndentUtil(doc);
DocumentEdits edit = new DocumentEdits(doc);
String snippet = createSnippet(template);
String indentedSnippet = indentUtil.applyIndentation(snippet, indentUtil.getReferenceIndent(query.getStart(), doc)) ;
edit.replace(query.getStart(), query.getEnd(), indentedSnippet);
return edit;
}

View File

@@ -0,0 +1,56 @@
/*******************************************************************************
* Copyright (c) 2017 Pivotal, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Pivotal, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.commons.languageserver.completion;
import org.springframework.ide.vscode.commons.languageserver.util.DocumentRegion;
import org.springframework.ide.vscode.commons.util.Assert;
import org.springframework.ide.vscode.commons.util.text.IDocument;
import org.springframework.ide.vscode.commons.util.text.IRegion;
import com.google.common.base.Strings;
/**
* Helper methods to manipulate indentation levels in yaml content.
*
* @author Kris De Volder
*/
public class IndentUtil {
/**
* Some functions introduce line separators and this may depend on the context (i.e. default line separator
* for the current document).
*/
public final String NEWLINE;
public IndentUtil(String newline) {
this.NEWLINE = newline;
Assert.isNotNull(NEWLINE);
}
public IndentUtil(IDocument doc) {
this(doc.getDefaultLineDelimiter());
}
public String applyIndentation(String text, String indentStr) {
return text.replaceAll("\\n", "\n"+indentStr);
}
public String getReferenceIndent(int offset, IDocument doc) {
//Apply indentfix, this is magic vscode seems to apply to edits returned by language server. So our harness has to
// mimick that behavior. See https://github.com/Microsoft/language-server-protocol/issues/83
IRegion referenceLine = doc.getLineInformationOfOffset(offset);
DocumentRegion queryPrefix = new DocumentRegion(doc, referenceLine.getOffset(), offset);
return queryPrefix.leadingWhitespace().toString();
}
}

View File

@@ -31,6 +31,7 @@ import org.springframework.ide.vscode.commons.languageserver.completion.Document
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.SortKeys;
import org.springframework.ide.vscode.commons.util.BadLocationException;
import org.springframework.ide.vscode.commons.util.Log;
import org.springframework.ide.vscode.commons.util.Renderable;
import org.springframework.ide.vscode.commons.util.StringUtil;
@@ -228,15 +229,18 @@ 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.
//See here: https://github.com/Microsoft/language-server-protocol/issues/83
int referenceLine = start.getLine();
int referenceLineIndent = doc.getLineIndentation(referenceLine);
int vscodeMagicIndent = Math.min(start.getCharacter(), referenceLineIndent);
return vscodeMagicIndent>0
? StringUtil.stripIndentation(vscodeMagicIndent, newText)
: newText;
IndentUtil indenter = new IndentUtil(doc);
try {
String refIndent = indenter.getReferenceIndent(doc.toOffset(start), doc);
if (!refIndent.isEmpty()) {
return StringUtil.stripIndentation(refIndent, newText);
}
} catch (BadLocationException e) {
Log.log(e);
}
return newText;
}
@Override
public CompletableFuture<CompletionItem> resolveCompletion(CompletionItem unresolved) {
resolver.resolveNow(unresolved);

View File

@@ -295,4 +295,13 @@ public class DocumentRegion implements CharSequence {
public Range asRange() throws BadLocationException {
return doc.toRange(asRegion());
}
public DocumentRegion leadingWhitespace() {
int howMany = 0;
int len = length();
while (howMany<len && Character.isWhitespace(charAt(howMany))) {
howMany++;
}
return subSequence(0, howMany);
}
}

View File

@@ -20,6 +20,8 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.google.common.base.Strings;
public class StringUtil {
public static boolean hasText(String name) {
return name!=null && !name.trim().equals("");
@@ -153,7 +155,7 @@ public class StringUtil {
* 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) {
public static String stripIndentation(String indent, String indentedText) {
StringBuilder out = new StringBuilder();
boolean first = true;
Matcher matcher = NEWLINE.matcher(indentedText);
@@ -179,9 +181,13 @@ public class StringUtil {
return out.toString();
}
public static String stripIndentationFromLine(int indent, String line) {
public static String stripIndentation(int indent, String indentedText) {
return stripIndentation(Strings.repeat(" ", indent), indentedText);
}
public static String stripIndentationFromLine(String indent, String line) {
int start = 0;
while (start<line.length() && start < indent && line.charAt(start)==' ') {
while (start<line.length() && start < indent.length() && line.charAt(start)==indent.charAt(start)) {
start++;
}
return line.substring(start);