diff options
-rw-r--r-- | config.c | 1 | ||||
-rw-r--r-- | lsp-write.c | 25 | ||||
-rw-r--r-- | lsp.c | 18 | ||||
-rw-r--r-- | lsp.h | 19 | ||||
-rw-r--r-- | main.c | 1 | ||||
-rw-r--r-- | ted.cfg | 2 | ||||
-rw-r--r-- | ted.h | 1 |
7 files changed, 44 insertions, 23 deletions
@@ -249,6 +249,7 @@ static OptionBool const options_bool[] = { {"restore-session", &options_zero.restore_session, false}, {"regenerate-tags-if-not-found", &options_zero.regenerate_tags_if_not_found, true}, {"indent-with-spaces", &options_zero.indent_with_spaces, true}, + {"trigger-characters", &options_zero.trigger_characters, true}, }; static OptionU8 const options_u8[] = { {"tab-width", &options_zero.tab_width, 1, 100, true}, diff --git a/lsp-write.c b/lsp-write.c index 4a56543..87cb238 100644 --- a/lsp-write.c +++ b/lsp-write.c @@ -167,14 +167,19 @@ static void write_arr_elem_string(JSONWriter *o, const char *s) { write_string(o, s); } -static void write_file_uri(JSONWriter *o, DocumentID document) { - const char *path = o->lsp->document_paths[document]; +static void write_file_uri(JSONWriter *o, LSPDocumentID document) { + if (document >= arr_len(o->lsp->document_data)) { + assert(0); + str_builder_append(&o->builder, "\"\""); + return; + } + const char *path = o->lsp->document_data[document].path; str_builder_append(&o->builder, "\"file:///"); write_escaped(o, path); str_builder_append(&o->builder, "\""); } -static void write_key_file_uri(JSONWriter *o, const char *key, DocumentID document) { +static void write_key_file_uri(JSONWriter *o, const char *key, LSPDocumentID document) { write_key(o, key); write_file_uri(o, document); } @@ -251,6 +256,8 @@ static bool request_type_is_notification(LSPRequestType type) { return false; } +// NOTE: don't call lsp_request_free after calling this function. +// I will do it for you. static void write_request(LSP *lsp, LSPRequest *request) { JSONWriter writer = json_writer_new(lsp); JSONWriter *o = &writer; @@ -332,7 +339,7 @@ static void write_request(LSP *lsp, LSPRequest *request) { write_key_obj_start(o, "textDocument"); write_key_file_uri(o, "uri", open->document); write_key_string(o, "languageId", lsp_language_id(open->language)); - write_key_number(o, "version", 1); + write_key_number(o, "version", 0); write_key_string(o, "text", open->file_contents); write_obj_end(o); write_obj_end(o); @@ -347,11 +354,15 @@ static void write_request(LSP *lsp, LSPRequest *request) { } break; case LSP_REQUEST_DID_CHANGE: { LSPRequestDidChange *change = &request->data.change; - static unsigned long long version_number = 1; // @TODO @TEMPORARY - ++version_number; + if (change->document >= arr_len(lsp->document_data)) { + assert(0); + break; + } + LSPDocumentData *document = &lsp->document_data[change->document]; + ++document->version_number; write_key_obj_start(o, "params"); write_key_obj_start(o, "textDocument"); - write_key_number(o, "version", (double)version_number); + write_key_number(o, "version", (double)document->version_number); write_key_file_uri(o, "uri", change->document); write_obj_end(o); write_key_arr_start(o, "contentChanges"); @@ -189,15 +189,14 @@ static bool lsp_send(LSP *lsp) { bool quit = false; for (size_t i = 0; i < n_requests; ++i) { LSPRequest *r = &requests[i]; - if (!quit) { - // this could slow down lsp_free if there's a gigantic request. - // whatever. + if (quit) { + lsp_request_free(r); + } else { write_request(lsp, r); } if (SDL_SemTryWait(lsp->quit_sem) == 0) { quit = true; - // important that we don't break here so all the requests get freed. } } @@ -256,10 +255,11 @@ static int lsp_communication_thread(void *data) { u32 lsp_document_id(LSP *lsp, const char *path) { u32 *value = str_hash_table_get(&lsp->document_ids, path); if (!value) { - u32 id = arr_len(lsp->document_paths); + u32 id = arr_len(lsp->document_data); value = str_hash_table_insert(&lsp->document_ids, path); *value = id; - arr_add(lsp->document_paths, str_dup(path)); + LSPDocumentData *data = arr_addp(lsp->document_data); + data->path = str_dup(path); } return *value; } @@ -308,9 +308,9 @@ void lsp_free(LSP *lsp) { 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_paths); ++i) - free(lsp->document_paths[i]); - arr_clear(lsp->document_paths); + 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) { lsp_message_free(message); } @@ -7,7 +7,7 @@ // (if the server never sends a response) // - TESTING: make rust-analyzer-slow (waits 10s before sending response) -typedef u32 DocumentID; +typedef u32 LSPDocumentID; typedef enum { LSP_REQUEST, @@ -49,13 +49,13 @@ typedef enum { typedef struct { Language language; - DocumentID document; + LSPDocumentID document; // freed by lsp_request_free char *file_contents; } LSPRequestDidOpen; typedef struct { - DocumentID document; + LSPDocumentID document; } LSPRequestDidClose; // see TextDocumentContentChangeEvent in the LSP spec @@ -66,7 +66,7 @@ typedef struct { } LSPDocumentChangeEvent; typedef struct { - DocumentID document; + LSPDocumentID document; LSPDocumentChangeEvent *changes; // dynamic array } LSPRequestDidChange; @@ -84,7 +84,7 @@ typedef struct { } LSPRequestMessage; typedef struct { - DocumentID document; + LSPDocumentID document; LSPPosition pos; } LSPDocumentPosition; @@ -240,13 +240,18 @@ typedef struct { } u; } LSPMessage; +typedef struct { + char *path; + u32 version_number; // for LSP +} LSPDocumentData; + typedef struct LSP { Process process; u32 request_id; - StrHashTable document_ids; // values are u32. they are indices into document_filenames. + StrHashTable document_ids; // values are u32. they are indices into document_data. // this is a dynamic array which just keeps growing. // but the user isn't gonna open millions of files so it's fine. - char **document_paths; + LSPDocumentData *document_data; LSPMessage *messages; SDL_mutex *messages_mutex; LSPRequest *requests_client2server; @@ -4,6 +4,7 @@ - scroll through completions - only show "Loading..." if it's taking some time (prevent flash) - LSP setting +- figure out workspace - make sure "save as" works - rename buffer->filename to buffer->path - make buffer->path NULL for untitled buffers & fix resulting mess @@ -29,6 +29,8 @@ auto-reload-config = on build-default-command = make # restore previously opened files when ted is launched? restore-session = on +# show autocomplete menu when a trigger character (e.g. '.') is typed (LSP only) +trigger-characters = on # search depth for files to generate tags for. # if set to 0, tag generation/regeneration will do nothing @@ -183,6 +183,7 @@ typedef struct { bool restore_session; bool regenerate_tags_if_not_found; bool indent_with_spaces; + bool trigger_characters; u8 tab_width; u8 cursor_width; u8 undo_save_time; |