From 53451f331667180e4b30c1ac0bf33bb48beb37f0 Mon Sep 17 00:00:00 2001 From: pommicket Date: Tue, 27 Dec 2022 00:34:38 -0500 Subject: better workspaceFolders idea ("withhold judgement") --- lsp.c | 19 ++++++------------- lsp.h | 4 +++- main.c | 7 +++++++ ted.c | 7 +++++++ 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/lsp.c b/lsp.c index e5bec71..a3e07e7 100644 --- a/lsp.c +++ b/lsp.c @@ -357,21 +357,14 @@ LSP *lsp_create(const char *root_dir, Language language, const char *analyzer_co } bool lsp_try_add_root_dir(LSP *lsp, const char *new_root_dir) { + assert(lsp->initialized); + bool got_it = false; SDL_LockMutex(lsp->workspace_folders_mutex); - if (!lsp->initialized) { - // pretend we have workspace folder support until we get initialize response - // (it's totally possible that this would be called with lsp->initialized = false, - // e.g. if the user starts up ted with multiple files in different projects) - // we'll fix things up when we get the initialize response if there's no actual support. - arr_add(lsp->workspace_folders, lsp_document_id(lsp, new_root_dir)); - got_it = true; - } else { - arr_foreach_ptr(lsp->workspace_folders, LSPDocumentID, folder) { - if (str_has_path_prefix(new_root_dir, lsp_document_path(lsp, *folder))) { - got_it = true; - break; - } + arr_foreach_ptr(lsp->workspace_folders, LSPDocumentID, folder) { + if (str_has_path_prefix(new_root_dir, lsp_document_path(lsp, *folder))) { + got_it = true; + break; } } SDL_UnlockMutex(lsp->workspace_folders_mutex); diff --git a/lsp.h b/lsp.h index b931b5c..e0595e2 100644 --- a/lsp.h +++ b/lsp.h @@ -296,7 +296,7 @@ typedef struct LSP { SDL_mutex *error_mutex; Language language; SDL_mutex *workspace_folders_mutex; - LSPDocumentID *workspace_folders; // dynamic array of root directories of LSP "workspaces" (meaningless garbage) + LSPDocumentID *workspace_folders; // dynamic array of root directories of LSP workspace folders char error[256]; } LSP; @@ -316,6 +316,8 @@ 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, Language language, const char *analyzer_command); // 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) // returns true on success or if new_root_dir is already contained in a workspace folder for this LSP. // if this fails (i.e. if the LSP does not have workspace support), create a new LSP // with root directory `new_root_dir`. diff --git a/main.c b/main.c index d514132..e82d539 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,10 @@ /* @TODO: +- LSP IDs, and make buffer send (didClose +) didOpen if its ID isn't maching up + (this should fix current "unexpected didChange" multi-root rust-analyzer problem and + also fix "save as") +- lsp_document_id / lsp_document_path thread-safety +- double check thread safety of other things - ignore telemetry/event - https://github.com/typescript-language-server/typescript-language-server - NOTE: This supports javascript. @@ -17,6 +22,8 @@ - workspaceFolders support (so we don't need to start up multiple instances of rust-analyzer) - document lsp.h and lsp.c. - maximum queue size for requests/responses just in case? + - idea: configurable timeout + - what to do if initialize request takes a long time? - delete old sent requests? but make sure requests that just take a long time are okay. (if the server never sends a response) - TESTING: make rust-analyzer-slow (waits 10s before sending response) diff --git a/ted.c b/ted.c index 8e2f669..825ab36 100644 --- a/ted.c +++ b/ted.c @@ -114,6 +114,13 @@ LSP *ted_get_lsp(Ted *ted, const char *path, Language language) { if (!lsp) break; if (lsp->language != language) continue; + if (!lsp->initialized) { + // withhold judgement until this server initializes. + // we shouldn't call lsp_try_add_root_dir yet because it doesn't know + // if the server supports workspaceFolders. + return NULL; + } + // check if root matches up or if we can add a workspace folder char *root = ted_get_root_dir_of(ted, path); bool success = lsp_try_add_root_dir(lsp, root); -- cgit v1.2.3