Skip to content

Commit

Permalink
Allow extensions to contribute to WorkspaceService
Browse files Browse the repository at this point in the history
Currently supports
didChangeWorkspaceFolders

Signed-off-by: Mickael Istria <[email protected]>
  • Loading branch information
mickaelistria committed Jan 19, 2021
1 parent 5488280 commit 38895d5
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/LemMinX-Extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ The [LemMinx Extensions API](https://github.com/eclipse/lemminx/tree/master/org.
- CodeLens with [ICodeLensParticipant](https://github.com/eclipse/lemminx/blob/master/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/extensions/codelens/ICodeLensParticipant.java)
- Formatter with [IFormatterParticipant](https://github.com/eclipse/lemminx/blob/master/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/extensions/format/IFormatterParticipant.java)
- Symbols with [ISymbolsProviderParticipant](https://github.com/eclipse/lemminx/blob/master/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/extensions/ISymbolsProviderParticipant.java)
- Monitoring workspace folders with [IWorkspaceServiceParticipant](https://github.com/eclipse/lemminx/blob/master/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/extensions/IWorkspaceServiceParticipant.java)

## XML Language Server services available for extensions
XML Language Server extension may need to use standard Language Server features such as commands, documents and ability to manipulate documents. These are available to extensions indirectly via specialized service API.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.eclipse.lemminx.services.extensions.commands.IXMLCommandService;
import org.eclipse.lsp4j.DidChangeConfigurationParams;
import org.eclipse.lsp4j.DidChangeWatchedFilesParams;
import org.eclipse.lsp4j.DidChangeWorkspaceFoldersParams;
import org.eclipse.lsp4j.ExecuteCommandParams;
import org.eclipse.lsp4j.FileEvent;
import org.eclipse.lsp4j.SymbolInformation;
Expand Down Expand Up @@ -82,6 +83,11 @@ public void didChangeConfiguration(DidChangeConfigurationParams params) {
xmlLanguageServer.getCapabilityManager().syncDynamicCapabilitiesWithPreferences();
}

@Override
public void didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParams params) {
xmlLanguageServer.getXMLLanguageService().getWorkspaceServiceParticipants().forEach(participant -> participant.didChangeWorkspaceFolders(params));
}

@Override
public void didChangeWatchedFiles(DidChangeWatchedFilesParams params) {
XMLTextDocumentService xmlTextDocumentService = (XMLTextDocumentService) xmlLanguageServer
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright (c) 2021 Red Hat Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.lemminx.services.extensions;

import org.eclipse.lsp4j.DidChangeWorkspaceFoldersParams;

public interface IWorkspaceServiceParticipant {

public void didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParams params);
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.eclipse.lemminx.services.extensions.save.ISaveContext.SaveContextType;
import org.eclipse.lemminx.uriresolver.URIResolverExtensionManager;
import org.eclipse.lsp4j.InitializeParams;
import org.eclipse.lsp4j.services.WorkspaceService;

/**
* XML extensions registry.
Expand All @@ -56,6 +57,7 @@ public class XMLExtensionsRegistry implements IComponentProvider {
private final List<IRenameParticipant> renameParticipants;
private final List<IFormatterParticipant> formatterParticipants;
private final List<ISymbolsProviderParticipant> symbolsProviderParticipants;
private final List<IWorkspaceServiceParticipant> workspaceServiceParticipants;
private IXMLDocumentProvider documentProvider;
private IXMLValidationService validationService;
private IXMLCommandService commandService;
Expand All @@ -68,7 +70,7 @@ public class XMLExtensionsRegistry implements IComponentProvider {

private IXMLNotificationService notificationService;

private final Map<Class, Object> components;
private final Map<Class<?>, Object> components;

public XMLExtensionsRegistry() {
extensions = new ArrayList<>();
Expand All @@ -85,6 +87,7 @@ public XMLExtensionsRegistry() {
renameParticipants = new ArrayList<>();
formatterParticipants = new ArrayList<>();
symbolsProviderParticipants = new ArrayList<>();
workspaceServiceParticipants = new ArrayList<>();
resolverExtensionManager = new URIResolverExtensionManager();
components = new HashMap<>();
registerComponent(resolverExtensionManager);
Expand Down Expand Up @@ -196,6 +199,15 @@ public Collection<ISymbolsProviderParticipant> getSymbolsProviderParticipants()
return symbolsProviderParticipants;
}

/**
* @return
* @since 0.14.2
*/
public Collection<IWorkspaceServiceParticipant> getWorkspaceServiceParticipants() {
initializeIfNeeded();
return workspaceServiceParticipants;
}

public void initializeIfNeeded() {
if (initialized) {
return;
Expand Down Expand Up @@ -356,6 +368,22 @@ public void registerSymbolsProviderParticipant(ISymbolsProviderParticipant symbo
public void unregisterSymbolsProviderParticipant(ISymbolsProviderParticipant symbolsProviderParticipant) {
symbolsProviderParticipants.remove(symbolsProviderParticipant);
}

/**
* @param workspaceServiceParticipant
* @since 0.14.2
*/
public void registerWorkspaceServiceParticipant(IWorkspaceServiceParticipant workspaceServiceParticipant) {
workspaceServiceParticipants.add(workspaceServiceParticipant);
}

/**
* @param workspaceServiceParticipant
* @since 0.14.2
*/
public void unregisterWorkspaceServiceParticipant(IWorkspaceServiceParticipant workspaceServiceParticipant) {
workspaceServiceParticipants.remove(workspaceServiceParticipant);
}

/**
* Returns the XML Document provider and null otherwise.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*******************************************************************************
* Copyright (c) 2021 Red Hat Inc. and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*********************************************************************************/
package org.eclipse.lemminx.services.extensions;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;

import java.util.Collections;
import java.util.concurrent.CompletableFuture;

import org.eclipse.lemminx.XMLLanguageServer;
import org.eclipse.lemminx.customservice.XMLLanguageClientAPI;
import org.eclipse.lsp4j.DidChangeWorkspaceFoldersParams;
import org.eclipse.lsp4j.MessageActionItem;
import org.eclipse.lsp4j.MessageParams;
import org.eclipse.lsp4j.PublishDiagnosticsParams;
import org.eclipse.lsp4j.RegistrationParams;
import org.eclipse.lsp4j.ShowMessageRequestParams;
import org.eclipse.lsp4j.WorkspaceFolder;
import org.eclipse.lsp4j.WorkspaceFoldersChangeEvent;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class WorkspaceServiceParticipantTest {

private static class CaptureWokspaceServiceCalls implements IWorkspaceServiceParticipant {

public DidChangeWorkspaceFoldersParams didChangeWorkspaceFolders;

@Override
public void didChangeWorkspaceFolders(DidChangeWorkspaceFoldersParams params) {
this.didChangeWorkspaceFolders = params;
}
}

private CaptureWokspaceServiceCalls workspaceServiceParticipant;
private XMLLanguageServer server;

@BeforeEach
public void initializeLanguageService() {
this.server = new XMLLanguageServer();
server.setClient(new XMLLanguageClientAPI() {
@Override public void telemetryEvent(Object object) { }
@Override public CompletableFuture<MessageActionItem> showMessageRequest(ShowMessageRequestParams requestParams) {
return null;
}
@Override public void showMessage(MessageParams messageParams) { }
@Override public void publishDiagnostics(PublishDiagnosticsParams diagnostics) { }
@Override public void logMessage(MessageParams message) { }
@Override public CompletableFuture<Void> registerCapability(RegistrationParams params) {
return null;
}
});
this.workspaceServiceParticipant = new CaptureWokspaceServiceCalls();
server.getXMLLanguageService().registerWorkspaceServiceParticipant(this.workspaceServiceParticipant);
}

@Test
public void testWorkspaceFolders() {
DidChangeWorkspaceFoldersParams params = new DidChangeWorkspaceFoldersParams(new WorkspaceFoldersChangeEvent(Collections.singletonList(new WorkspaceFolder("added")), Collections.singletonList(new WorkspaceFolder("removed"))));
server.getWorkspaceService().didChangeWorkspaceFolders(params);
assertArrayEquals(new String[] { "added" }, workspaceServiceParticipant.didChangeWorkspaceFolders.getEvent().getAdded().stream().map(WorkspaceFolder::getUri).toArray(String[]::new));
assertArrayEquals(new String[] { "removed" }, workspaceServiceParticipant.didChangeWorkspaceFolders.getEvent().getRemoved().stream().map(WorkspaceFolder::getUri).toArray(String[]::new));
}
}

0 comments on commit 38895d5

Please sign in to comment.