summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-12-26 20:41:43 -0500
committerpommicket <pommicket@gmail.com>2022-12-26 20:41:43 -0500
commit9a5cad47fe6a8b84892f62e110ca887c95df5eff (patch)
tree48f5bcdf4d36d11716d233e98f52d1a9cb583143
parent44d607df5d5a9a1c892fe56c4874fbef7f209464 (diff)
workspace/workspaceFolders request
-rw-r--r--lsp-parse.c6
-rw-r--r--lsp-write.c50
-rw-r--r--lsp.c68
-rw-r--r--lsp.h6
-rw-r--r--main.c5
5 files changed, 87 insertions, 48 deletions
diff --git a/lsp-parse.c b/lsp-parse.c
index de63401..6d436d9 100644
--- a/lsp-parse.c
+++ b/lsp-parse.c
@@ -370,6 +370,7 @@ static void process_message(LSP *lsp, JSON *json) {
JSONValue result = json_get(json, "result");
if (result.type != JSON_UNDEFINED) {
+ // server-to-client response
LSPResponse response = {0};
bool add_to_messages = false;
response.request = response_to;
@@ -405,7 +406,7 @@ static void process_message(LSP *lsp, JSON *json) {
}
if (add_to_messages) {
SDL_LockMutex(lsp->messages_mutex);
- LSPMessage *message = arr_addp(lsp->messages);
+ LSPMessage *message = arr_addp(lsp->messages_server2client);
message->type = LSP_RESPONSE;
message->u.response = response;
SDL_UnlockMutex(lsp->messages_mutex);
@@ -414,10 +415,11 @@ static void process_message(LSP *lsp, JSON *json) {
lsp_response_free(&response);
}
} else if (json_has(json, "method")) {
+ // server-to-client request
LSPRequest request = {0};
if (parse_server2client_request(lsp, json, &request)) {
SDL_LockMutex(lsp->messages_mutex);
- LSPMessage *message = arr_addp(lsp->messages);
+ LSPMessage *message = arr_addp(lsp->messages_server2client);
message->type = LSP_REQUEST;
message->u.request = request;
SDL_UnlockMutex(lsp->messages_mutex);
diff --git a/lsp-write.c b/lsp-write.c
index ef60b91..5d402c4 100644
--- a/lsp-write.c
+++ b/lsp-write.c
@@ -463,9 +463,9 @@ static void write_request(LSP *lsp, LSPRequest *request) {
if (is_notification) {
lsp_request_free(request);
} else {
- SDL_LockMutex(lsp->requests_mutex);
+ SDL_LockMutex(lsp->messages_mutex);
arr_add(lsp->requests_sent, *request);
- SDL_UnlockMutex(lsp->requests_mutex);
+ SDL_UnlockMutex(lsp->messages_mutex);
}
}
@@ -477,24 +477,38 @@ static void write_response(LSP *lsp, LSPResponse *response) {
JSONWriter *o = &writer;
LSPRequest *request = &response->request;
- if (request->id_string)
- write_key_string(o, "id", request->id_string);
- else
- write_key_number(o, "id", request->id);
- write_key_obj_start(o, "result");
-
- switch (response->request.type) {
- case LSP_REQUEST_WORKSPACE_FOLDERS:
- write_workspace_folders(o, lsp->workspace_folders);
- break;
- default:
- // this is not a valid client-to-server response.
- assert(0);
- break;
- }
+ write_obj_start(o);
+ if (request->id_string)
+ write_key_string(o, "id", request->id_string);
+ else
+ write_key_number(o, "id", request->id);
+ write_key_string(o, "jsonrpc", "2.0");
+ write_key(o, "result");
+ switch (response->request.type) {
+ case LSP_REQUEST_WORKSPACE_FOLDERS:
+ write_workspace_folders(o, lsp->workspace_folders);
+ break;
+ default:
+ // this is not a valid client-to-server response.
+ assert(0);
+ break;
+ }
write_obj_end(o);
message_writer_write_and_free(lsp, o);
-
lsp_response_free(response);
}
+
+static void write_message(LSP *lsp, LSPMessage *message) {
+ switch (message->type) {
+ case LSP_REQUEST:
+ write_request(lsp, &message->u.request);
+ break;
+ case LSP_RESPONSE:
+ write_response(lsp, &message->u.response);
+ break;
+ }
+ // it's okay to free the message here since the request/response part has been zeroed.
+ // (as i'm writing this, this won't do anything but it might in the future)
+ lsp_message_free(message);
+}
diff --git a/lsp.c b/lsp.c
index 4267fd3..0c9aede 100644
--- a/lsp.c
+++ b/lsp.c
@@ -130,14 +130,26 @@ static bool lsp_supports_request(LSP *lsp, const LSPRequest *request) {
return false;
}
+void lsp_send_message(LSP *lsp, LSPMessage *message) {
+ SDL_LockMutex(lsp->messages_mutex);
+ arr_add(lsp->messages_client2server, *message);
+ SDL_UnlockMutex(lsp->messages_mutex);
+}
+
void lsp_send_request(LSP *lsp, LSPRequest *request) {
if (!lsp_supports_request(lsp, request)) {
lsp_request_free(request);
return;
}
- SDL_LockMutex(lsp->requests_mutex);
- arr_add(lsp->requests_client2server, *request);
- SDL_UnlockMutex(lsp->requests_mutex);
+ LSPMessage message = {.type = LSP_REQUEST};
+ message.u.request = *request;
+ lsp_send_message(lsp, &message);
+}
+
+void lsp_send_response(LSP *lsp, LSPResponse *response) {
+ LSPMessage message = {.type = LSP_RESPONSE};
+ message.u.response = *response;
+ lsp_send_message(lsp, &message);
}
const char *lsp_response_string(const LSPResponse *response, LSPString string) {
@@ -215,21 +227,21 @@ static bool lsp_send(LSP *lsp) {
return false;
}
- LSPRequest *requests = NULL;
- SDL_LockMutex(lsp->requests_mutex);
- size_t n_requests = arr_len(lsp->requests_client2server);
- requests = calloc(n_requests, sizeof *requests);
- memcpy(requests, lsp->requests_client2server, n_requests * sizeof *requests);
- arr_clear(lsp->requests_client2server);
- SDL_UnlockMutex(lsp->requests_mutex);
+ LSPMessage *messages = NULL;
+ SDL_LockMutex(lsp->messages_mutex);
+ size_t n_messages = arr_len(lsp->messages_client2server);
+ messages = calloc(n_messages, sizeof *messages);
+ memcpy(messages, lsp->messages_client2server, n_messages * sizeof *messages);
+ arr_clear(lsp->messages_client2server);
+ SDL_UnlockMutex(lsp->messages_mutex);
bool quit = false;
- for (size_t i = 0; i < n_requests; ++i) {
- LSPRequest *r = &requests[i];
+ for (size_t i = 0; i < n_messages; ++i) {
+ LSPMessage *m = &messages[i];
if (quit) {
- lsp_request_free(r);
+ lsp_message_free(m);
} else {
- write_request(lsp, r);
+ write_message(lsp, m);
}
if (SDL_SemTryWait(lsp->quit_sem) == 0) {
@@ -237,7 +249,7 @@ static bool lsp_send(LSP *lsp) {
}
}
- free(requests);
+ free(messages);
return quit;
}
@@ -315,7 +327,6 @@ LSP *lsp_create(const char *root_dir, Language language, const char *analyzer_co
lsp->language = language;
lsp->quit_sem = SDL_CreateSemaphore(0);
lsp->messages_mutex = SDL_CreateMutex();
- lsp->requests_mutex = SDL_CreateMutex();
ProcessSettings settings = {
.stdin_blocking = true,
@@ -338,9 +349,9 @@ LSP *lsp_create(const char *root_dir, Language language, const char *analyzer_co
bool lsp_next_message(LSP *lsp, LSPMessage *message) {
bool any = false;
SDL_LockMutex(lsp->messages_mutex);
- if (arr_len(lsp->messages)) {
- *message = lsp->messages[0];
- arr_remove(lsp->messages, 0);
+ if (arr_len(lsp->messages_server2client)) {
+ *message = lsp->messages_server2client[0];
+ arr_remove(lsp->messages_server2client, 0);
any = true;
}
SDL_UnlockMutex(lsp->messages_mutex);
@@ -351,21 +362,32 @@ void lsp_free(LSP *lsp) {
SDL_SemPost(lsp->quit_sem);
SDL_WaitThread(lsp->communication_thread, NULL);
SDL_DestroyMutex(lsp->messages_mutex);
- SDL_DestroyMutex(lsp->requests_mutex);
SDL_DestroySemaphore(lsp->quit_sem);
process_kill(&lsp->process);
+
arr_free(lsp->received_data);
+
str_hash_table_clear(&lsp->document_ids);
for (size_t i = 0; i < arr_len(lsp->document_data); ++i)
free(lsp->document_data[i].path);
arr_free(lsp->document_data);
- arr_foreach_ptr(lsp->messages, LSPMessage, message) {
+
+ arr_foreach_ptr(lsp->messages_server2client, LSPMessage, message)
lsp_message_free(message);
- }
+ arr_free(lsp->messages_server2client);
+
+ arr_foreach_ptr(lsp->messages_client2server, LSPMessage, message)
+ lsp_message_free(message);
+ arr_free(lsp->messages_client2server);
+
+ arr_foreach_ptr(lsp->requests_sent, LSPRequest, r)
+ lsp_request_free(r);
+ arr_free(lsp->requests_sent);
+
arr_foreach_ptr(lsp->workspace_folders, char *, folder)
free(*folder);
arr_free(lsp->workspace_folders);
- arr_free(lsp->messages);
+
arr_free(lsp->trigger_chars);
memset(lsp, 0, sizeof *lsp);
free(lsp);
diff --git a/lsp.h b/lsp.h
index 666ff1b..85993cb 100644
--- a/lsp.h
+++ b/lsp.h
@@ -259,15 +259,13 @@ typedef struct LSP {
// this is a dynamic array which just keeps growing.
// but the user isn't gonna open millions of files so it's fine.
LSPDocumentData *document_data;
- LSPMessage *messages;
SDL_mutex *messages_mutex;
- LSPRequest *requests_client2server;
- LSPRequest *requests_server2client;
+ LSPMessage *messages_server2client;
+ LSPMessage *messages_client2server;
// we keep track of client-to-server requests
// so that we can process responses.
// this also lets us re-send requests if that's ever necessary.
LSPRequest *requests_sent;
- SDL_mutex *requests_mutex;
bool initialized; // has the response to the initialize request been sent?
SDL_Thread *communication_thread;
SDL_sem *quit_sem;
diff --git a/main.c b/main.c
index 7fdb6de..9339b95 100644
--- a/main.c
+++ b/main.c
@@ -1,9 +1,9 @@
/*
@TODO:
-- what's wrong with gopls?
- ignore telemetry/event
- handle window/showMessageRequest
- make sure "save as" works
+- what's wrong with gopls?
- more LSP stuff:
- hover
- go to definition using LSP
@@ -17,6 +17,8 @@
- run everything through valgrind ideally with leak checking
- grep -i -n TODO *.[ch]
--- LSP MERGE ---
+- improve structure of ted source code to make LSP completions better
+ (make every c file a valid translation unit)
- rename buffer->filename to buffer->path
- make buffer->path NULL for untitled buffers & fix resulting mess
- rust-analyzer bug reports:
@@ -1083,6 +1085,7 @@ int main(int argc, char **argv) {
SDL_SetWindowTitle(window, ted->window_title);
SDL_SetCursor(ted->cursor);
+
// annoyingly, SDL_GL_SwapWindow seems to be a busy loop on my laptop for some reason...
// enforce a framerate of 60. this isn't ideal but SDL_GetDisplayMode is *extremely slow* (250ms), so we don't really have a choice.
int refresh_rate = 60;