M lsp/Server.java => lsp/Server.java +12 -0
@@ 48,6 48,7 @@ import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionList;
import org.eclipse.lsp4j.CompletionParams;
import org.eclipse.lsp4j.DefinitionParams;
+import org.eclipse.lsp4j.DidChangeConfigurationParams;
import org.eclipse.lsp4j.DocumentDiagnosticParams;
import org.eclipse.lsp4j.DocumentDiagnosticReport;
import org.eclipse.lsp4j.DocumentFormattingParams;
@@ 295,6 296,7 @@ public class Server {
log(Log.DEBUG, "Initialization response: " + result.toString());
this.handle.getRemoteProxy().initialized(new InitializedParams());
this.initResult = result;
+ sendConfiguration();
Synchronization.didOpenAll(this);
Utils.showTemporaryMessage("Server ready");
} catch (Exception e) {
@@ 304,6 306,16 @@ public class Server {
}));
}
+ private void sendConfiguration() {
+ try {
+ Settings settings = Settings.get(this.workspaceFolders);
+ DidChangeConfigurationParams params = new DidChangeConfigurationParams(settings.getAll());
+ this.handle.getRemoteProxy().getWorkspaceService().didChangeConfiguration(params);
+ } catch (Exception e) {
+ log(Log.WARNING, "Failed to send initial configuration", e);
+ }
+ }
+
/*
* Executes the lsp.pull-diagnostics action.
*/
M lsp/Settings.java => lsp/Settings.java +61 -8
@@ 3,11 3,19 @@ package lsp;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.Map;
import java.util.HashMap;
+import org.gjt.sp.jedit.Buffer;
+import org.gjt.sp.jedit.jEdit;
+import org.gjt.sp.jedit.OperatingSystem;
import org.gjt.sp.util.Log;
+import org.eclipse.lsp4j.WorkspaceFolder;
+
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
@@ 16,10 24,24 @@ import com.google.gson.JsonPrimitive;
public class Settings {
private Map<String, Object> settings;
- public Settings(File file) throws IOException {
+ private Settings() {
+ this(Collections.emptyMap());
+ }
+
+ private Settings(Map<String, Object> settings) {
+ this.settings = settings;
+ }
+
+ private Settings(String parent, String path) {
+ Buffer buffer = jEdit.openTemporary(null, parent, path, false);
+ String text = buffer.getText();
+ jEdit._closeBuffer(null, buffer);
+
this.settings = new HashMap<>();
- JsonObject root = JsonParser.parseReader(new FileReader(file)).getAsJsonObject();
- load(root, null);
+ if (!text.isEmpty()) {
+ JsonObject root = JsonParser.parseString(text).getAsJsonObject();
+ load(root, null);
+ }
}
private void load(JsonObject object, String prefix) {
@@ 47,19 69,50 @@ public class Settings {
}
}
- public Map<String, Object> getSettings() {
- return this.settings;
+ private Settings merge(Settings other) {
+ if (other == null || other.settings.isEmpty()) {
+ return this;
+ }
+ Map<String, Object> mergedSettings = new HashMap<>(this.settings);
+ mergedSettings.putAll(other.settings);
+ return new Settings(mergedSettings);
}
- public Map<String, Object> getSettingsForScope(String section) {
+ public Map<String, Object> getSection(String section) {
String prefix = section + ".";
Map<String, Object> sectionSettings = new HashMap<>();
for (Map.Entry<String, Object> entry : this.settings.entrySet()) {
String key = entry.getKey();
- if (key.startsWith(prefix)) {
- sectionSettings.put(key.substring(prefix.length()), entry.getValue());
+ if (key.equals(section) || key.startsWith(prefix)) {
+ sectionSettings.put(key, entry.getValue());
}
}
return sectionSettings;
}
+
+ public Map<String, Object> getAll() {
+ return this.settings;
+ }
+
+ public static Settings get(List<WorkspaceFolder> workspaceFolders) {
+ Settings settings = new Settings();
+
+ // See https://code.visualstudio.com/docs/getstarted/settings#_settings-file-locations
+ if (OperatingSystem.isWindows()) {
+ String appData = System.getenv("APPDATA");
+ if (appData != null) {
+ settings = settings.merge(new Settings(appData, "Code/User/settings.json"));
+ }
+ } else if (OperatingSystem.isMacOS()) {
+ settings = settings.merge(new Settings(System.getProperty("user.home"), "Library/Application Support/Code/User/settings.json"));
+ } else if (OperatingSystem.isUnix()) {
+ settings = settings.merge(new Settings(System.getProperty("user.home"), ".config/Code/User/settings.json"));
+ }
+
+ for (WorkspaceFolder folder : workspaceFolders) {
+ settings = settings.merge(new Settings(folder.getUri(), ".vscode/settings.json"));
+ settings = settings.merge(new Settings(folder.getUri(), ".jedit/settings.json"));
+ }
+ return settings;
+ }
}
M lsp/jEditLanguageClient.java => lsp/jEditLanguageClient.java +6 -18
@@ 307,27 307,15 @@ public class jEditLanguageClient implements LanguageClient {
Log.log(Log.DEBUG, this, "configuration: " + params.toString());
CompletableFuture<List<Object>> future = new CompletableFuture<>();
ThreadUtilities.runInBackground(() -> {
- // TODO: iterate over all workspace folders, and merge the results
List<Object> config = new ArrayList<>(params.getItems().size());
- List<WorkspaceFolder> folders = this.server.getWorkspaceFolders();
- if (!folders.isEmpty()) {
- // TODO: use VFS?
- String rootPath = folders.get(0).getUri();
- if (rootPath.startsWith("file://")) {
- rootPath = rootPath.substring(7);
- }
- try {
- Settings settings = new Settings(new File(rootPath, ".vscode/settings.json"));
- for (ConfigurationItem item : params.getItems()) {
- config.add(settings.getSettingsForScope(item.getSection()));
- }
- } catch (IOException e) {
- Log.log(Log.ERROR, this, "Error loading configuration settings:", e);
- }
- } else {
+ try {
+ Settings settings = Settings.get(this.server.getWorkspaceFolders());
for (ConfigurationItem item : params.getItems()) {
- config.add(null);
+ // TODO: support the scope parameter?
+ config.add(settings.getSection(item.getSection()));
}
+ } catch (Exception e) {
+ Log.log(Log.WARNING, this, "Failed to load requested configuration", e);
}
future.complete(config);
});