diff --git a/concourse/tasks/fatjars-language-servers.sh b/concourse/tasks/fatjars-language-servers.sh index 834396c30c..7bd276170e 100755 --- a/concourse/tasks/fatjars-language-servers.sh +++ b/concourse/tasks/fatjars-language-servers.sh @@ -15,7 +15,7 @@ else fi cd ${sources} -xvfb-run ./mvnw clean install -DargLine="-Dlsp.completions.indentation.enable=true -Dlsp.yaml.completions.errors.disable=true" +xvfb-run ./mvnw clean install -DargLine="-Dlsp.yaml.completions.errors.disable=true" # Copy fatjars to `out` directory timestamp=`date -u +%Y%m%d%H%M` diff --git a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/SpringBootLanguageServer.java b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/SpringBootLanguageServer.java index e17c26c702..bcc9460e08 100644 --- a/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/SpringBootLanguageServer.java +++ b/eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/SpringBootLanguageServer.java @@ -43,7 +43,6 @@ private List getJVMArgs() { // args.add("-Xdebug"); // args.add("-Xrunjdwp:server=y,transport=dt_socket,address=1044,suspend=n"); - args.add("-Dlsp.completions.indentation.enable=true"); args.add("-Xmx1024m"); args.add("-XX:TieredStopAtLevel=1"); diff --git a/eclipse-language-servers/org.springframework.tooling.bosh.ls/src/org/springframework/tooling/bosh/ls/BoshLanguageServer.java b/eclipse-language-servers/org.springframework.tooling.bosh.ls/src/org/springframework/tooling/bosh/ls/BoshLanguageServer.java index 36b2a3b82e..537bcf3fb4 100644 --- a/eclipse-language-servers/org.springframework.tooling.bosh.ls/src/org/springframework/tooling/bosh/ls/BoshLanguageServer.java +++ b/eclipse-language-servers/org.springframework.tooling.bosh.ls/src/org/springframework/tooling/bosh/ls/BoshLanguageServer.java @@ -31,7 +31,6 @@ public BoshLanguageServer() { "application.properties", Arrays.asList( "-Dlsp.lazy.completions.disable=true", - "-Dlsp.completions.indentation.enable=true", "-XX:TieredStopAtLevel=1" ) ); diff --git a/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls/src/org/springframework/tooling/cloudfoundry/manifest/ls/CloudFoundryManifestLanguageServer.java b/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls/src/org/springframework/tooling/cloudfoundry/manifest/ls/CloudFoundryManifestLanguageServer.java index 2415036417..4927a4c511 100644 --- a/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls/src/org/springframework/tooling/cloudfoundry/manifest/ls/CloudFoundryManifestLanguageServer.java +++ b/eclipse-language-servers/org.springframework.tooling.cloudfoundry.manifest.ls/src/org/springframework/tooling/cloudfoundry/manifest/ls/CloudFoundryManifestLanguageServer.java @@ -47,7 +47,6 @@ public CloudFoundryManifestLanguageServer() { "application.properties", Arrays.asList( "-Dlsp.lazy.completions.disable=true", - "-Dlsp.completions.indentation.enable=true", "-XX:TieredStopAtLevel=1" ) ); diff --git a/eclipse-language-servers/org.springframework.tooling.concourse.ls/src/org/springframework/tooling/concourse/ls/ConcourseLanguageServer.java b/eclipse-language-servers/org.springframework.tooling.concourse.ls/src/org/springframework/tooling/concourse/ls/ConcourseLanguageServer.java index ec8fccfa83..c9c60e7892 100644 --- a/eclipse-language-servers/org.springframework.tooling.concourse.ls/src/org/springframework/tooling/concourse/ls/ConcourseLanguageServer.java +++ b/eclipse-language-servers/org.springframework.tooling.concourse.ls/src/org/springframework/tooling/concourse/ls/ConcourseLanguageServer.java @@ -31,7 +31,6 @@ public ConcourseLanguageServer() { "application.properties", Arrays.asList( "-Dlsp.lazy.completions.disable=true", - "-Dlsp.completions.indentation.enable=true", "-XX:TieredStopAtLevel=1" ) ); diff --git a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/completion/VscodeCompletionEngineAdapter.java b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/completion/VscodeCompletionEngineAdapter.java index 191b42df45..9be52cce60 100644 --- a/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/completion/VscodeCompletionEngineAdapter.java +++ b/headless-services/commons/commons-language-server/src/main/java/org/springframework/ide/vscode/commons/languageserver/completion/VscodeCompletionEngineAdapter.java @@ -48,9 +48,7 @@ import org.springframework.ide.vscode.commons.languageserver.util.SimpleTextDocumentService; import org.springframework.ide.vscode.commons.languageserver.util.SortKeys; import org.springframework.ide.vscode.commons.protocol.CursorMovement; -import org.springframework.ide.vscode.commons.util.BadLocationException; import org.springframework.ide.vscode.commons.util.Renderable; -import org.springframework.ide.vscode.commons.util.StringUtil; import org.springframework.ide.vscode.commons.util.text.IRegion; import org.springframework.ide.vscode.commons.util.text.TextDocument; @@ -399,7 +397,7 @@ private static void resolveItem(TextDocument doc, ICompletionProposal completion private void resolveMainEdit(TextDocument doc, ICompletionProposal completion, CompletionItem item) { AtomicBoolean usedSnippets = new AtomicBoolean(); - Optional mainEdit = adaptEdits(doc, completion.getTextEdit(), usedSnippets, isCommandExecution(item)); + Optional mainEdit = adaptEdits(doc, completion.getTextEdit(), usedSnippets); if (mainEdit.isPresent()) { item.setTextEdit(Either.forLeft(mainEdit.get())); if (server.hasCompletionSnippetSupport()) { @@ -419,7 +417,7 @@ private void resolveAdditionalEdits(TextDocument doc, ICompletionProposal comple if (!edit.isResolved()) { edit.resolve(); } - adaptEdits(doc, edit, null, isCommandExecution(item)).ifPresent(extraEdit -> { + adaptEdits(doc, edit, null).ifPresent(extraEdit -> { item.setAdditionalTextEdits(ImmutableList.of(extraEdit)); }); } else { @@ -435,7 +433,7 @@ private static String toMarkdown(Renderable r) { return null; } - private Optional adaptEdits(TextDocument doc, DocumentEdits edits, AtomicBoolean usedSnippets, boolean ignoreClientIndent) { + private Optional adaptEdits(TextDocument doc, DocumentEdits edits, AtomicBoolean usedSnippets) { try { TextReplace replaceEdit = edits == null ? null : edits.asReplacement(doc); if (usedSnippets != null && edits != null) { @@ -448,9 +446,10 @@ private Optional adaptEdits(TextDocument doc, DocumentEdits edits, Ato TextDocument newDoc = doc.copy(); edits.apply(newDoc); TextEdit vscodeEdit = new TextEdit(); - vscodeEdit.setRange(doc.toRange(replaceEdit.start, replaceEdit.end-replaceEdit.start)); + vscodeEdit.setRange(doc.toRange(replaceEdit.start, replaceEdit.end - replaceEdit.start)); String newText = replaceEdit.newText; IRegion selection = edits.getSelection(); + if (selection!=null && usedSnippets != null) { //Special handling for the case where cursor is *not* just at the end of the newText int cursor = selection.getOffset() + selection.getLength(); @@ -465,9 +464,7 @@ private Optional adaptEdits(TextDocument doc, DocumentEdits edits, Ato usedSnippets.set(true); } } -// if (isMagicIndentingClient() && !ignoreClientIndent) { -// newText = vscodeIndentFix(doc, vscodeEdit.getRange().getStart(), replaceEdit.newText); -// } + vscodeEdit.setNewText(newText); return Optional.of(vscodeEdit); } @@ -477,42 +474,6 @@ private Optional adaptEdits(TextDocument doc, DocumentEdits edits, Ato } } - /** - * When this is true, it means the client does 'magic indents' (basically.. that is only on vscode since the magics aren't part of the LSP spec). - */ -// private boolean isMagicIndentingClient() { -// return !Boolean.getBoolean("lsp.completions.indentation.enable"); -// } - - private static String vscodeIndentFix(TextDocument doc, Position start, String newText) { - //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 - 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.error("{}", e); - } - return newText; - } - - private static String revertVscodeIndentFix(TextDocument doc, Position start, String newText) { - IndentUtil indenter = new IndentUtil(doc); - try { - String refIndent = indenter.getReferenceIndent(doc.toOffset(start), doc); - if (!refIndent.isEmpty()) { - return StringUtil.reverseStripIndentation(refIndent, newText); - } - } catch (BadLocationException e) { - log.error("{}", e); - } - return newText; - } - @Override public CompletionItem resolveCompletion(CancelChecker cancelToken, CompletionItem unresolved) { resolver.resolveNow(cancelToken, unresolved); @@ -532,7 +493,4 @@ public interface CompletionFilter { } - private boolean isCommandExecution(CompletionItem item) { - return RESOLVE_EDIT_COMMAND == item.getLabel(); - } } diff --git a/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/Editor.java b/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/Editor.java index 1703111c87..c5eaeba696 100644 --- a/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/Editor.java +++ b/headless-services/commons/language-server-test-harness/src/main/java/org/springframework/ide/vscode/languageserver/testharness/Editor.java @@ -465,18 +465,6 @@ public void apply(CompletionItem completion) throws Exception { String replaceWith = edit.getLeft().getNewText(); int cursorReplaceOffset = 0; -// if (!Boolean.getBoolean("lsp.completions.indentation.enable")) { -// //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 -// int referenceLine = edit.getLeft().getRange().getStart().getLine(); -// int cursorOffset = edit.getLeft().getRange().getStart().getCharacter(); -// String referenceIndent = doc.getLineIndentString(referenceLine); -// if (cursorOffset= 0) { diff --git a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/test/ApplicationYamlEditorTest.java b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/test/ApplicationYamlEditorTest.java index b60d55acf8..1f2d620164 100644 --- a/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/test/ApplicationYamlEditorTest.java +++ b/headless-services/spring-boot-language-server/src/test/java/org/springframework/ide/vscode/boot/test/ApplicationYamlEditorTest.java @@ -651,68 +651,65 @@ void testJumpyInsertion() throws Exception { //This test not working in vscode. It is only meant to work in environment that // a) don't apply magic indents // b) allow completions with no restrictions on the main edit. - withSystemProperty("lsp.completions.indentation.enable", "true", () -> { - String[] names = {"foo", "nested", "bar"}; - int levels = 4; - generateNestedProperties(levels, names, ""); - - //Note: jumpy completions use the snippet '$0' placeholder to move the cursor - //Our harness actually does not understand / interpret snippet placeholders. - //Thus the examples below expected outcome will have both a '$0' and '<*>' - //showing the cursor position. You can think of the second '<*>' as showing - //where the cursor will end up when the client doesn't have snippet support capability. - - assertCompletion( - "foo:\n" + - " nested:\n" + - " bar:\n" + - " foo:\n" + - "other:\n" + - "foo.nested.bar.b<*>" - , - "foo:\n" + - " nested:\n" + - " bar:\n" + - " foo:\n" + - " bar: $0\n" + - "other:<*>" - ); - - assertCompletion( - "foo:\n" + - " nested:\n" + - " bar:\n" + - " foo:\n" + - "other:\n" + - "foo.nested.nested.b<*>" - , - "foo:\n" + - " nested:\n" + - " bar:\n" + - " foo:\n" + - " nested:\n" + - " bar: $0\n" + - "other:<*>" - ); - - assertCompletion( - "foo.nested.nested.b<*>\n" + - "foo:\n" + - " nested:\n" + - " bar:\n" + - " foo:\n" + - "other:" - , - "foo:\n" + - " nested:\n" + - " bar:\n" + - " foo:\n" + - " nested:\n" + - " bar: <*>\n" + - "other:" - ); - return; // Skip running this test - }); + String[] names = {"foo", "nested", "bar"}; + int levels = 4; + generateNestedProperties(levels, names, ""); + + //Note: jumpy completions use the snippet '$0' placeholder to move the cursor + //Our harness actually does not understand / interpret snippet placeholders. + //Thus the examples below expected outcome will have both a '$0' and '<*>' + //showing the cursor position. You can think of the second '<*>' as showing + //where the cursor will end up when the client doesn't have snippet support capability. + + assertCompletion( + "foo:\n" + + " nested:\n" + + " bar:\n" + + " foo:\n" + + "other:\n" + + "foo.nested.bar.b<*>" + , + "foo:\n" + + " nested:\n" + + " bar:\n" + + " foo:\n" + + " bar: $0\n" + + "other:<*>" + ); + + assertCompletion( + "foo:\n" + + " nested:\n" + + " bar:\n" + + " foo:\n" + + "other:\n" + + "foo.nested.nested.b<*>" + , + "foo:\n" + + " nested:\n" + + " bar:\n" + + " foo:\n" + + " nested:\n" + + " bar: $0\n" + + "other:<*>" + ); + + assertCompletion( + "foo.nested.nested.b<*>\n" + + "foo:\n" + + " nested:\n" + + " bar:\n" + + " foo:\n" + + "other:" + , + "foo:\n" + + " nested:\n" + + " bar:\n" + + " foo:\n" + + " nested:\n" + + " bar: <*>\n" + + "other:" + ); } @Test