You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by lk...@apache.org on 2020/10/23 01:11:00 UTC
[netbeans] 13/18: StatusDisplayer messages remoted to LSP client.
(#2478)
This is an automated email from the ASF dual-hosted git repository.
lkishalmi pushed a commit to branch release122
in repository https://gitbox.apache.org/repos/asf/netbeans.git
commit 15099a794af75e5343b188517bbc652172cc3699
Author: Svatopluk Dedic <sv...@oracle.com>
AuthorDate: Thu Oct 22 20:25:18 2020 +0200
StatusDisplayer messages remoted to LSP client. (#2478)
* StatusDisplayer messages remoted to vscode.
* Extended capabilities negotiated with the client.
---
.../server/protocol/NbCodeClientCapabilities.java | 87 +++++++++++++++
.../lsp/server/protocol/NbCodeClientWrapper.java | 120 +++++++++++++++++++++
.../lsp/server/protocol/NbCodeLanguageClient.java | 49 +++++++++
.../modules/java/lsp/server/protocol/Server.java | 83 ++++++++++++--
.../server/protocol/ShowStatusMessageParams.java | 78 ++++++++++++++
.../server/protocol/TextDocumentServiceImpl.java | 5 +-
.../lsp/server/protocol/WorkspaceServiceImpl.java | 33 +-----
.../lsp/server/protocol/WorkspaceUIContext.java | 62 +++++++++++
.../lsp/server/ui/AbstractLspStatusDisplayer.java | 5 +-
.../modules/java/lsp/server/ui/UIContext.java | 15 +++
.../java/lsp/server/protocol/ServerTest.java | 24 +++--
java/java.lsp.server/vscode/src/extension.ts | 38 ++++++-
java/java.lsp.server/vscode/src/protocol.ts | 35 ++++++
13 files changed, 583 insertions(+), 51 deletions(-)
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/NbCodeClientCapabilities.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/NbCodeClientCapabilities.java
new file mode 100644
index 0000000..41f7e0a
--- /dev/null
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/NbCodeClientCapabilities.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.lsp.server.protocol;
+
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonElement;
+import org.eclipse.lsp4j.InitializeParams;
+
+/**
+ * Encapsulates all nbcode-specific client capabilities. Need to be passed in
+ * an object:
+ * <code><pre>
+ * "nbcodeCapabilities" : {
+ * "statusBarMessageSupport"? : boolean
+ * ...
+ * }
+ * </pre></code>
+ * @author sdedic
+ */
+public final class NbCodeClientCapabilities {
+ /**
+ * Supports status bar messages:
+ * <ul>
+ * <li>window/showStatusBarMessage
+ * </ul>
+ */
+ private Boolean statusBarMessageSupport;
+
+ public Boolean getStatusBarMessageSupport() {
+ return statusBarMessageSupport;
+ }
+
+ public boolean hasStatusBarMessageSupport() {
+ return statusBarMessageSupport != null && statusBarMessageSupport.booleanValue();
+ }
+
+ public void setStatusBarMessageSupport(Boolean statusBarMessageSupport) {
+ this.statusBarMessageSupport = statusBarMessageSupport;
+ }
+
+ public static NbCodeClientCapabilities get(InitializeParams initParams) {
+ if (initParams == null) {
+ return null;
+ }
+ Object ext = initParams.getInitializationOptions();
+ if (!(ext instanceof JsonElement)) {
+ return null;
+ }
+ InitializationExtendedCapabilities root = new GsonBuilder().
+ /*
+ hypothetically needed for formatting options with Either type
+ registerTypeAdapterFactory(new EitherTypeAdapter.Factory()).
+ */
+ create().
+ fromJson((JsonElement)ext, InitializationExtendedCapabilities.class);
+ return root == null ? null : root.getNbcodeCapabilities();
+
+ }
+
+ static final class InitializationExtendedCapabilities {
+ private NbCodeClientCapabilities nbcodeCapabilities;
+
+ public NbCodeClientCapabilities getNbcodeCapabilities() {
+ return nbcodeCapabilities;
+ }
+
+ public void setNbcodeCapabilities(NbCodeClientCapabilities nbcodeCapabilities) {
+ this.nbcodeCapabilities = nbcodeCapabilities;
+ }
+ }
+}
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/NbCodeClientWrapper.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/NbCodeClientWrapper.java
new file mode 100644
index 0000000..c4ba4b5
--- /dev/null
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/NbCodeClientWrapper.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.lsp.server.protocol;
+
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import org.eclipse.lsp4j.ApplyWorkspaceEditParams;
+import org.eclipse.lsp4j.ApplyWorkspaceEditResponse;
+import org.eclipse.lsp4j.ConfigurationParams;
+import org.eclipse.lsp4j.MessageActionItem;
+import org.eclipse.lsp4j.MessageParams;
+import org.eclipse.lsp4j.PublishDiagnosticsParams;
+import org.eclipse.lsp4j.RegistrationParams;
+import org.eclipse.lsp4j.SemanticHighlightingParams;
+import org.eclipse.lsp4j.ShowMessageRequestParams;
+import org.eclipse.lsp4j.UnregistrationParams;
+import org.eclipse.lsp4j.WorkspaceFolder;
+
+/**
+ * Convenience wrapper that binds language client's remote proxy together with
+ * other useful methods. Will be sent out as THE client by the server core code.
+ *
+ * @author sdedic
+ */
+class NbCodeClientWrapper implements NbCodeLanguageClient {
+ private final NbCodeLanguageClient remote;
+ private volatile NbCodeClientCapabilities clientCaps;
+
+ public NbCodeClientWrapper(NbCodeLanguageClient remote) {
+ this.remote = remote;
+ this.clientCaps = new NbCodeClientCapabilities();
+ }
+
+ public void setClientCaps(NbCodeClientCapabilities clientCaps) {
+ if (clientCaps != null) {
+ this.clientCaps = clientCaps;
+ }
+ }
+
+ @Override
+ public NbCodeClientCapabilities getNbCodeCapabilities() {
+ return clientCaps;
+ }
+
+ @Override
+ public void showStatusBarMessage(ShowStatusMessageParams params) {
+ remote.showStatusBarMessage(params);
+ }
+
+ @Override
+ public CompletableFuture<ApplyWorkspaceEditResponse> applyEdit(ApplyWorkspaceEditParams params) {
+ return remote.applyEdit(params);
+ }
+
+ @Override
+ public CompletableFuture<Void> registerCapability(RegistrationParams params) {
+ return remote.registerCapability(params);
+ }
+
+ @Override
+ public CompletableFuture<Void> unregisterCapability(UnregistrationParams params) {
+ return remote.unregisterCapability(params);
+ }
+
+ @Override
+ public void telemetryEvent(Object object) {
+ remote.telemetryEvent(object);
+ }
+
+ @Override
+ public void publishDiagnostics(PublishDiagnosticsParams diagnostics) {
+ remote.publishDiagnostics(diagnostics);
+ }
+
+ @Override
+ public void showMessage(MessageParams messageParams) {
+ remote.showMessage(messageParams);
+ }
+
+ @Override
+ public CompletableFuture<MessageActionItem> showMessageRequest(ShowMessageRequestParams requestParams) {
+ return remote.showMessageRequest(requestParams);
+ }
+
+ @Override
+ public void logMessage(MessageParams message) {
+ remote.logMessage(message);
+ }
+
+ @Override
+ public CompletableFuture<List<WorkspaceFolder>> workspaceFolders() {
+ return remote.workspaceFolders();
+ }
+
+ @Override
+ public CompletableFuture<List<Object>> configuration(ConfigurationParams configurationParams) {
+ return remote.configuration(configurationParams);
+ }
+
+ @Override
+ public void semanticHighlighting(SemanticHighlightingParams params) {
+ remote.semanticHighlighting(params);
+ }
+}
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/NbCodeLanguageClient.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/NbCodeLanguageClient.java
new file mode 100644
index 0000000..10ad5a6
--- /dev/null
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/NbCodeLanguageClient.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.lsp.server.protocol;
+
+import org.eclipse.lsp4j.MessageParams;
+import org.eclipse.lsp4j.jsonrpc.services.JsonNotification;
+import org.eclipse.lsp4j.jsonrpc.validation.NonNull;
+import org.eclipse.lsp4j.services.LanguageClient;
+
+/**
+ * An extension to the standard LanguageClient that adds several messages missing
+ * from the official LSP protocol.s
+ * @author sdedic
+ */
+public interface NbCodeLanguageClient extends LanguageClient {
+
+ /**
+ * Shows a message in the status bar. Log- and Info-type messages are shown "as is".
+ * The other message types can be decorated by an icon according to {@link MessageParams#getType}.
+ * The message will be hidden after specified number of milliseconds; 0 means the client
+ * controls when the message is hidden.
+ *
+ * @param params message type and text.
+ */
+ @JsonNotification("window/showStatusBarMessage")
+ public void showStatusBarMessage(@NonNull ShowStatusMessageParams params);
+
+ /**
+ * Returns extended code capabilities.
+ * @return code capabilities.
+ */
+ public NbCodeClientCapabilities getNbCodeCapabilities();
+}
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java
index 2a10c70..91bf541 100644
--- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/Server.java
@@ -35,12 +35,15 @@ import org.eclipse.lsp4j.CompletionOptions;
import org.eclipse.lsp4j.ExecuteCommandOptions;
import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4j.InitializeResult;
-import org.eclipse.lsp4j.MessageParams;
import org.eclipse.lsp4j.MessageType;
import org.eclipse.lsp4j.ServerCapabilities;
import org.eclipse.lsp4j.TextDocumentSyncKind;
import org.eclipse.lsp4j.WorkspaceFolder;
+import org.eclipse.lsp4j.jsonrpc.JsonRpcException;
import org.eclipse.lsp4j.jsonrpc.Launcher;
+import org.eclipse.lsp4j.jsonrpc.MessageConsumer;
+import org.eclipse.lsp4j.jsonrpc.MessageIssueException;
+import org.eclipse.lsp4j.jsonrpc.messages.Message;
import org.eclipse.lsp4j.launch.LSPLauncher;
import org.eclipse.lsp4j.services.LanguageClient;
import org.eclipse.lsp4j.services.LanguageClientAware;
@@ -57,6 +60,11 @@ import org.netbeans.api.project.Sources;
import org.netbeans.api.project.ui.OpenProjects;
import org.openide.filesystems.FileObject;
import org.openide.util.Exceptions;
+import org.openide.util.Lookup;
+import org.openide.util.lookup.AbstractLookup;
+import org.openide.util.lookup.InstanceContent;
+import org.openide.util.lookup.Lookups;
+import org.openide.util.lookup.ProxyLookup;
/**
*
@@ -68,7 +76,7 @@ public final class Server {
public static void launchServer(InputStream in, OutputStream out) {
LanguageServerImpl server = new LanguageServerImpl();
- Launcher<LanguageClient> serverLauncher = LSPLauncher.createServerLauncher(server, in, out);
+ Launcher<NbCodeLanguageClient> serverLauncher = createLauncher(server, in, out);
((LanguageClientAware) server).connect(serverLauncher.getRemoteProxy());
Future<Void> runningServer = serverLauncher.startListening();
try {
@@ -77,16 +85,60 @@ public final class Server {
Exceptions.printStackTrace(ex);
}
}
+
+ private static Launcher<NbCodeLanguageClient> createLauncher(LanguageServerImpl server, InputStream in, OutputStream out) {
+ return new LSPLauncher.Builder<NbCodeLanguageClient>()
+ .setLocalService(server)
+ .setRemoteInterface(NbCodeLanguageClient.class)
+ .setInput(in)
+ .setOutput(out)
+ .wrapMessages(new ConsumeWithLookup(server.getSessionLookup())::attachLookup)
+ .create();
+ }
+
+ /**
+ * Processes message while the default Lookup is set to
+ * {@link LanguageServerImpl#getSessionLookup()}.
+ */
+ private static class ConsumeWithLookup {
+ private final Lookup sessionLookup;
+ public ConsumeWithLookup(Lookup sessionLookup) {
+ this.sessionLookup = sessionLookup;
+ }
+
+ public MessageConsumer attachLookup(MessageConsumer delegate) {
+ return new MessageConsumer() {
+ @Override
+ public void consume(Message msg) throws MessageIssueException, JsonRpcException {
+ Lookups.executeWith(sessionLookup, () -> {
+ delegate.consume(msg);
+ });
+ }
+ };
+ }
+ }
+
private static class LanguageServerImpl implements LanguageServer, LanguageClientAware {
private static final Logger LOG = Logger.getLogger(LanguageServerImpl.class.getName());
- private LanguageClient client;
+ private NbCodeClientWrapper client;
private final TextDocumentService textDocumentService = new TextDocumentServiceImpl();
private final WorkspaceService workspaceService = new WorkspaceServiceImpl();
-
+ private final InstanceContent sessionServices = new InstanceContent();
+ private final Lookup sessionLookup = new ProxyLookup(
+ new AbstractLookup(sessionServices),
+ Lookup.getDefault()
+ );
+
+ Lookup getSessionLookup() {
+ return sessionLookup;
+ }
+
@Override
public CompletableFuture<InitializeResult> initialize(InitializeParams init) {
+ NbCodeClientCapabilities capa = NbCodeClientCapabilities.get(init);
+ client.setClientCaps(capa);
List<FileObject> projectCandidates = new ArrayList<>();
List<WorkspaceFolder> folders = init.getWorkspaceFolders();
if (folders != null) {
@@ -142,7 +194,11 @@ public final class Server {
try {
JavaSource.create(ClasspathInfo.create(ClassPath.EMPTY, ClassPath.EMPTY, ClassPath.EMPTY))
.runWhenScanFinished(cc -> {
- client.showMessage(new MessageParams(MessageType.Info, INDEXING_COMPLETED));
+ if (client.getNbCodeCapabilities().hasStatusBarMessageSupport()) {
+ client.showStatusBarMessage(new ShowStatusMessageParams(MessageType.Info, INDEXING_COMPLETED, 0));
+ } else {
+ client.showMessage(new ShowStatusMessageParams(MessageType.Info, INDEXING_COMPLETED, 0));
+ }
//todo: refresh diagnostics all open editor?
}, true);
} catch (IOException ex) {
@@ -183,10 +239,19 @@ public final class Server {
}
@Override
- public void connect(LanguageClient client) {
- this.client = client;
- ((LanguageClientAware) getTextDocumentService()).connect(client);
- ((LanguageClientAware) getWorkspaceService()).connect(client);
+ public void connect(LanguageClient aClient) {
+ this.client = new NbCodeClientWrapper((NbCodeLanguageClient)aClient);
+
+ sessionServices.add(new WorkspaceIOContext() {
+ @Override
+ protected LanguageClient client() {
+ return client;
+ }
+ });
+ sessionServices.add(new WorkspaceUIContext(client));
+
+ ((LanguageClientAware) getTextDocumentService()).connect(aClient);
+ ((LanguageClientAware) getWorkspaceService()).connect(aClient);
}
}
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ShowStatusMessageParams.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ShowStatusMessageParams.java
new file mode 100644
index 0000000..43af736
--- /dev/null
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/ShowStatusMessageParams.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.lsp.server.protocol;
+
+import java.util.Objects;
+import org.eclipse.lsp4j.MessageParams;
+import org.eclipse.lsp4j.MessageType;
+import org.eclipse.xtext.xbase.lib.Pure;
+
+/**
+ *
+ * @author sdedic
+ */
+public class ShowStatusMessageParams extends MessageParams {
+ private Integer timeout;
+
+ public ShowStatusMessageParams(MessageType type, String message) {
+ super(type, message);
+ }
+
+ public ShowStatusMessageParams(MessageType type, String message, int timeout) {
+ super(type, message);
+ this.timeout = timeout;
+ }
+
+ @Pure
+ public Integer getTimeout() {
+ return timeout;
+ }
+
+ public ShowStatusMessageParams setTimeout(Integer timeout) {
+ this.timeout = timeout;
+ return this;
+ }
+
+ @Pure
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 53 * hash + (timeout == null ? 7 : this.timeout.hashCode());
+ return hash;
+ }
+
+ @Pure
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final ShowStatusMessageParams other = (ShowStatusMessageParams) obj;
+ if (Objects.equals(this.timeout, other.timeout)) {
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/TextDocumentServiceImpl.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/TextDocumentServiceImpl.java
index e0a1df0..f612a1a 100644
--- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/TextDocumentServiceImpl.java
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/TextDocumentServiceImpl.java
@@ -172,6 +172,7 @@ import org.netbeans.spi.editor.hints.ErrorDescription;
import org.netbeans.spi.editor.hints.Fix;
import org.netbeans.spi.editor.hints.LazyFixList;
import org.netbeans.spi.java.hints.JavaFix;
+import org.openide.awt.StatusDisplayer;
import org.openide.cookies.EditorCookie;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;
@@ -194,7 +195,7 @@ public class TextDocumentServiceImpl implements TextDocumentService, LanguageCli
private final Map<String, Document> openedDocuments = new HashMap<>();
private final Map<String, RequestProcessor.Task> diagnosticTasks = new HashMap<>();
- private LanguageClient client;
+ private NbCodeLanguageClient client;
public TextDocumentServiceImpl() {
}
@@ -245,7 +246,7 @@ public class TextDocumentServiceImpl implements TextDocumentService, LanguageCli
@Override
public void connect(LanguageClient client) {
- this.client = client;
+ this.client = (NbCodeLanguageClient)client;
}
private static class ItemFactoryImpl implements JavaCompletionTask.ItemFactory<CompletionItem> {
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/WorkspaceServiceImpl.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/WorkspaceServiceImpl.java
index 696ef85..52c395b 100644
--- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/WorkspaceServiceImpl.java
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/WorkspaceServiceImpl.java
@@ -23,7 +23,6 @@ import java.util.concurrent.CompletableFuture;
import org.eclipse.lsp4j.DidChangeConfigurationParams;
import org.eclipse.lsp4j.DidChangeWatchedFilesParams;
import org.eclipse.lsp4j.ExecuteCommandParams;
-import org.eclipse.lsp4j.MessageParams;
import org.eclipse.lsp4j.SymbolInformation;
import org.eclipse.lsp4j.WorkspaceSymbolParams;
import org.eclipse.lsp4j.services.LanguageClient;
@@ -33,11 +32,8 @@ import org.netbeans.api.debugger.ActionsManager;
import org.netbeans.api.debugger.DebuggerManager;
import org.netbeans.api.project.Project;
import org.netbeans.api.project.ui.OpenProjects;
-import org.netbeans.modules.java.lsp.server.ui.UIContext;
import org.netbeans.spi.project.ActionProvider;
-import org.openide.util.Lookup;
import org.openide.util.lookup.Lookups;
-import org.openide.util.lookup.ProxyLookup;
/**
*
@@ -45,12 +41,9 @@ import org.openide.util.lookup.ProxyLookup;
*/
public final class WorkspaceServiceImpl implements WorkspaceService, LanguageClientAware {
- private LanguageClient client;
- private UIContext ctx;
- private final WorkspaceIOContext ioContext;
+ private NbCodeLanguageClient client;
public WorkspaceServiceImpl() {
- this.ioContext = new WorkspaceContext();
}
@Override
@@ -64,9 +57,7 @@ public final class WorkspaceServiceImpl implements WorkspaceService, LanguageCli
for (Project prj : OpenProjects.getDefault().getOpenProjects()) {
ActionProvider ap = prj.getLookup().lookup(ActionProvider.class);
if (ap != null && ap.isActionEnabled(ActionProvider.COMMAND_BUILD, Lookups.fixed())) {
- Lookups.executeWith(new ProxyLookup(Lookups.fixed(ctx, ioContext), Lookup.getDefault()), () -> {
- ap.invokeAction(ActionProvider.COMMAND_REBUILD, Lookups.fixed());
- });
+ ap.invokeAction(ActionProvider.COMMAND_REBUILD, Lookups.fixed());
}
}
return CompletableFuture.completedFuture(true);
@@ -92,24 +83,6 @@ public final class WorkspaceServiceImpl implements WorkspaceService, LanguageCli
@Override
public void connect(LanguageClient client) {
- this.client = client;
- this.ctx = new UIContext() {
- @Override
- protected boolean isValid() {
- return true;
- }
-
- @Override
- protected void showMessage(MessageParams msg) {
- client.showMessage(msg);
- }
- };
- }
-
- private final class WorkspaceContext extends WorkspaceIOContext {
- @Override
- protected LanguageClient client() {
- return client;
- }
+ this.client = (NbCodeLanguageClient)client;
}
}
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/WorkspaceUIContext.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/WorkspaceUIContext.java
new file mode 100644
index 0000000..c20575c
--- /dev/null
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/protocol/WorkspaceUIContext.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.netbeans.modules.java.lsp.server.protocol;
+
+import org.eclipse.lsp4j.MessageParams;
+import org.eclipse.lsp4j.services.LanguageClient;
+import org.netbeans.modules.java.lsp.server.ui.UIContext;
+import org.openide.awt.StatusDisplayer;
+
+/**
+ *
+ * @author sdedic
+ */
+class WorkspaceUIContext extends UIContext {
+ private final NbCodeLanguageClient client;
+
+ public WorkspaceUIContext(NbCodeLanguageClient client) {
+ this.client = client;
+ }
+
+ @Override
+ protected boolean isValid() {
+ return true;
+ }
+
+ @Override
+ protected void showMessage(MessageParams msg) {
+ client.showMessage(msg);
+ }
+
+ @Override
+ protected void logMessage(MessageParams msg) {
+ client.logMessage(msg);
+ }
+
+ @Override
+ protected StatusDisplayer.Message showStatusMessage(ShowStatusMessageParams msg) {
+ if (client.getNbCodeCapabilities().hasStatusBarMessageSupport()) {
+ client.showStatusBarMessage(msg);
+ } else {
+ client.showMessage(msg);
+ }
+ return null;
+ }
+
+}
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/ui/AbstractLspStatusDisplayer.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/ui/AbstractLspStatusDisplayer.java
index 97953d2..aa5f7a3 100644
--- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/ui/AbstractLspStatusDisplayer.java
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/ui/AbstractLspStatusDisplayer.java
@@ -21,6 +21,7 @@ package org.netbeans.modules.java.lsp.server.ui;
import javax.swing.event.ChangeListener;
import org.eclipse.lsp4j.MessageParams;
import org.eclipse.lsp4j.MessageType;
+import org.netbeans.modules.java.lsp.server.protocol.ShowStatusMessageParams;
import org.openide.awt.StatusDisplayer;
public abstract class AbstractLspStatusDisplayer extends StatusDisplayer {
@@ -56,8 +57,8 @@ public abstract class AbstractLspStatusDisplayer extends StatusDisplayer {
} else {
type = MessageType.Info;
}
- ctx.showMessage(new MessageParams(type, text));
- return (int timeInMillis) -> {
+ Message m = ctx.showStatusMessage(new ShowStatusMessageParams(type, text, 0));
+ return m != null ? m : (int timeInMillis) -> {
};
}
diff --git a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/ui/UIContext.java b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/ui/UIContext.java
index aa4a510..781d04e 100644
--- a/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/ui/UIContext.java
+++ b/java/java.lsp.server/src/org/netbeans/modules/java/lsp/server/ui/UIContext.java
@@ -21,6 +21,8 @@ package org.netbeans.modules.java.lsp.server.ui;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import org.eclipse.lsp4j.MessageParams;
+import org.netbeans.modules.java.lsp.server.protocol.ShowStatusMessageParams;
+import org.openide.awt.StatusDisplayer.Message;
import org.openide.util.Lookup;
public abstract class UIContext {
@@ -49,6 +51,8 @@ public abstract class UIContext {
protected abstract boolean isValid();
protected abstract void showMessage(MessageParams msg);
+ protected abstract void logMessage(MessageParams msg);
+ protected abstract Message showStatusMessage(ShowStatusMessageParams msg);
private static final class LogImpl extends UIContext {
@@ -63,6 +67,17 @@ public abstract class UIContext {
}
@Override
+ protected void logMessage(MessageParams msg) {
+ System.err.println(msg.getType() + ": " + msg.getMessage());
+ }
+
+ @Override
+ protected Message showStatusMessage(ShowStatusMessageParams msg) {
+ System.out.println(msg.getType() + ": " + msg.getMessage());
+ return (int timeInMillis) -> {};
+ }
+
+ @Override
protected boolean isValid() {
return true;
}
diff --git a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java
index 4d7231c..8213c5b 100644
--- a/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java
+++ b/java/java.lsp.server/test/unit/src/org/netbeans/modules/java/lsp/server/protocol/ServerTest.java
@@ -18,6 +18,8 @@
*/
package org.netbeans.modules.java.lsp.server.protocol;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
@@ -957,7 +959,19 @@ public class ServerTest extends NbTestCase {
}
List<Diagnostic>[] diags = new List[1];
CountDownLatch indexingComplete = new CountDownLatch(1);
- Launcher<LanguageServer> serverLauncher = LSPLauncher.createClientLauncher(new LanguageClient() {
+ Launcher<LanguageServer> serverLauncher = LSPLauncher.createClientLauncher(new NbCodeLanguageClient() {
+ @Override
+ public void showStatusBarMessage(ShowStatusMessageParams params) {
+ if (Server.INDEXING_COMPLETED.equals(params.getMessage())) {
+ indexingComplete.countDown();
+ }
+ }
+
+ @Override
+ public NbCodeClientCapabilities getNbCodeCapabilities() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+
@Override
public void telemetryEvent(Object arg0) {
throw new UnsupportedOperationException("Not supported yet.");
@@ -973,11 +987,7 @@ public class ServerTest extends NbTestCase {
@Override
public void showMessage(MessageParams params) {
- if (Server.INDEXING_COMPLETED.equals(params.getMessage())) {
- indexingComplete.countDown();
- } else {
- throw new UnsupportedOperationException("Unexpected message.");
- }
+ throw new UnsupportedOperationException("Unexpected message.");
}
@Override
@@ -993,6 +1003,8 @@ public class ServerTest extends NbTestCase {
serverLauncher.startListening();
LanguageServer server = serverLauncher.getRemoteProxy();
InitializeParams initParams = new InitializeParams();
+ initParams.setInitializationOptions(new JsonParser().parse(
+ "{ nbcodeCapabilities: { statusBarMessageSupport : true } }").getAsJsonObject());
initParams.setRootUri(getWorkDir().toURI().toString());
InitializeResult result = server.initialize(initParams).get();
indexingComplete.await();
diff --git a/java/java.lsp.server/vscode/src/extension.ts b/java/java.lsp.server/vscode/src/extension.ts
index 785741c..5ce27ce 100644
--- a/java/java.lsp.server/vscode/src/extension.ts
+++ b/java/java.lsp.server/vscode/src/extension.ts
@@ -23,7 +23,8 @@ import { commands, window, workspace, ExtensionContext, ProgressLocation } from
import {
LanguageClient,
LanguageClientOptions,
- StreamInfo
+ StreamInfo,
+ ShowMessageParams, MessageType,
} from 'vscode-languageclient';
import * as net from 'net';
@@ -32,6 +33,7 @@ import * as path from 'path';
import { spawn, ChildProcess, SpawnOptions } from 'child_process';
import * as vscode from 'vscode';
import * as launcher from './nbcode';
+import { StatusMessageRequest, ShowStatusMessageParams } from './protocol';
let client: LanguageClient;
let nbProcess : ChildProcess | null = null;
@@ -182,7 +184,12 @@ export function activate(context: ExtensionContext) {
]
},
outputChannelName: 'Java',
- revealOutputChannelOn: 4 // never
+ revealOutputChannelOn: 4,
+ initializationOptions : {
+ 'nbcodeCapabilities' : {
+ 'statusBarMessageSupport' : true
+ }
+ }
}
// Create the language client and start the client.
@@ -197,6 +204,7 @@ export function activate(context: ExtensionContext) {
client.start();
client.onReady().then((value) => {
commands.executeCommand('setContext', 'nbJavaLSReady', true);
+ client.onNotification(StatusMessageRequest.type, showStatusBarMessage);
});
//register debugger:
@@ -240,6 +248,32 @@ export function activate(context: ExtensionContext) {
}
+function showStatusBarMessage(params : ShowStatusMessageParams) {
+ let decorated : string = params.message;
+ let defTimeout;
+
+ switch (params.type) {
+ case MessageType.Error:
+ decorated = '$(error) ' + params.message;
+ defTimeout = 0;
+ break;
+ case MessageType.Warning:
+ decorated = '$(warning) ' + params.message;
+ defTimeout = 0;
+ break;
+ default:
+ defTimeout = 10000;
+ break;
+ }
+ // params.timeout may be defined but 0 -> should be used
+ const timeout = params.timeout != undefined ? params.timeout : defTimeout;
+ if (timeout > 0) {
+ window.setStatusBarMessage(decorated, timeout);
+ } else {
+ window.setStatusBarMessage(decorated);
+ }
+}
+
export function deactivate(): Thenable<void> {
if (nbProcess != null) {
nbProcess.kill();
diff --git a/java/java.lsp.server/vscode/src/protocol.ts b/java/java.lsp.server/vscode/src/protocol.ts
new file mode 100644
index 0000000..4b485ba
--- /dev/null
+++ b/java/java.lsp.server/vscode/src/protocol.ts
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+'use strict';
+
+import {
+ NotificationType,
+ ShowMessageParams
+} from 'vscode-languageclient';
+
+export interface ShowStatusMessageParams extends ShowMessageParams {
+ /**
+ * The timeout
+ */
+ timeout?: number;
+}
+
+export namespace StatusMessageRequest {
+ export const type = new NotificationType<ShowStatusMessageParams, void>('window/showStatusBarMessage');
+};
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org
For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists