From 2d32df18e83b059834ae65904e6439c72372454b Mon Sep 17 00:00:00 2001 From: pommicket Date: Fri, 6 Jan 2023 12:02:11 -0500 Subject: lsp-log setting --- config.c | 1 + lsp-write.c | 17 ++++++++--------- lsp.c | 13 ++++++++----- lsp.h | 7 ++++++- main.c | 2 +- ted.c | 3 ++- ted.cfg | 3 +++ ted.h | 1 + 8 files changed, 30 insertions(+), 17 deletions(-) diff --git a/config.c b/config.c index 3fc3183..b8f0f17 100644 --- a/config.c +++ b/config.c @@ -85,6 +85,7 @@ static SettingBool const settings_bool[] = { {"phantom-completions", &settings_zero.phantom_completions, true}, {"signature-help-enabled", &settings_zero.signature_help_enabled, true}, {"lsp-enabled", &settings_zero.lsp_enabled, true}, + {"lsp-log", &settings_zero.lsp_log, true}, {"hover-enabled", &settings_zero.hover_enabled, true}, {"vsync", &settings_zero.vsync, false}, {"highlight-enabled", &settings_zero.highlight_enabled, true}, diff --git a/lsp-write.c b/lsp-write.c index 56f8e7d..df31d47 100644 --- a/lsp-write.c +++ b/lsp-write.c @@ -318,19 +318,18 @@ static void message_writer_write_and_free(LSP *lsp, JSONWriter *o) { // this is kind of hacky but it lets us send the whole request with one write call. // probably not *actually* needed. i thought it would help fix an error but it didn't. size_t content_length = str_builder_len(&builder) - max_header_size; - char content_length_str[32]; - sprintf(content_length_str, "%zu", content_length); - size_t header_size = strlen("Content-Length: \r\n\r\n") + strlen(content_length_str); - char *header = &builder.str[max_header_size - header_size]; - strcpy(header, "Content-Length: "); - strcat(header, content_length_str); - // we specifically DON'T want a null byte - memcpy(header + strlen(header), "\r\n\r\n", 4); + char header_str[64]; + sprintf(header_str, "Content-Length: %zu\r\n\r\n", content_length); + size_t header_size = strlen(header_str); + char *content = &builder.str[max_header_size - header_size]; + memcpy(content, header_str, header_size); - char *content = header; #if LSP_SHOW_C2S printf("%s%s%s\n",term_bold(stdout),content,term_clear(stdout)); #endif + if (lsp->log) { + fprintf(lsp->log, "MESSAGE FROM CLIENT TO SERVER\n%s\n\n", content + header_size); + } process_write(lsp->process, content, strlen(content)); diff --git a/lsp.c b/lsp.c index f721efd..2c9b680 100644 --- a/lsp.c +++ b/lsp.c @@ -308,6 +308,9 @@ static void lsp_receive(LSP *lsp, size_t max_size) { } char *copy = strn_dup(lsp->received_data + response_offset, response_size); + if (lsp->log) { + + } JSON json = {0}; if (json_parse(&json, copy)) { assert(json.text == copy); @@ -453,7 +456,7 @@ const char *lsp_document_path(LSP *lsp, LSPDocumentID document) { return path; } -LSP *lsp_create(const char *root_dir, const char *analyzer_command, const char *configuration) { +LSP *lsp_create(const char *root_dir, const char *command, const char *configuration, FILE *log) { LSP *lsp = calloc(1, sizeof *lsp); if (!lsp) return NULL; @@ -462,15 +465,15 @@ LSP *lsp_create(const char *root_dir, const char *analyzer_command, const char * static LSPID curr_id = 1; lsp->id = curr_id++; - + lsp->log = log; #if DEBUG printf("Starting up LSP %p `%s` in %s\n", - (void *)lsp, analyzer_command, root_dir); + (void *)lsp, command, root_dir); #endif str_hash_table_create(&lsp->document_ids, sizeof(u32)); - lsp->command = str_dup(analyzer_command); + lsp->command = str_dup(command); if (configuration && *configuration) lsp->configuration_to_send = str_dup(configuration); lsp->quit_sem = SDL_CreateSemaphore(0); @@ -486,7 +489,7 @@ LSP *lsp_create(const char *root_dir, const char *analyzer_command, const char * .separate_stderr = true, .working_directory = root_dir, }; - lsp->process = process_run_ex(analyzer_command, &settings); + lsp->process = process_run_ex(command, &settings); LSPRequest initialize = { .type = LSP_REQUEST_INITIALIZE }; diff --git a/lsp.h b/lsp.h index b501da1..b87f2a9 100644 --- a/lsp.h +++ b/lsp.h @@ -527,6 +527,9 @@ typedef struct LSP { // thread-safety: only set once in lsp_create. LSPID id; + // thread-safety: set once in lsp_create, then only used by communication thread + FILE *log; + // The server process // thread-safety: created in lsp_create, then only accessed by the communication thread Process *process; @@ -593,7 +596,9 @@ 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, const char *configuration); +// Start up an LSP server. +// configuration and log can be NULL. +LSP *lsp_create(const char *root_dir, const char *command, const char *configuration, FILE *log); // 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 3975adc..a0bc3b6 100644 --- a/main.c +++ b/main.c @@ -1,9 +1,9 @@ /* @TODO: -- debug-lsp option (which logs LSP messages) - check LSP process status (TEST: what happens if LSP server is not installed) - make tags_dir the root folder - check that tags still works + - check that phantom completions works with tags - do we need higher than 1-second resolution in time_last_modified on windows? - TESTING: make rust-analyzer-slow (waits 10s before sending response) - TESTING: check all IDE features with different servers diff --git a/ted.c b/ted.c index 4a76cd7..ae1908b 100644 --- a/ted.c +++ b/ted.c @@ -191,8 +191,9 @@ LSP *ted_get_lsp(Ted *ted, const char *path, Language language) { return NULL; // why are there so many LSP open??? if (*settings->lsp) { // start up this LSP + FILE *log = settings->lsp_log ? ted->log : NULL; char *root_dir = settings_get_root_dir(settings, path); - ted->lsps[i] = lsp_create(root_dir, settings->lsp, settings->lsp_configuration); + ted->lsps[i] = lsp_create(root_dir, settings->lsp, settings->lsp_configuration, log); 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 220de0a..94e528d 100644 --- a/ted.cfg +++ b/ted.cfg @@ -38,6 +38,9 @@ phantom-completions = on # enable LSP support (for autocompletion, etc.) # you can also set `lsp = ""` but this is a quick way to disable LSP servers for all langauges lsp-enabled = yes +# enable this to log all messages between ted and the LSP server +# (may require restarting ted to update) +lsp-log = no # display function signature help? (only with LSP running) # this is the thing at the bottom of ted which shows the parameters to the function you're calling signature-help-enabled = yes diff --git a/ted.h b/ted.h index a3104e8..270adff 100644 --- a/ted.h +++ b/ted.h @@ -128,6 +128,7 @@ typedef struct { bool identifier_trigger_characters; bool signature_help_enabled; bool lsp_enabled; + bool lsp_log; bool hover_enabled; bool highlight_enabled; bool highlight_auto; -- cgit v1.2.3