Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions org.eclipse.lsp4e/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Language Server Protocol client for Eclipse IDE (Incubation)
Bundle-SymbolicName: org.eclipse.lsp4e;singleton:=true
Bundle-Version: 0.17.3.qualifier
Bundle-Version: 0.18.0.qualifier
Bundle-RequiredExecutionEnvironment: JavaSE-17
Require-Bundle: org.eclipse.core.runtime;bundle-version="3.12.0",
org.eclipse.equinox.common;bundle-version="3.8.0",
Expand Down Expand Up @@ -43,13 +43,15 @@ Require-Bundle: org.eclipse.core.runtime;bundle-version="3.12.0",
com.google.guava;bundle-version="30.1.0",
org.eclipse.e4.core.commands,
org.eclipse.compare.core,
org.eclipse.compare
org.eclipse.compare,
org.eclipse.core.net
Bundle-ClassPath: .
Bundle-Localization: plugin
Bundle-ActivationPolicy: lazy
Bundle-Activator: org.eclipse.lsp4e.LanguageServerPlugin
Export-Package: org.eclipse.lsp4e;x-internal:=true,
org.eclipse.lsp4e.command;x-internal:=true,
org.eclipse.lsp4e.configuration;x-internal:=true,
org.eclipse.lsp4e.format;x-internal:=true,
org.eclipse.lsp4e.operations.codeactions;x-internal:=true,
org.eclipse.lsp4e.operations.completion;x-internal:=true,
Expand Down
7 changes: 7 additions & 0 deletions org.eclipse.lsp4e/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<?eclipse version="3.4"?>
<plugin>
<extension-point id="languageServer" name="Language Server" schema="schema/languageServer.exsd"/>
<extension-point id="languageServerConfiguration" name="Language Server configuration providers" schema="schema/languageServerConfiguration.exsd"/>
<!-- Extension point will ideally be "org.eclipse.text...." because
the feature should be part of the generic text editor -->
<extension
Expand Down Expand Up @@ -754,4 +755,10 @@
</and>
</definition>
</extension>
<extension
point="org.eclipse.core.runtime.preferences">
<modifier
class="org.eclipse.lsp4e.PreferenceModifyListener2">
</modifier>
</extension>
</plugin>
2 changes: 1 addition & 1 deletion org.eclipse.lsp4e/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</parent>
<artifactId>org.eclipse.lsp4e</artifactId>
<packaging>eclipse-plugin</packaging>
<version>0.17.3-SNAPSHOT</version>
<version>0.18.0-SNAPSHOT</version>

<build>
<plugins>
Expand Down
7 changes: 7 additions & 0 deletions org.eclipse.lsp4e/schema/languageServer.exsd
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,13 @@ If set to a number bigger than zero, the server will run until the timeout is re
</documentation>
</annotation>
</attribute>
<attribute name="watchConfiguration" type="string">
<annotation>
<documentation>
comma separated list of configuration prefix that will be send after initialization and after ConfigurationRegistry.notifyChange calls
</documentation>
</annotation>
</attribute>
</complexType>
</element>

Expand Down
134 changes: 134 additions & 0 deletions org.eclipse.lsp4e/schema/languageServerConfiguration.exsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
<schema targetNamespace="org.eclipse.lsp4e" xmlns="http://www.w3.org/2001/XMLSchema">
<annotation>
<appinfo>
<meta.schema plugin="org.eclipse.lsp4e" id="languageServerConfiguration" name="Language Server configuration providers"/>
</appinfo>
<documentation>
This extension point allows to define configuration sources.
</documentation>
</annotation>

<element name="extension">
<annotation>
<appinfo>
<meta.element />
</appinfo>
</annotation>
<complexType>
<sequence>
<element ref="provider" minOccurs="0" maxOccurs="unbounded"/>
<element ref="alias" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
<attribute name="point" type="string" use="required">
<annotation>
<documentation>

</documentation>
</annotation>
</attribute>
<attribute name="id" type="string">
<annotation>
<documentation>

</documentation>
</annotation>
</attribute>
<attribute name="name" type="string">
<annotation>
<documentation>

</documentation>
<appinfo>
<meta.attribute translatable="true"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>

<element name="provider">
<annotation>
<documentation>
Configuration provider report supported configuration keys and fetch them on demand

To notify servers about change, implementors should call ConfigurationRegistry.notifyChange
</documentation>
</annotation>
<complexType>
<attribute name="class" type="string" use="required">
<annotation>
<documentation>

</documentation>
<appinfo>
<meta.attribute kind="java" basedOn=":org.eclipse.lsp4e.configuration.IConfigurationProvider"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>

<element name="alias">
<annotation>
<documentation>
Allow map configuration supported by providers to they alias
</documentation>
</annotation>
<complexType>
<attribute name="source" type="string" use="required">
<annotation>
<documentation>
Original settings paths already support by another provider
</documentation>
</annotation>
</attribute>
<attribute name="target" type="string" use="required">
<annotation>
<documentation>
New settings paths
</documentation>
</annotation>
</attribute>
</complexType>
</element>

