summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-12-31 12:12:07 -0500
committerpommicket <pommicket@gmail.com>2022-12-31 12:12:07 -0500
commitb45acfb66cd4c4474d3fd951d2a1b0fe3b63ae0b (patch)
tree61209fe68bd406e26e4f356043c7836668b8cd5b
parent02faedf9bf7e826bc78161f8cf07ffca5d2dbe57 (diff)
better LSP request cancelling
-rw-r--r--ide-autocomplete.c29
-rw-r--r--ide-definitions.c7
-rw-r--r--ide-usages.c3
-rw-r--r--main.c3
-rw-r--r--ted.h5
5 files changed, 27 insertions, 20 deletions
diff --git a/ide-autocomplete.c b/ide-autocomplete.c
index e5dd848..76871af 100644
--- a/ide-autocomplete.c
+++ b/ide-autocomplete.c
@@ -76,8 +76,9 @@ void autocomplete_close(Ted *ted) {
Autocomplete *ac = &ted->autocomplete;
if (ac->open) {
ac->open = false;
- ac->waiting_for_lsp = false;
autocomplete_clear_completions(ted);
+ ted_cancel_lsp_request(ted, ac->last_request_lsp, ac->last_request_id);
+ ac->last_request_id = 0;
}
}
@@ -110,6 +111,8 @@ static void autocomplete_send_completion_request(Ted *ted, TextBuffer *buffer, B
LSP *lsp = buffer_lsp(buffer);
Autocomplete *ac = &ted->autocomplete;
+ ted_cancel_lsp_request(ted, ac->last_request_lsp, ac->last_request_id);
+
LSPRequest request = {
.type = LSP_REQUEST_COMPLETION
};
@@ -132,9 +135,10 @@ static void autocomplete_send_completion_request(Ted *ted, TextBuffer *buffer, B
};
if (trigger < UNICODE_CODE_POINTS)
unicode_utf32_to_utf8(request.data.completion.context.trigger_character, trigger);
- if (lsp_send_request(lsp, &request)) {
- ac->waiting_for_lsp = true;
- ac->lsp_request_time = ted->frame_time;
+ ac->last_request_id = lsp_send_request(lsp, &request);
+ if (ac->last_request_id) {
+ ac->last_request_lsp = lsp->id;
+ ac->last_request_time = ted->frame_time;
// *technically sepaking* this can mess things up if a complete
// list arrives only after the user has typed some stuff
// (in that case we'll send a TriggerKind = incomplete request even though it makes no sense).
@@ -238,14 +242,14 @@ static void autocomplete_process_lsp_response(Ted *ted, const LSPResponse *respo
const LSPRequest *request = &response->request;
if (request->type != LSP_REQUEST_COMPLETION)
return;
-
Autocomplete *ac = &ted->autocomplete;
- ac->waiting_for_lsp = false;
+ if (request->id != ac->last_request_id)
+ return; // old request
+ ac->last_request_id = 0;
if (!ac->open) {
// user hit escape or down or something before completions arrived.
return;
}
-
const LSPResponseCompletion *completion = &response->data.completion;
size_t ncompletions = arr_len(completion->items);
@@ -350,16 +354,17 @@ static void autocomplete_frame(Ted *ted) {
autocomplete_find_completions(ted, TRIGGER_INCOMPLETE);
size_t ncompletions = arr_len(ac->suggested);
+ bool waiting_for_lsp = ac->last_request_id != 0;
- if (ac->waiting_for_lsp && ncompletions == 0) {
+ if (waiting_for_lsp && ncompletions == 0) {
double now = ted->frame_time;
- if (now - ac->lsp_request_time < 0.2) {
+ if (now - ac->last_request_time < 0.2) {
// don't show "Loading..." unless we've actually been loading for a bit of time
return;
}
}
- if (!ac->waiting_for_lsp && ncompletions == 0) {
+ if (!waiting_for_lsp && ncompletions == 0) {
// no completions. close menu.
autocomplete_close(ted);
return;
@@ -373,7 +378,7 @@ static void autocomplete_frame(Ted *ted) {
float menu_width = 400, menu_height = (float)ncompletions_visible * char_height;
- if (ac->waiting_for_lsp && ncompletions == 0) {
+ if (waiting_for_lsp && ncompletions == 0) {
menu_height = 200.f;
}
@@ -468,7 +473,7 @@ static void autocomplete_frame(Ted *ted) {
state.min_x = x + padding; state.min_y = y; state.max_x = x + menu_width - padding; state.max_y = y + menu_height;
rgba_u32_to_floats(colors[COLOR_TEXT], state.color);
- if (ac->waiting_for_lsp && ncompletions == 0) {
+ if (waiting_for_lsp && ncompletions == 0) {
state.x = x + padding; state.y = y;
text_utf8_with_state(font, &state, "Loading...");
} else {
diff --git a/ide-definitions.c b/ide-definitions.c
index 46dc1f4..6ea0547 100644
--- a/ide-definitions.c
+++ b/ide-definitions.c
@@ -1,6 +1,6 @@
void definition_cancel_lookup(Ted *ted) {
Definitions *defs = &ted->definitions;
- lsp_cancel_request(ted_get_lsp_by_id(ted, defs->last_request_lsp), defs->last_request_id);
+ ted_cancel_lsp_request(ted, defs->last_request_lsp, defs->last_request_id);
defs->last_request_id = 0;
}
@@ -52,11 +52,12 @@ static SymbolKind symbol_kind_to_ted(LSPSymbolKind kind) {
void definition_goto(Ted *ted, LSP *lsp, const char *name, LSPDocumentPosition position) {
Definitions *defs = &ted->definitions;
if (lsp) {
+ // cancel old request
+ ted_cancel_lsp_request(ted, defs->last_request_lsp, defs->last_request_id);
// send that request
LSPRequest request = {.type = LSP_REQUEST_DEFINITION};
request.data.definition.position = position;
LSPRequestID id = lsp_send_request(lsp, &request);
- lsp_cancel_request(lsp, defs->last_request_id); // cancel old request
defs->last_request_id = id;
defs->last_request_lsp = lsp->id;
defs->last_request_time = ted->frame_time;
@@ -220,7 +221,7 @@ void definitions_selector_open(Ted *ted) {
void definitions_selector_close(Ted *ted) {
Definitions *defs = &ted->definitions;
definitions_clear_entries(defs);
- lsp_cancel_request(ted_get_lsp_by_id(ted, defs->last_request_lsp), defs->last_request_id);
+ ted_cancel_lsp_request(ted, defs->last_request_lsp, defs->last_request_id);
defs->last_request_id = 0;
free(defs->last_request_query);
defs->last_request_query = NULL;
diff --git a/ide-usages.c b/ide-usages.c
index 9b1b3fb..73fb725 100644
--- a/ide-usages.c
+++ b/ide-usages.c
@@ -1,8 +1,7 @@
void usages_cancel_lookup(Ted *ted) {
Usages *usages = &ted->usages;
if (usages->last_request_id) {
- LSP *lsp = ted_get_lsp_by_id(ted, usages->last_request_lsp);
- lsp_cancel_request(lsp, usages->last_request_id);
+ ted_cancel_lsp_request(ted, usages->last_request_lsp, usages->last_request_id);
usages->last_request_id = 0;
}
}
diff --git a/main.c b/main.c
index 335f48b..b5e4bd2 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,6 @@
/*
@TODO:
-- use ted_cancel_request more
+- highlighting stuff in README
- show line containing usage
- hover-auto
- handle multiple symbols with same name in go-to-definition menu
@@ -17,6 +17,7 @@
- make tags_dir the root folder
- check that tags still works
- TESTING: make rust-analyzer-slow (waits 10s before sending response)
+- TESTING: check all IDE features with different servers
- run everything through valgrind ideally with leak checking
- grep -i -n TODO *.[ch]
- when searching files, put exact matches at the top
diff --git a/ted.h b/ted.h
index 56185fc..8b73898 100644
--- a/ted.h
+++ b/ted.h
@@ -367,7 +367,6 @@ enum {
typedef struct {
bool open; // is the autocomplete window open?
- bool waiting_for_lsp;
bool is_list_complete; // should the completions array be updated when more characters are typed?
// what trigger caused the last request for completions:
@@ -375,9 +374,11 @@ typedef struct {
// or one of the TRIGGER_* constants above
uint32_t trigger;
+ LSPID last_request_lsp;
+ LSPRequestID last_request_id;
// when we sent the request to the LSP for completions
// (this is used to figure out when we should display "Loading...")
- double lsp_request_time;
+ double last_request_time;
Autocompletion *completions; // dynamic array of all completions
u32 *suggested; // dynamic array of completions to be suggested (indices into completions)