Skip to content

Commit

Permalink
Multiple LS server instances per workspace
Browse files Browse the repository at this point in the history
  • Loading branch information
ghentschke committed Mar 9, 2023
1 parent 360b056 commit 9a805b4
Show file tree
Hide file tree
Showing 19 changed files with 478 additions and 60 deletions.
12 changes: 12 additions & 0 deletions bundles/org.eclipse.cdt.lsp.editor.ui/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,17 @@
</enabledWhen>
</server>
</extension>
<extension
point="org.eclipse.core.runtime.preferences">
<initializer
class="org.eclipse.cdt.lsp.editor.ui.preference.LsPreferenceInitializer">
</initializer>
</extension>
<extension
point="org.eclipse.cdt.lsp.compileCommands">
<locator
class="org.eclipse.cdt.lsp.editor.ui.properties.PropertiesCompileCommandsDirLocator">
</locator>
</extension>

</plugin>
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.util.List;

import org.eclipse.cdt.lsp.editor.ui.preference.LspEditorPreferences;
import org.eclipse.cdt.lsp.editor.ui.properties.LspEditorPropertiesPage;
import org.eclipse.cdt.lsp.server.DefaultCLanguageServerProvider;
import org.eclipse.cdt.utils.CommandLineUtil;
import org.eclipse.jface.preference.IPreferenceStore;
Expand All @@ -26,28 +27,25 @@
public class CdtCLanguageServerProvider extends DefaultCLanguageServerProvider {
private static final IPreferenceStore preferenceStore = LspEditorUiPlugin.getDefault().getLsPreferences();


@Override
protected List<String> createCommands() {
List<String> commands = super.createCommands();
setPreferenceStoreDefaults(commands); // use the server provider settings as default
List<String> retCommands = new ArrayList<>();
List<String> defaultCommands = super.createCommands();
List<String> commandsFromStore = getCommandsFromStore();
if (commandsFromStore.isEmpty()) {
return commands;
}
return commandsFromStore;
}

private void setPreferenceStoreDefaults(List<String> commands) {
if (!commands.isEmpty()) {
//set values in preference store:
preferenceStore.setDefault(LspEditorPreferences.SERVER_PATH, commands.get(0));
String args = "";
for (int i=1; i<commands.size(); i++) {
args = args + " " + commands.get(i);
if (!commandsFromStore.isEmpty()) {
retCommands.add(commandsFromStore.get(0)); //add server path
if (commandsFromStore.size() > 1) {
for (int i=1; i<commandsFromStore.size(); i++) {
retCommands.add(commandsFromStore.get(i));
}
} else {
for (int i=1; i<defaultCommands.size(); i++) {
retCommands.add(defaultCommands.get(i));
}
}
preferenceStore.setDefault(LspEditorPreferences.SERVER_OPTIONS, args);
return retCommands;
}
return defaultCommands;
}

private List<String> getCommandsFromStore(){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class LspEditorUiMessages extends NLS {
public static String LspEditorPreferencePage_preferLspEditor_description;
public static String LspEditorPreferencePage_server_options;
public static String LspEditorPreferencePage_server_path;
public static String LspEditorPreferencePage_compile_commands_dir;

public static String LspEditorPropertiesPage_projectSpecificSettings;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ LspEditorPreferencePage_preferLspEditor=Prefer C/C++ Editor (LSP)
LspEditorPreferencePage_preferLspEditor_description=Prefer to use language server based C/C++ Editor instead of classic C/C++ Editor
LspEditorPreferencePage_server_path=Path to the server executable:
LspEditorPreferencePage_server_options=Command-line options for the server:
LspEditorPreferencePage_compile_commands_dir=Compile commands directory:

LspEditorPropertiesPage_projectSpecificSettings=Project specific editor settings
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ public static void logError(String message, Throwable throwable) {
getDefault().getLog().error(message, throwable);
}

public static void logError(String message) {
getDefault().getLog().error(message);
}

public IWorkspace getWorkspace() {
return workspace;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.eclipse.cdt.lsp.editor.ui.preference;

import org.eclipse.cdt.lsp.LspPlugin;
import org.eclipse.cdt.lsp.editor.ui.LspEditorUiPlugin;
import org.eclipse.cdt.lsp.editor.ui.properties.LspEditorPropertiesPage;
import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
import org.eclipse.jface.preference.IPreferenceStore;

public class LsPreferenceInitializer extends AbstractPreferenceInitializer {
private static final IPreferenceStore preferenceStore = LspEditorUiPlugin.getDefault().getLsPreferences();

@Override
public void initializeDefaultPreferences() {
var cLanguageServerProvider = LspPlugin.getDefault().getCLanguageServerProvider();
if (cLanguageServerProvider == null) {
LspEditorUiPlugin.logError("Cannot determine language server provider");
return;
}
preferenceStore.setDefault(LspEditorPreferences.SERVER_PATH, cLanguageServerProvider.getDefaultServerPath());
preferenceStore.setDefault(LspEditorPreferences.SERVER_OPTIONS, cLanguageServerProvider.getDefaultOptionsAsString());
preferenceStore.setDefault(LspEditorPropertiesPage.COMPILE_COMMANDS_DIR, LspEditorPropertiesPage.DEFAULT_COMPILE_COMMANDS_DIR);

preferenceStore.setValue(LspEditorPreferences.SERVER_PATH, cLanguageServerProvider.getServerPath());
preferenceStore.setValue(LspEditorPreferences.SERVER_OPTIONS, cLanguageServerProvider.getOptionsAsString());
preferenceStore.setValue(LspEditorPropertiesPage.COMPILE_COMMANDS_DIR, LspEditorPropertiesPage.DEFAULT_COMPILE_COMMANDS_DIR);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import java.util.Optional;

import org.eclipse.cdt.lsp.editor.ui.LspEditorUiMessages;
import org.eclipse.cdt.lsp.editor.ui.LspEditorUiPlugin;
import org.eclipse.cdt.lsp.editor.ui.preference.LspEditorPreferences;
import org.eclipse.core.resources.IProject;
Expand All @@ -24,6 +25,7 @@
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.PreferenceMetadata;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.preference.StringFieldEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
Expand All @@ -35,8 +37,11 @@
import org.osgi.service.prefs.BackingStoreException;

public class LspEditorPropertiesPage extends PropertyPage {
public static final String COMPILE_COMMANDS_DIR = "compile_commands_dir";
public static final String DEFAULT_COMPILE_COMMANDS_DIR = "build/default";

private Button preferLspEditorCheckbox;
private StringFieldEditor compileCommandsDir;

@Override
protected Control createContents(Composite parent) {
Expand All @@ -55,6 +60,7 @@ protected Control createContents(Composite parent) {
protected void performDefaults() {
super.performDefaults();
preferLspEditorCheckbox.setSelection(LspEditorPreferences.getPreferenceMetadata().defaultValue());
compileCommandsDir.setStringValue("build/default");
}

@Override
Expand All @@ -63,6 +69,7 @@ public boolean performOk() {
if (project.isPresent()) {
IEclipsePreferences node = new ProjectScope(project.get()).getNode(LspEditorUiPlugin.PLUGIN_ID);
node.putBoolean(LspEditorPreferences.getPreferenceMetadata().identifer(), preferLspEditorCheckbox.getSelection());
node.put(COMPILE_COMMANDS_DIR, compileCommandsDir.getStringValue());
try {
node.flush();
return true;
Expand All @@ -75,11 +82,15 @@ public boolean performOk() {

private void addSettingsSection(Composite parent) {
PreferenceMetadata<Boolean> option = LspEditorPreferences.getPreferenceMetadata();
Composite composite = createDefaultComposite(parent);
preferLspEditorCheckbox = new Button(composite, SWT.CHECK);
Composite compositeCheckbox = createDefaultComposite(parent);
preferLspEditorCheckbox = new Button(compositeCheckbox, SWT.CHECK);
preferLspEditorCheckbox.setLayoutData(new GridData());
preferLspEditorCheckbox.setText(option.name());
preferLspEditorCheckbox.setToolTipText(option.description());

Composite compositeCompileCommandsDir = createDefaultComposite(parent);
compileCommandsDir = new StringFieldEditor(COMPILE_COMMANDS_DIR,
LspEditorUiMessages.LspEditorPreferencePage_compile_commands_dir, compositeCompileCommandsDir);
}

private void load() {
Expand All @@ -88,8 +99,12 @@ private void load() {
if (project.isPresent()) {
preferLspEditorCheckbox.setSelection(Platform.getPreferencesService().getBoolean(LspEditorUiPlugin.PLUGIN_ID, option.identifer(),
option.defaultValue(), new IScopeContext[] { new ProjectScope(project.get()) }));

compileCommandsDir.setStringValue(Platform.getPreferencesService().getString(LspEditorUiPlugin.PLUGIN_ID, COMPILE_COMMANDS_DIR,
DEFAULT_COMPILE_COMMANDS_DIR, new IScopeContext[] { new ProjectScope(project.get()) }));
} else {
preferLspEditorCheckbox.setSelection(option.defaultValue());
compileCommandsDir.setStringValue(DEFAULT_COMPILE_COMMANDS_DIR);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.eclipse.cdt.lsp.editor.ui.properties;

import java.net.URI;

import org.eclipse.cdt.lsp.LspPlugin;
import org.eclipse.cdt.lsp.editor.ui.LspEditorUiPlugin;
import org.eclipse.cdt.lsp.server.ICompileCommandsDirLocator;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;

public class PropertiesCompileCommandsDirLocator implements ICompileCommandsDirLocator {

@Override
public IPath getCompileCommandsDir(URI uri) {
var project = getProject(uri);
if (project == null) {
return null;
}
IEclipsePreferences node = new ProjectScope(project).getNode(LspEditorUiPlugin.PLUGIN_ID);
if (node == null) {
return null;
}
var relativePath = node.get(LspEditorPropertiesPage.COMPILE_COMMANDS_DIR, "build/default");
return project.getLocation().append(relativePath);
}

private IProject getProject(URI uri) {
var scheme = uri.getScheme();
if ("file".equals(scheme)) {
IContainer[] container = LspPlugin.getDefault().getWorkspace().getRoot().findContainersForLocationURI(uri);
if (container.length > 0) {
return container[0].getProject();
}
}
return null;
}

}
3 changes: 2 additions & 1 deletion bundles/org.eclipse.cdt.lsp/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="serverProvider" name="C/C++ Language Server" schema="schema/serverProvider.exsd"/>
<extension-point id="compileCommands" name="Directory locator for compile_commands.json file" schema="schema/compileCommands.exsd"/>
<extension
point="org.eclipse.ui.editors">
<editor
Expand Down Expand Up @@ -34,7 +35,7 @@
class="org.eclipse.cdt.lsp.internal.server.CLanguageServerStreamConnectionProvider"
id="org.eclipse.cdt.lsp.server"
label="C/C++ Language Server"
singleton="true">
singleton="false">
</server>
<contentTypeMapping
contentType="org.eclipse.cdt.core.cSource"
Expand Down
102 changes: 102 additions & 0 deletions bundles/org.eclipse.cdt.lsp/schema/compileCommands.exsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
<schema targetNamespace="org.eclipse.cdt.lsp" xmlns="http://www.w3.org/2001/XMLSchema">
<annotation>
<appinfo>
<meta.schema plugin="org.eclipse.cdt.lsp" id="compileCommands" name="Directory locator for compile_commands.json file"/>
</appinfo>
<documentation>
Defines a locator for a directory containing the compile_commands.json file for a given file URI
</documentation>
</annotation>

<element name="extension">
<annotation>
<appinfo>
<meta.element />
</appinfo>
</annotation>
<complexType>
<sequence>
<element ref="locator"/>
</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="locator">
<complexType>
<attribute name="class" type="string" use="required">
<annotation>
<documentation>
Class implementing the ICompileCommandsDirLocator inferface.
</documentation>
<appinfo>
<meta.attribute kind="java" basedOn=":org.eclipse.cdt.lsp.server.ICompileCommandsDirLocator"/>
</appinfo>
</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>
Loading

0 comments on commit 9a805b4

Please sign in to comment.