summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rw-r--r--config.c1
-rw-r--r--lsp-parse.c46
-rw-r--r--lsp-write.c16
-rw-r--r--lsp.c16
-rw-r--r--lsp.h16
-rw-r--r--main.c1
-rw-r--r--ted.c2
-rw-r--r--ted.cfg8
-rw-r--r--ted.h1
10 files changed, 65 insertions, 46 deletions
diff --git a/README.md b/README.md
index e905510..e2ccdf8 100644
--- a/README.md
+++ b/README.md
@@ -70,6 +70,7 @@ to open the command palette, and select "open-config". There are several section
- `[extensions]` for which file extensions should be mapped to which programming languages
Comments begin with `#`, and all other lines are of the form `key = value`.
+Strings can span multiple lines and can either be delimited with `"` or `\``.
By default ted's settings will automatically update when you save the config file.
@@ -163,7 +164,8 @@ to reset all running LSP servers.
You can integrate any LSP server with ted by setting the `lsp` option in the `[core.<language>]` section of `ted.cfg`
to the command which starts the server. Some defaults will already be there, and are listed below. Make
sure you install the LSP(s) you want and put the executables in your PATH (or change the `lsp` variable
-to include the absolute path if not).
+to include the absolute path if not). You can also set configuration options with the `lsp-configuration` option.
+Make sure the configuration you provide is valid JSON.
### C/C++
diff --git a/config.c b/config.c
index b49b031..5d819ad 100644
--- a/config.c
+++ b/config.c
@@ -119,6 +119,7 @@ static SettingString const settings_string[] = {
{"bg-texture", settings_zero.bg_shader_image, sizeof settings_zero.bg_shader_image, true},
{"root-identifiers", settings_zero.root_identifiers, sizeof settings_zero.root_identifiers, true},
{"lsp", settings_zero.lsp, sizeof settings_zero.lsp, true},
+ {"lsp-configuration", settings_zero.lsp_configuration, sizeof settings_zero.lsp_configuration, true},
};
diff --git a/lsp-parse.c b/lsp-parse.c
index 7bbcbd1..8c914fa 100644
--- a/lsp-parse.c
+++ b/lsp-parse.c
@@ -929,30 +929,32 @@ void process_message(LSP *lsp, JSON *json) {
case LSP_REQUEST_RENAME:
add_to_messages = parse_rename(lsp, json, &response);
break;
- case LSP_REQUEST_INITIALIZE: {
- // it's the response to our initialize request!
- if (result.type == JSON_OBJECT) {
- // read server capabilities
- JSONObject capabilities = json_object_get_object(json, result.val.object, "capabilities");
- parse_capabilities(lsp, json, capabilities);
- }
-
- LSPRequest initialized = {
- .type = LSP_REQUEST_INITIALIZED,
- .data = {{0}},
- };
- write_request(lsp, &initialized);
- // we can now send requests which have nothing to do with initialization
- lsp->initialized = true;
- {
- // configure jdtls so it actually supports signature help
- // NOTE: this won't send if the LSP isn't jdtls (because of lsp_supports_request)
- LSPRequest jdtls_configuration = {
- .type = LSP_REQUEST_JDTLS_CONFIGURATION
+ case LSP_REQUEST_INITIALIZE:
+ if (!lsp->initialized) {
+ // it's the response to our initialize request!
+ if (result.type == JSON_OBJECT) {
+ // read server capabilities
+ JSONObject capabilities = json_object_get_object(json, result.val.object, "capabilities");
+ parse_capabilities(lsp, json, capabilities);
+ }
+
+ LSPRequest initialized = {
+ .type = LSP_REQUEST_INITIALIZED,
+ .data = {{0}},
};
- lsp_send_request(lsp, &jdtls_configuration);
+ write_request(lsp, &initialized);
+ // we can now send requests which have nothing to do with initialization
+ lsp->initialized = true;
+ if (lsp->configuration_to_send) {
+ LSPRequest configuration = {
+ .type = LSP_REQUEST_CONFIGURATION
+ };
+ configuration.data.configuration.settings = lsp->configuration_to_send;
+ lsp->configuration_to_send = NULL;
+ lsp_send_request(lsp, &configuration);
+ }
}
- } break;
+ break;
default:
// it's some response we don't care about
break;
diff --git a/lsp-write.c b/lsp-write.c
index c32b8f6..56f8e7d 100644
--- a/lsp-write.c
+++ b/lsp-write.c
@@ -295,7 +295,7 @@ static const char *lsp_request_method(LSPRequest *request) {
return "workspace/workspaceFolders";
case LSP_REQUEST_DID_CHANGE_WORKSPACE_FOLDERS:
return "workspace/didChangeWorkspaceFolders";
- case LSP_REQUEST_JDTLS_CONFIGURATION:
+ case LSP_REQUEST_CONFIGURATION:
return "workspace/didChangeConfiguration";
case LSP_REQUEST_WORKSPACE_SYMBOLS:
return "workspace/symbol";
@@ -613,17 +613,13 @@ void write_request(LSP *lsp, LSPRequest *request) {
write_obj_end(o);
write_obj_end(o);
} break;
- case LSP_REQUEST_JDTLS_CONFIGURATION:
+ case LSP_REQUEST_CONFIGURATION: {
+ const LSPRequestConfiguration *config = &request->data.configuration;
write_key_obj_start(o, "params");
- write_key_obj_start(o, "settings");
- write_key_obj_start(o, "java");
- write_key_obj_start(o, "signatureHelp");
- write_key_bool(o, "enabled", true);
- write_obj_end(o);
- write_obj_end(o);
- write_obj_end(o);
+ write_key(o, "settings");
+ str_builder_append(&o->builder, config->settings);
write_obj_end(o);
- break;
+ } break;
}
write_obj_end(o);
diff --git a/lsp.c b/lsp.c
index 01dc2a3..f721efd 100644
--- a/lsp.c
+++ b/lsp.c
@@ -57,8 +57,11 @@ void lsp_request_free(LSPRequest *r) {
case LSP_REQUEST_HIGHLIGHT:
case LSP_REQUEST_DID_CLOSE:
case LSP_REQUEST_WORKSPACE_FOLDERS:
- case LSP_REQUEST_JDTLS_CONFIGURATION:
break;
+ case LSP_REQUEST_CONFIGURATION: {
+ LSPRequestConfiguration *config = &r->data.configuration;
+ free(config->settings);
+ } break;
case LSP_REQUEST_DID_OPEN: {
LSPRequestDidOpen *open = &r->data.open;
free(open->file_contents);
@@ -165,12 +168,10 @@ static bool lsp_supports_request(LSP *lsp, const LSPRequest *request) {
case LSP_REQUEST_DID_OPEN:
case LSP_REQUEST_DID_CLOSE:
case LSP_REQUEST_DID_CHANGE:
+ case LSP_REQUEST_CONFIGURATION:
case LSP_REQUEST_SHUTDOWN:
case LSP_REQUEST_EXIT:
return true;
- case LSP_REQUEST_JDTLS_CONFIGURATION:
- // not perfect but whatever
- return strstr(lsp->command, "jdtls") != 0;
case LSP_REQUEST_COMPLETION:
return cap->completion_support;
case LSP_REQUEST_SIGNATURE_HELP:
@@ -216,7 +217,7 @@ static bool request_type_is_notification(LSPRequestType type) {
case LSP_REQUEST_DID_CLOSE:
case LSP_REQUEST_DID_CHANGE:
case LSP_REQUEST_DID_CHANGE_WORKSPACE_FOLDERS:
- case LSP_REQUEST_JDTLS_CONFIGURATION:
+ case LSP_REQUEST_CONFIGURATION:
return true;
case LSP_REQUEST_INITIALIZE:
case LSP_REQUEST_SHUTDOWN:
@@ -452,7 +453,7 @@ const char *lsp_document_path(LSP *lsp, LSPDocumentID document) {
return path;
}
-LSP *lsp_create(const char *root_dir, const char *analyzer_command) {
+LSP *lsp_create(const char *root_dir, const char *analyzer_command, const char *configuration) {
LSP *lsp = calloc(1, sizeof *lsp);
if (!lsp) return NULL;
@@ -470,6 +471,8 @@ LSP *lsp_create(const char *root_dir, const char *analyzer_command) {
str_hash_table_create(&lsp->document_ids, sizeof(u32));
lsp->command = str_dup(analyzer_command);
+ if (configuration && *configuration)
+ lsp->configuration_to_send = str_dup(configuration);
lsp->quit_sem = SDL_CreateSemaphore(0);
lsp->error_mutex = SDL_CreateMutex();
lsp->messages_mutex = SDL_CreateMutex();
@@ -574,6 +577,7 @@ void lsp_free(LSP *lsp) {
arr_free(lsp->signature_help_trigger_chars);
arr_free(lsp->signature_help_retrigger_chars);
free(lsp->command);
+ free(lsp->configuration_to_send);
memset(lsp, 0, sizeof *lsp);
free(lsp);
}
diff --git a/lsp.h b/lsp.h
index 917ec7a..b501da1 100644
--- a/lsp.h
+++ b/lsp.h
@@ -61,10 +61,7 @@ typedef enum {
LSP_REQUEST_INITIALIZE, // initialize
LSP_REQUEST_INITIALIZED, // initialized
LSP_REQUEST_CANCEL, // $/cancelRequest
- // workspace/didChangeConfiguration with parameters specifically for jdtls.
- // we need this because annoyingly jdtls refuses to give signature help
- // unless you specifically configure it to do that
- LSP_REQUEST_JDTLS_CONFIGURATION,
+ LSP_REQUEST_CONFIGURATION, // workspace/didChangeConfiguration
LSP_REQUEST_SHUTDOWN, // shutdown
LSP_REQUEST_EXIT, // exit
LSP_REQUEST_DID_OPEN, // textDocument/didOpen
@@ -201,6 +198,11 @@ typedef struct {
} LSPRequestDidChangeWorkspaceFolders;
typedef struct {
+ // this string should be valid JSON. will be freed.
+ char *settings;
+} LSPRequestConfiguration;
+
+typedef struct {
LSPRequestID id;
LSPRequestType type;
char *id_string; // if not NULL, this is the ID (only for server-to-client messages; we always use integer IDs)
@@ -210,6 +212,7 @@ typedef struct {
LSPRequestDidOpen open;
LSPRequestDidClose close;
LSPRequestDidChange change;
+ LSPRequestConfiguration configuration;
LSPRequestCompletion completion;
LSPRequestSignatureHelp signature_help;
LSPRequestHover hover;
@@ -548,6 +551,9 @@ typedef struct LSP {
bool initialized;
// thread-safety: only set once in lsp_create.
char *command;
+ // this is set in lsp_create, then later set to NULL when we send over the configuration (after the initialized notification).
+ // thread-safety: set once in lsp_create, then only acessed once in communication thread.
+ char *configuration_to_send;
LSPThread communication_thread;
LSPSemaphore quit_sem;
// thread-safety: only accessed in communication thread
@@ -587,7 +593,7 @@ void lsp_cancel_request(LSP *lsp, LSPRequestID id);
// don't free the contents of this response! let me handle it!
void lsp_send_response(LSP *lsp, LSPResponse *response);
const char *lsp_response_string(const LSPResponse *response, LSPString string);
-LSP *lsp_create(const char *root_dir, const char *analyzer_command);
+LSP *lsp_create(const char *root_dir, const char *analyzer_command, const char *configuration);
// try to add a new "workspace folder" to the lsp.
// IMPORTANT: only call this if lsp->initialized is true
// (if not we don't yet know whether the server supports workspace folders)
diff --git a/main.c b/main.c
index 87c76c6..f9f2014 100644
--- a/main.c
+++ b/main.c
@@ -1,7 +1,6 @@
/*
@TODO:
- LSP configuration in ted.cfg
- - remove LSP_REQUEST_JDTLS_CONFIGURATION
- disable publishDiagnostics for rust-analyzer (& others)?
- phantom completions
- debug-lsp option (which logs LSP messages)
diff --git a/ted.c b/ted.c
index c718dc2..4a76cd7 100644
--- a/ted.c
+++ b/ted.c
@@ -192,7 +192,7 @@ LSP *ted_get_lsp(Ted *ted, const char *path, Language language) {
if (*settings->lsp) {
// start up this LSP
char *root_dir = settings_get_root_dir(settings, path);
- ted->lsps[i] = lsp_create(root_dir, settings->lsp);
+ ted->lsps[i] = lsp_create(root_dir, settings->lsp, settings->lsp_configuration);
free(root_dir);
// don't actually return it yet, since it's still initializing (see above)
}
diff --git a/ted.cfg b/ted.cfg
index 1841542..521aaab 100644
--- a/ted.cfg
+++ b/ted.cfg
@@ -110,6 +110,14 @@ lsp = "gopls"
[Java.core]
lsp = "jdtls"
+# by default, jdtls doesn't give signature help
+lsp-configuration = `{
+ "java": {
+ "signatureHelp": {
+ "enabled": true
+ }
+ }
+}`
[JavaScript.core]
lsp = "typescript-language-server --stdio"
diff --git a/ted.h b/ted.h
index 1bc3fce..c42fd69 100644
--- a/ted.h
+++ b/ted.h
@@ -144,6 +144,7 @@ typedef struct {
char bg_shader_image[TED_PATH_MAX];
char root_identifiers[4096];
char lsp[512];
+ char lsp_configuration[4096];
char build_default_command[256];
// [i] = comma-separated string of file extensions for language i, or NULL for none
char *language_extensions[LANG_COUNT];