<annotation>
<appinfo>
<meta.section type="since"/>
</appinfo>
<documentation>
[Enter the first release in which this extension point appears.]
</documentation>
</annotation>

<annotation>
<appinfo>
<meta.section type="examples"/>
</appinfo>
<documentation>
[Enter extension point usage example here.]
</documentation>
</annotation>

<annotation>
<appinfo>
<meta.section type="apiinfo"/>
</appinfo>
<documentation>
[Enter API information here.]
</documentation>
</annotation>

<annotation>
<appinfo>
<meta.section type="implementation"/>
</appinfo>
<documentation>
[Enter information about supplied implementation of this extension point.]
</documentation>
</annotation>


</schema>
10 changes: 8 additions & 2 deletions org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageClientImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.lsp4e.configuration.ConfigurationRegistry;
import org.eclipse.lsp4e.progress.LSPProgressManager;
import org.eclipse.lsp4e.ui.Messages;
import org.eclipse.lsp4e.ui.UI;
import org.eclipse.lsp4j.ApplyWorkspaceEditParams;
import org.eclipse.lsp4j.ApplyWorkspaceEditResponse;
import org.eclipse.lsp4j.ConfigurationItem;
import org.eclipse.lsp4j.ConfigurationParams;
import org.eclipse.lsp4j.Location;
import org.eclipse.lsp4j.MessageActionItem;
Expand Down Expand Up @@ -75,8 +77,12 @@ protected final LanguageServer getLanguageServer() {
public CompletableFuture<List<Object>> configuration(ConfigurationParams configurationParams) {
// override as needed
List<Object> list = new ArrayList<>(configurationParams.getItems().size());
for (int i = 0; i < configurationParams.getItems().size(); i++) {
list.add(null);
for (ConfigurationItem item: configurationParams.getItems()) {
if (item.getScopeUri() == null) {
list.add(ConfigurationRegistry.getInstance().resolve(item.getSection()));
} else {
list.add(null);
}
}
return CompletableFuture.completedFuture(list);
}
Expand Down
46 changes: 46 additions & 0 deletions org.eclipse.lsp4e/src/org/eclipse/lsp4e/LanguageServerWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jface.text.IDocument;
import org.eclipse.lsp4e.LanguageServersRegistry.LanguageServerDefinition;
import org.eclipse.lsp4e.configuration.ConfigurationRegistry;
import org.eclipse.lsp4e.internal.FileBufferListenerAdapter;
import org.eclipse.lsp4e.internal.SupportedFeatures;
import org.eclipse.lsp4e.server.StreamConnectionProvider;
Expand All @@ -74,6 +75,7 @@
import org.eclipse.lsp4j.ClientCapabilities;
import org.eclipse.lsp4j.ClientInfo;
import org.eclipse.lsp4j.CodeActionOptions;
import org.eclipse.lsp4j.DidChangeConfigurationParams;
import org.eclipse.lsp4j.DidChangeWorkspaceFoldersParams;
import org.eclipse.lsp4j.DocumentFormattingOptions;
import org.eclipse.lsp4j.DocumentRangeFormattingOptions;
Expand Down Expand Up @@ -161,6 +163,7 @@ public void dirtyStateChanged(IFileBuffer buffer, boolean isDirty) {
private final Timer timer = new Timer("Stop Language Server Task Processor"); //$NON-NLS-1$
private TimerTask stopTimerTask;
private AtomicBoolean stopping = new AtomicBoolean(false);
private String[] subscribedConfig;

private final ExecutorService dispatcher;

Expand Down Expand Up @@ -189,6 +192,7 @@ private LanguageServerWrapper(@Nullable IProject project, @NonNull LanguageServe
this.initialPath = initialPath;
this.serverDefinition = serverDefinition;
this.connectedDocuments = new HashMap<>();
this.subscribedConfig = serverDefinition.subcribedConfigurations;
String projectName = (project != null && project.getName() != null && !serverDefinition.isSingleton) ? ("@" + project.getName()) : ""; //$NON-NLS-1$//$NON-NLS-2$
String dispatcherThreadNameFormat = "LS-" + serverDefinition.id + projectName + "#dispatcher"; //$NON-NLS-1$ //$NON-NLS-2$
this.dispatcher = Executors
Expand Down Expand Up @@ -307,6 +311,10 @@ public synchronized void start() throws IOException {
this.initiallySupportsWorkspaceFolders = supportsWorkspaceFolders(serverCapabilities);
}).thenRun(() -> {
this.languageServer.initialized(new InitializedParams());
}).thenRun(() -> {
if (this.subscribedConfig != null && this.subscribedConfig.length > 0) {
sendConfiguration();
}
}).thenRun(() -> {
final Map<URI, IDocument> toReconnect = filesToReconnect;
initializeFuture.thenRunAsync(() -> {
Expand Down Expand Up @@ -718,6 +726,34 @@ public void sendNotification(@NonNull Consumer<LanguageServer> fn) {
getInitializedServer().thenAcceptAsync(fn, this.dispatcher);
}

public void configurationChanged(String[] paths) {
if (this.subscribedConfig == null) {
return;
}
if (subscribedConfig.length == 0) {
sendNotification(ls -> ls.getWorkspaceService().didChangeConfiguration(new DidChangeConfigurationParams()));
} else {
for (String prefix : subscribedConfig) {
for (String path : paths) {
if (path.startsWith(prefix)) {
sendConfiguration();
return;
}
}
}
}
}

private void sendConfiguration()
{
Map<String, Object> obj = new HashMap<>();
for (String prefx : subscribedConfig) {
obj.put(prefx, ConfigurationRegistry.getInstance().resolve(prefx));
}

sendNotification(ls -> ls.getWorkspaceService().didChangeConfiguration(new DidChangeConfigurationParams(obj)));
}

/**
* Runs a request on the language server
*
Expand Down Expand Up @@ -913,6 +949,16 @@ void registerCapability(RegistrationParams params) {
serverCapabilities.setTypeHierarchyProvider(Boolean.TRUE);
addRegistration(reg, () -> serverCapabilities.setTypeHierarchyProvider(typeHierarchyBeforeRegistration));
break;

case "workspace/didChangeConfiguration": //$NON-NLS-1$
synchronized(this) {
this.subscribedConfig = new String[0];
addRegistration(reg, () -> {
subscribedConfig = null;
});
}

break;
}});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,20 +89,24 @@ public class LanguageServersRegistry {
private static final String LABEL_ATTRIBUTE = "label"; //$NON-NLS-1$
private static final String ENABLED_WHEN_ATTRIBUTE = "enabledWhen"; //$NON-NLS-1$
private static final String ENABLED_WHEN_DESC = "description"; //$NON-NLS-1$
private static final String WATCH_CONFIGURATION = "watchConfiguration"; //$NON-NLS-1$
private static final String COMMA = ","; //$NON-NLS-1$

public abstract static class LanguageServerDefinition {
public final @NonNull String id;
public final @NonNull String label;
public final boolean isSingleton;
public final int lastDocumentDisconnectedTimeout;
public final @NonNull Map<IContentType, String> languageIdMappings;
public final String[] subcribedConfigurations;

LanguageServerDefinition(@NonNull String id, @NonNull String label, boolean isSingleton, int lastDocumentDisconnectedTimeout) {
LanguageServerDefinition(@NonNull String id, @NonNull String label, boolean isSingleton, int lastDocumentDisconnectedTimeout, String[] subscribedConfigurations) {
this.id = id;
this.label = label;
this.isSingleton = isSingleton;
this.lastDocumentDisconnectedTimeout = lastDocumentDisconnectedTimeout;
this.languageIdMappings = new ConcurrentHashMap<>();
this.subcribedConfigurations = subscribedConfigurations;
}

public void registerAssociation(@NonNull IContentType contentType, @NonNull String languageId) {
Expand Down Expand Up @@ -159,7 +163,7 @@ private static int getLastDocumentDisconnectedTimeout(IConfigurationElement elem
}

public ExtensionLanguageServerDefinition(@NonNull IConfigurationElement element) {
super(element.getAttribute(ID_ATTRIBUTE), element.getAttribute(LABEL_ATTRIBUTE), getIsSingleton(element), getLastDocumentDisconnectedTimeout(element));
super(element.getAttribute(ID_ATTRIBUTE), element.getAttribute(LABEL_ATTRIBUTE), getIsSingleton(element), getLastDocumentDisconnectedTimeout(element), element.getAttribute(WATCH_CONFIGURATION) == null ? null : element.getAttribute(WATCH_CONFIGURATION).split(COMMA));
this.extension = element;
}

Expand Down Expand Up @@ -232,7 +236,7 @@ static class LaunchConfigurationLanguageServerDefinition extends LanguageServerD

public LaunchConfigurationLanguageServerDefinition(ILaunchConfiguration launchConfiguration,
Set<String> launchModes) {
super(launchConfiguration.getName(), launchConfiguration.getName(), DEFAULT_SINGLETON, DEFAULT_LAST_DOCUMENTED_DISCONNECTED_TIEMOUT);
super(launchConfiguration.getName(), launchConfiguration.getName(), DEFAULT_SINGLETON, DEFAULT_LAST_DOCUMENTED_DISCONNECTED_TIEMOUT, null);
this.launchConfiguration = launchConfiguration;
this.launchModes = launchModes;
}
Expand Down
Loading