This is an automated email from the ASF dual-hosted git repository.
jlahoda pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-netbeans.git
The following commit(s) were added to refs/heads/master by this push:
new c95b336 Various improvements to the Language Server Protocol client.
c95b336 is described below
commit c95b336f711c12413d69598b252c1b3cb8ab431f
Author: Jan Lahoda <[email protected]>
AuthorDate: Sun Jan 27 20:19:24 2019 +0100
Various improvements to the Language Server Protocol client.
* Creating and using a utility to convert FileObjects to URI strings.
* Track the language server process.
* Sending events asynchronously.
* Improving LSP code completion.
* Improvements to the LSP client: code completion tooltip, stopping all
server on shutdown, handling workspace/configuration request.
* Some more improvements: sending client capabilities (empty now); don't
try to read fixes for errors when the server does not support codeActions.
---
.../netbeans/modules/lsp/client/LSPBindings.java | 52 +++++++--
.../modules/lsp/client/{bindings => }/Utils.java | 7 +-
.../modules/lsp/client/bindings/CodeActions.java | 6 +-
.../client/bindings/CompletionProviderImpl.java | 129 +++++++++++++++++++--
.../lsp/client/bindings/HyperlinkProviderImpl.java | 5 +-
.../lsp/client/bindings/LanguageClientImpl.java | 31 ++++-
.../lsp/client/bindings/NavigatorPanelImpl.java | 4 +-
.../TextDocumentSyncServerCapabilityHandler.java | 54 ++++++---
8 files changed, 244 insertions(+), 44 deletions(-)
diff --git
a/ide/lsp.client/src/org/netbeans/modules/lsp/client/LSPBindings.java
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/LSPBindings.java
index b6af96d..f68c1db 100644
--- a/ide/lsp.client/src/org/netbeans/modules/lsp/client/LSPBindings.java
+++ b/ide/lsp.client/src/org/netbeans/modules/lsp/client/LSPBindings.java
@@ -23,12 +23,10 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
-import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.WeakHashMap;
@@ -36,8 +34,11 @@ import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
+import org.eclipse.lsp4j.ClientCapabilities;
import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4j.InitializeResult;
+import org.eclipse.lsp4j.TextDocumentClientCapabilities;
+import org.eclipse.lsp4j.WorkspaceClientCapabilities;
import org.eclipse.lsp4j.jsonrpc.Launcher;
import org.eclipse.lsp4j.launch.LSPLauncher;
import org.eclipse.lsp4j.services.LanguageServer;
@@ -52,6 +53,7 @@ import
org.netbeans.modules.lsp.client.spi.LanguageServerProvider;
import
org.netbeans.modules.lsp.client.spi.LanguageServerProvider.LanguageServerDescription;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
+import org.openide.modules.OnStop;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle.Messages;
import org.openide.util.RequestProcessor;
@@ -70,7 +72,7 @@ public class LSPBindings {
private static final Map<FileObject, Map<String, LSPBindings>>
workspace2Extension2Server = new HashMap<>();
private final Map<FileObject, Map<BackgroundTask, RequestProcessor.Task>>
backgroundTasks = new WeakHashMap<>();
- public static LSPBindings getBindings(FileObject file) {
+ public static synchronized LSPBindings getBindings(FileObject file) {
for (Entry<FileObject, Map<String, LSPBindings>> e :
workspace2Extension2Server.entrySet()) {
if (FileUtil.isParentOf(e.getKey(), file)) {
LSPBindings bindings = e.getValue().get(file.getExt());
@@ -108,21 +110,26 @@ public class LSPBindings {
launcher.startListening();
LanguageServer server =
launcher.getRemoteProxy();
InitializeParams
initParams = new InitializeParams();
-
initParams.setRootUri(prj.getProjectDirectory().toURI().toString()); //XXX:
what if a different root is expected????
+
initParams.setRootUri(Utils.toURI(prj.getProjectDirectory())); //XXX: what if a
different root is expected????
initParams.setRootPath(FileUtil.toFile(prj.getProjectDirectory()).getAbsolutePath());
//some servers still expect root path
initParams.setProcessId(0);
+
initParams.setCapabilities(new ClientCapabilities(new
WorkspaceClientCapabilities(), new TextDocumentClientCapabilities(), null));
InitializeResult result
= server.initialize(initParams).get();
- LSPBindings b = new
LSPBindings(server, result);
+ LSPBindings b = new
LSPBindings(server, result,
LanguageServerProviderAccessor.getINSTANCE().getProcess(desc));
lci.setBindings(b);
return b;
} catch
(InterruptedException | ExecutionException ex) {
- LOG.log(Level.FINE,
null, ex);
+ LOG.log(Level.WARNING,
null, ex);
}
}
}
- return new LSPBindings(null, null);
+ return new LSPBindings(null, null,
null);
});
+ if (bindings.process != null && !bindings.process.isAlive()) {
+ //XXX: what now
+ return null;
+ }
return bindings.server != null ? bindings : null;
}
private static final Logger LOG =
Logger.getLogger(LSPBindings.class.getName());
@@ -147,10 +154,10 @@ public class LSPBindings {
LanguageServer server = launcher.getRemoteProxy();
InitializeParams initParams = new InitializeParams();
- initParams.setRootUri(root.toURI().toString());
+ initParams.setRootUri(Utils.toURI(root));
initParams.setProcessId(0);
InitializeResult result = server.initialize(initParams).get();
- LSPBindings bindings = new LSPBindings(server, result);
+ LSPBindings bindings = new LSPBindings(server, result, null);
lc.setBindings(bindings);
@@ -163,10 +170,12 @@ public class LSPBindings {
private final LanguageServer server;
private final InitializeResult initResult;
+ private final Process process;
- private LSPBindings(LanguageServer server, InitializeResult initResult) {
+ private LSPBindings(LanguageServer server, InitializeResult initResult,
Process process) {
this.server = server;
this.initResult = initResult;
+ this.process = process;
}
public TextDocumentService getTextDocumentService() {
@@ -222,4 +231,27 @@ public class LSPBindings {
public interface BackgroundTask {
public void run(LSPBindings bindings, FileObject file);
}
+
+ @OnStop
+ public static class Cleanup implements Runnable {
+
+ @Override
+ public void run() {
+ for (Map<String, LSPBindings> mime2Bindings :
project2MimeType2Server.values()) {
+ for (LSPBindings b : mime2Bindings.values()) {
+ if (b != null) {
+ b.process.destroy();
+ }
+ }
+ }
+ for (Map<String, LSPBindings> mime2Bindings :
workspace2Extension2Server.values()) {
+ for (LSPBindings b : mime2Bindings.values()) {
+ if (b != null) {
+ b.process.destroy();
+ }
+ }
+ }
+ }
+
+ }
}
diff --git
a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/Utils.java
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/Utils.java
similarity index 88%
rename from
ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/Utils.java
rename to ide/lsp.client/src/org/netbeans/modules/lsp/client/Utils.java
index ca0c7d9..f972bc5 100644
--- a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/Utils.java
+++ b/ide/lsp.client/src/org/netbeans/modules/lsp/client/Utils.java
@@ -16,13 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.netbeans.modules.lsp.client.bindings;
+package org.netbeans.modules.lsp.client;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import org.eclipse.lsp4j.Position;
import org.netbeans.api.editor.document.LineDocument;
import org.netbeans.api.editor.document.LineDocumentUtils;
+import org.openide.filesystems.FileObject;
/**
*
@@ -30,6 +31,10 @@ import org.netbeans.api.editor.document.LineDocumentUtils;
*/
public class Utils {
+ public static String toURI(FileObject file) {
+ return file.toURI().toString().replace("file:/", "file:///");
+ }
+
public static Position createPosition(Document doc, int offset) throws
BadLocationException {
return new Position(LineDocumentUtils.getLineIndex((LineDocument)
doc, offset),
offset -
LineDocumentUtils.getLineStart((LineDocument) doc, offset));
diff --git
a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/CodeActions.java
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/CodeActions.java
index 8e7e071..982da88 100644
---
a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/CodeActions.java
+++
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/CodeActions.java
@@ -18,7 +18,6 @@
*/
package org.netbeans.modules.lsp.client.bindings;
-import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
@@ -34,6 +33,7 @@ import org.eclipse.lsp4j.TextDocumentIdentifier;
import org.netbeans.api.editor.mimelookup.MimeRegistration;
import org.netbeans.modules.editor.NbEditorUtilities;
import org.netbeans.modules.lsp.client.LSPBindings;
+import org.netbeans.modules.lsp.client.Utils;
import org.netbeans.spi.editor.codegen.CodeGenerator;
import org.openide.filesystems.FileObject;
import org.openide.util.Exceptions;
@@ -60,10 +60,10 @@ public class CodeActions implements CodeGenerator.Factory {
if (server == null) {
return Collections.emptyList();
}
- URI uri = file.toURI();
+ String uri = Utils.toURI(file);
try {
List<? extends Command> commands =
- server.getTextDocumentService().codeAction(new
CodeActionParams(new TextDocumentIdentifier(uri.toString()),
+ server.getTextDocumentService().codeAction(new
CodeActionParams(new TextDocumentIdentifier(uri),
new Range(Utils.createPosition(component.getDocument(),
component.getSelectionStart()),
Utils.createPosition(component.getDocument(),
component.getSelectionEnd())),
new CodeActionContext(Collections.emptyList()))).get();
diff --git
a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/CompletionProviderImpl.java
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/CompletionProviderImpl.java
index 61d016f..75a017f 100644
---
a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/CompletionProviderImpl.java
+++
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/CompletionProviderImpl.java
@@ -22,12 +22,14 @@ import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
-import java.net.URI;
+import java.net.URL;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
+import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.ImageIcon;
+import javax.swing.JToolTip;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
@@ -36,7 +38,11 @@ import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionItemKind;
import org.eclipse.lsp4j.CompletionList;
import org.eclipse.lsp4j.CompletionParams;
+import org.eclipse.lsp4j.ParameterInformation;
+import org.eclipse.lsp4j.SignatureHelp;
+import org.eclipse.lsp4j.SignatureInformation;
import org.eclipse.lsp4j.TextDocumentIdentifier;
+import org.eclipse.lsp4j.TextDocumentPositionParams;
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
import org.netbeans.api.editor.mimelookup.MimeRegistration;
@@ -44,6 +50,8 @@ import org.netbeans.editor.BaseDocument;
import org.netbeans.editor.Utilities;
import org.netbeans.modules.editor.NbEditorUtilities;
import org.netbeans.modules.lsp.client.LSPBindings;
+import org.netbeans.modules.lsp.client.Utils;
+import org.netbeans.spi.editor.completion.CompletionDocumentation;
import org.netbeans.spi.editor.completion.CompletionProvider;
import org.netbeans.spi.editor.completion.CompletionResultSet;
import org.netbeans.spi.editor.completion.CompletionTask;
@@ -64,6 +72,64 @@ public class CompletionProviderImpl implements
CompletionProvider {
@Override
public CompletionTask createTask(int queryType, JTextComponent component) {
+ if ((queryType & TOOLTIP_QUERY_TYPE) != 0) {
+ return new AsyncCompletionTask(new AsyncCompletionQuery() {
+ @Override
+ protected void query(CompletionResultSet resultSet, Document
doc, int caretOffset) {
+ try {
+ FileObject file = NbEditorUtilities.getFileObject(doc);
+ if (file == null) {
+ //TODO: beep
+ return ;
+ }
+ LSPBindings server = LSPBindings.getBindings(file);
+ if (server == null) {
+ return ;
+ }
+ String uri = Utils.toURI(file);
+ TextDocumentPositionParams params;
+ params = new TextDocumentPositionParams(new
TextDocumentIdentifier(uri),
+ Utils.createPosition(doc, caretOffset));
+ SignatureHelp help =
server.getTextDocumentService().signatureHelp(params).get();
+ if (help == null || help.getSignatures().isEmpty()) {
+ return ;
+ }
+ //TODO: active signature?
+ StringBuilder signatures = new StringBuilder();
+ signatures.append("<html>");
+ for (SignatureInformation info : help.getSignatures())
{
+ if (info.getParameters().isEmpty()) {
+ signatures.append("No parameter.");
+ continue;
+ }
+ String sigSep = "";
+ int idx = 0;
+ for (ParameterInformation pi :
info.getParameters()) {
+ if (idx == help.getActiveParameter()) {
+ signatures.append("<b>");
+ }
+ signatures.append(sigSep);
+ signatures.append(pi.getLabel());
+ if (idx == help.getActiveParameter()) {
+ signatures.append("</b>");
+ }
+ sigSep = ", ";
+ idx++;
+ }
+ }
+ JToolTip tip = new JToolTip();
+ tip.setTipText(signatures.toString());
+ resultSet.setToolTip(tip);
+ } catch (BadLocationException | InterruptedException ex) {
+ Exceptions.printStackTrace(ex);
+ } catch (ExecutionException ex) {
+ Exceptions.printStackTrace(ex);
+ } finally {
+ resultSet.finish();
+ }
+ }
+ }, component);
+ }
return new AsyncCompletionTask(new AsyncCompletionQuery() {
@Override
protected void query(CompletionResultSet resultSet, Document doc,
int caretOffset) {
@@ -77,9 +143,9 @@ public class CompletionProviderImpl implements
CompletionProvider {
if (server == null) {
return ;
}
- URI uri = file.toURI();
+ String uri = Utils.toURI(file);
CompletionParams params;
- params = new CompletionParams(new
TextDocumentIdentifier(uri.toString()),
+ params = new CompletionParams(new
TextDocumentIdentifier(uri),
Utils.createPosition(doc, caretOffset));
CountDownLatch l = new CountDownLatch(1);
//TODO: Location or Location[]
@@ -95,6 +161,21 @@ public class CompletionProviderImpl implements
CompletionProvider {
}
for (CompletionItem i : items) {
String insert = i.getInsertText() != null ?
i.getInsertText() : i.getLabel();
+ String leftLabel = encode(i.getLabel());
+ String rightLabel = encode(""); //TODO: anything we
could show there?
+ String sortText = i.getSortText() != null ?
i.getSortText() : i.getLabel();
+ String header = "<html>" + "<b>" + (i.getDetail() !=
null ? i.getDetail() : i.getLabel()) + "</b>";
+ String documentation;
+ if (i.getDocumentation() != null) {
+ header += "<br><br>";
+ if (i.getDocumentation().isLeft()) {
+ documentation = header +
i.getDocumentation().getLeft();
+ } else {
+ documentation = header +
i.getDocumentation().getRight().getValue(); //TODO: convert markup!
+ }
+ } else {
+ documentation = header;
+ }
CompletionItemKind kind = i.getKind();
Icon ic = Icons.getCompletionIcon(kind);
ImageIcon icon = new
ImageIcon(ImageUtilities.icon2Image(ic));
@@ -135,17 +216,46 @@ public class CompletionProviderImpl implements
CompletionProvider {
@Override
public int getPreferredWidth(Graphics grphcs, Font
font) {
- return
CompletionUtilities.getPreferredWidth(insert, null, grphcs, font);
+ return
CompletionUtilities.getPreferredWidth(leftLabel, rightLabel, grphcs, font);
}
@Override
public void render(Graphics grphcs, Font font,
Color color, Color color1, int i, int i1, boolean bln) {
- CompletionUtilities.renderHtml(icon, insert,
null, grphcs, font, color, i, i1, bln);
+ CompletionUtilities.renderHtml(icon,
leftLabel, rightLabel, grphcs, font, color, i, i1, bln);
}
@Override
public CompletionTask createDocumentationTask() {
- return null;
+ return new CompletionTask() {
+ @Override
+ public void query(CompletionResultSet
resultSet) {
+ resultSet.setDocumentation(new
CompletionDocumentation() {
+ @Override
+ public String getText() {
+ return documentation;
+ }
+ @Override
+ public URL getURL() {
+ return null;
+ }
+ @Override
+ public CompletionDocumentation
resolveLink(String link) {
+ return null;
+ }
+ @Override
+ public Action
getGotoSourceAction() {
+ return null;
+ }
+ });
+ resultSet.finish();
+ }
+
+ @Override
+ public void refresh(CompletionResultSet
resultSet) {}
+
+ @Override
+ public void cancel() {}
+ };
}
@Override
@@ -165,7 +275,7 @@ public class CompletionProviderImpl implements
CompletionProvider {
@Override
public CharSequence getSortText() {
- return i.getSortText();
+ return sortText;
}
@Override
@@ -184,6 +294,11 @@ public class CompletionProviderImpl implements
CompletionProvider {
}
}, component);
}
+
+ private String encode(String str) {
+ return str.replace("&", "&")
+ .replace("<", "<");
+ }
@Override
public int getAutoQueryTypes(JTextComponent component, String typedText) {
diff --git
a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/HyperlinkProviderImpl.java
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/HyperlinkProviderImpl.java
index 4c79aa1..4f1cb70 100644
---
a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/HyperlinkProviderImpl.java
+++
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/HyperlinkProviderImpl.java
@@ -38,6 +38,7 @@ import
org.netbeans.lib.editor.hyperlink.spi.HyperlinkProviderExt;
import org.netbeans.lib.editor.hyperlink.spi.HyperlinkType;
import org.netbeans.modules.editor.NbEditorUtilities;
import org.netbeans.modules.lsp.client.LSPBindings;
+import org.netbeans.modules.lsp.client.Utils;
import org.openide.cookies.LineCookie;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.URLMapper;
@@ -84,10 +85,10 @@ public class HyperlinkProviderImpl implements
HyperlinkProviderExt {
if (server == null) {
return ;
}
- URI uri = file.toURI();
+ String uri = Utils.toURI(file);
try {
TextDocumentPositionParams params;
- params = new TextDocumentPositionParams(new
TextDocumentIdentifier(uri.toString()),
+ params = new TextDocumentPositionParams(new
TextDocumentIdentifier(uri),
Utils.createPosition(doc,
offset));
//TODO: Location or Location[]
CompletableFuture<List<? extends Location>> def =
server.getTextDocumentService().definition(params);
diff --git
a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/LanguageClientImpl.java
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/LanguageClientImpl.java
index 4ed1fd5..fe2ebdd 100644
---
a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/LanguageClientImpl.java
+++
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/LanguageClientImpl.java
@@ -24,6 +24,7 @@ import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumMap;
import java.util.List;
@@ -42,18 +43,22 @@ import org.eclipse.lsp4j.ApplyWorkspaceEditResponse;
import org.eclipse.lsp4j.CodeActionContext;
import org.eclipse.lsp4j.CodeActionParams;
import org.eclipse.lsp4j.Command;
+import org.eclipse.lsp4j.ConfigurationItem;
+import org.eclipse.lsp4j.ConfigurationParams;
import org.eclipse.lsp4j.Diagnostic;
import org.eclipse.lsp4j.DiagnosticSeverity;
import org.eclipse.lsp4j.ExecuteCommandParams;
import org.eclipse.lsp4j.MessageActionItem;
import org.eclipse.lsp4j.MessageParams;
import org.eclipse.lsp4j.PublishDiagnosticsParams;
+import org.eclipse.lsp4j.ServerCapabilities;
import org.eclipse.lsp4j.ShowMessageRequestParams;
import org.eclipse.lsp4j.TextDocumentIdentifier;
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4j.WorkspaceEdit;
import org.eclipse.lsp4j.services.LanguageClient;
import org.netbeans.modules.lsp.client.LSPBindings;
+import org.netbeans.modules.lsp.client.Utils;
import org.netbeans.spi.editor.hints.ChangeInfo;
import org.netbeans.spi.editor.hints.ErrorDescription;
import org.netbeans.spi.editor.hints.ErrorDescriptionFactory;
@@ -66,6 +71,7 @@ import org.openide.filesystems.FileObject;
import org.openide.filesystems.URLMapper;
import org.openide.text.NbDocument;
import org.openide.util.Exceptions;
+import org.openide.util.RequestProcessor;
/**
*
@@ -74,11 +80,16 @@ import org.openide.util.Exceptions;
public class LanguageClientImpl implements LanguageClient {
private static final Logger LOG =
Logger.getLogger(LanguageClientImpl.class.getName());
+ private static final RequestProcessor WORKER = new
RequestProcessor(LanguageClientImpl.class.getName(), 1, false, false);
private LSPBindings bindings;
+ private boolean allowCodeActions;
public void setBindings(LSPBindings bindings) {
this.bindings = bindings;
+ ServerCapabilities serverCapabilities =
bindings.getInitResult().getCapabilities();
+ Boolean codeActions = serverCapabilities.getCodeActionProvider();
+ allowCodeActions = codeActions != null && codeActions;
}
@Override
@@ -94,9 +105,10 @@ public class LanguageClientImpl implements LanguageClient {
Document doc = ec != null ? ec.getDocument() : null;
if (doc == null)
return ; //ignore...
- List<ErrorDescription> diags = pdp.getDiagnostics().stream().map(d
->
-
ErrorDescriptionFactory.createErrorDescription(severityMap.get(d.getSeverity()),
d.getMessage(), new DiagnosticFixList(pdp.getUri(), d), file,
Utils.getOffset(doc, d.getRange().getStart()), Utils.getOffset(doc,
d.getRange().getEnd()))
- ).collect(Collectors.toList());
+ List<ErrorDescription> diags = pdp.getDiagnostics().stream().map(d
-> {
+ LazyFixList fixList = allowCodeActions ? new
DiagnosticFixList(pdp.getUri(), d) :
ErrorDescriptionFactory.lazyListForFixes(Collections.emptyList());
+ return
ErrorDescriptionFactory.createErrorDescription(severityMap.get(d.getSeverity()),
d.getMessage(), fixList, file, Utils.getOffset(doc, d.getRange().getStart()),
Utils.getOffset(doc, d.getRange().getEnd()));
+ }).collect(Collectors.toList());
HintsController.setErrors(doc, LanguageClientImpl.class.getName(),
diags);
} catch (URISyntaxException | MalformedURLException ex) {
LOG.log(Level.FINE, null, ex);
@@ -161,6 +173,19 @@ public class LanguageClientImpl implements LanguageClient {
System.err.println("logMessage: " + arg0);
}
+ @Override
+ public CompletableFuture<List<Object>> configuration(ConfigurationParams
configurationParams) {
+ CompletableFuture<List<Object>> result = new CompletableFuture<>();
+ WORKER.post(() -> {
+ List<Object> outcome = new ArrayList<>();
+ for (ConfigurationItem ci : configurationParams.getItems()) {
+ outcome.add(null);
+ }
+ result.complete(outcome);
+ });
+ return result;
+ }
+
private final class DiagnosticFixList implements LazyFixList {
private final PropertyChangeSupport pcs = new
PropertyChangeSupport(this);
diff --git
a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/NavigatorPanelImpl.java
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/NavigatorPanelImpl.java
index bbc12f3..def4911 100644
---
a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/NavigatorPanelImpl.java
+++
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/NavigatorPanelImpl.java
@@ -32,6 +32,7 @@ import org.eclipse.lsp4j.SymbolInformation;
import org.eclipse.lsp4j.TextDocumentIdentifier;
import org.netbeans.modules.lsp.client.LSPBindings;
import org.netbeans.modules.lsp.client.LSPBindings.BackgroundTask;
+import org.netbeans.modules.lsp.client.Utils;
import org.netbeans.spi.navigator.NavigatorPanel;
import org.openide.explorer.ExplorerManager;
import org.openide.explorer.view.BeanTreeView;
@@ -135,7 +136,8 @@ public class NavigatorPanelImpl extends
Children.Keys<SymbolInformation> impleme
public void run(LSPBindings bindings, FileObject file) {
if (file.equals(this.file)) {
try {
- List<? extends SymbolInformation> symbols =
bindings.getTextDocumentService().documentSymbol(new DocumentSymbolParams(new
TextDocumentIdentifier(file.toURI().toString()))).get();
+ String uri = Utils.toURI(file);
+ List<? extends SymbolInformation> symbols =
bindings.getTextDocumentService().documentSymbol(new DocumentSymbolParams(new
TextDocumentIdentifier(uri))).get();
setKeys(symbols);
} catch (InterruptedException | ExecutionException ex) {
diff --git
a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/TextDocumentSyncServerCapabilityHandler.java
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/TextDocumentSyncServerCapabilityHandler.java
index c08a3b9..9ac2f60 100644
---
a/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/TextDocumentSyncServerCapabilityHandler.java
+++
b/ide/lsp.client/src/org/netbeans/modules/lsp/client/bindings/TextDocumentSyncServerCapabilityHandler.java
@@ -39,19 +39,21 @@ import org.netbeans.api.editor.EditorRegistry;
import org.netbeans.editor.BaseDocumentEvent;
import org.netbeans.modules.editor.*;
import org.netbeans.modules.lsp.client.LSPBindings;
+import org.netbeans.modules.lsp.client.Utils;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
import org.openide.modules.OnStart;
import org.openide.util.Exceptions;
+import org.openide.util.RequestProcessor;
-/** TODO: asynchronous
- * TODO: follow the synchronization options
+/** TODO: follow the synchronization options
* TODO: close
*
* @author lahvac
*/
public class TextDocumentSyncServerCapabilityHandler {
+ private final RequestProcessor WORKER = new
RequestProcessor(TextDocumentSyncServerCapabilityHandler.class.getName(), 1,
false, false);
private final Set<JTextComponent> lastOpened =
Collections.newSetFromMap(new IdentityHashMap<>());
private void handleChange() {
@@ -73,25 +75,34 @@ public class TextDocumentSyncServerCapabilityHandler {
if (file == null)
continue; //ignore
- LSPBindings server = LSPBindings.getBindings(file);
+ Document doc = opened.getDocument();
- if (server == null)
- continue; //ignore
+ WORKER.post(() -> {
+ LSPBindings server = LSPBindings.getBindings(file);
+
+ if (server == null)
+ return ; //ignore
+
+ String uri = Utils.toURI(file);
+ String[] text = new String[1];
- try {
- //XXX: should construct events outside of AWT
- TextDocumentItem textDocumentItem = new
TextDocumentItem(file.toURI().toString(),
+ doc.render(() -> {
+ try {
+ text[0] = doc.getText(0, doc.getLength());
+ } catch (BadLocationException ex) {
+ Exceptions.printStackTrace(ex);
+ text[0] = "";
+ }
+ });
+
+ TextDocumentItem textDocumentItem = new TextDocumentItem(uri,
FileUtil.getMIMEType(file),
0,
-
opened.getDocument().getText(0, opened.getDocument().getLength())); //XXX:
should do in render!
+
text[0]);
server.getTextDocumentService().didOpen(new
DidOpenTextDocumentParams(textDocumentItem));
server.scheduleBackgroundTasks(file);
- } catch (BadLocationException ex) {
- Exceptions.printStackTrace(ex);
- }
-
- Document doc = opened.getDocument();
+ });
doc.addDocumentListener(new DocumentListener() { //XXX: listener
int version; //XXX: proper versioning!
@@ -128,9 +139,18 @@ public class TextDocumentSyncServerCapabilityHandler {
oldText.length(),
newText);
VersionedTextDocumentIdentifier di = new
VersionedTextDocumentIdentifier(++version);
- di.setUri(file.toURI().toString());
- server.getTextDocumentService().didChange(new
DidChangeTextDocumentParams(di, Arrays.asList(event)));
- server.scheduleBackgroundTasks(file);
+
di.setUri(org.netbeans.modules.lsp.client.Utils.toURI(file));
+ DidChangeTextDocumentParams params = new
DidChangeTextDocumentParams(di, Arrays.asList(event));
+
+ WORKER.post(() -> {
+ LSPBindings server = LSPBindings.getBindings(file);
+
+ if (server == null)
+ return ; //ignore
+
+ server.getTextDocumentService().didChange(params);
+ server.scheduleBackgroundTasks(file);
+ });
} catch (BadLocationException ex) {
Exceptions.printStackTrace(ex);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists