Merge branch 'master' of github.com:spring-projects/sts4
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user