summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.c1
-rw-r--r--lsp-write.c25
-rw-r--r--lsp.c18
-rw-r--r--lsp.h19
-rw-r--r--main.c1
-rw-r--r--ted.cfg2
-rw-r--r--ted.h1
7 files changed, 44 insertions, 23 deletions
diff --git a/config.c b/config.c
index c3e316a..5f60b05 100644
--- a/config.c
+++ b/config.c
@@ -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");
diff --git a/lsp.c b/lsp.c
index c6b0215..fedc085 100644
--- a/lsp.c
+++ b/lsp.c
@@ -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);
}
diff --git a/lsp.h b/lsp.h
index 72e621e..cee1505 100644
--- a/lsp.h
+++ b/lsp.h
@@ -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;
diff --git a/main.c b/main.c
index 147f4b1..f9f8605 100644
--- a/main.c
+++ b/main.c
@@ -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
diff --git a/ted.cfg b/ted.cfg
index 0e823bd..12ff922 100644
--- a/ted.cfg
+++ b/ted.cfg
@@ -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
diff --git a/ted.h b/ted.h
index a7974dd..547197c 100644
--- a/ted.h
+++ b/ted.h
@@ -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;