summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2023-08-05 15:01:38 -0400
committerpommicket <pommicket@gmail.com>2023-08-05 15:01:38 -0400
commitb65943698a241624973f3ab54530bb5d5884cff2 (patch)
tree07b519ae1a9f601894935ddfba2f968656302dd8
parent0f38b14e10f553cb49a5da65125e21e1591cba3e (diff)
internalize Autocomplete
-rw-r--r--buffer.c8
-rw-r--r--command.c8
-rw-r--r--ide-autocomplete.c79
-rw-r--r--main.c4
-rw-r--r--ted.h48
5 files changed, 87 insertions, 60 deletions
diff --git a/buffer.c b/buffer.c
index 4393f0f..097e4ed 100644
--- a/buffer.c
+++ b/buffer.c
@@ -1635,7 +1635,7 @@ BufferPos buffer_insert_text_at_pos(TextBuffer *buffer, BufferPos pos, String32
}
str32_remove_all_instances_of_char(&str, '\r');
- if (buffer->ted->autocomplete.open) {
+ if (autocomplete_is_open(buffer->ted)) {
// close completions if a non-word character is typed
bool close_completions = false;
for (u32 i = 0; i < str.len; ++i) {
@@ -2105,7 +2105,7 @@ void buffer_delete_chars_at_pos(TextBuffer *buffer, BufferPos pos, i64 nchars_)
// Not doing this might also cause other bugs, best to keep it here just in case.
nchars = (u32)buffer_get_text_at_pos(buffer, pos, NULL, nchars);
- if (buffer->ted->autocomplete.open) {
+ if (autocomplete_is_open(buffer->ted)) {
// close completions if a non-word character is deleted
bool close_completions = false;
if (nchars > 256) {
@@ -2895,8 +2895,8 @@ void buffer_goto_word_at_cursor(TextBuffer *buffer, GotoType type) {
// returns true if the buffer "used" this event
bool buffer_handle_click(Ted *ted, TextBuffer *buffer, vec2 click, u8 times) {
BufferPos buffer_pos;
- if (ted->autocomplete.open) {
- if (rect_contains_point(ted->autocomplete.rect, click))
+ if (autocomplete_is_open(ted)) {
+ if (autocomplete_box_contains_point(ted, click))
return false; // don't look at clicks in the autocomplete menu
else
autocomplete_close(ted); // close autocomplete menu if user clicks outside of it
diff --git a/command.c b/command.c
index c09e0fd..8611f3e 100644
--- a/command.c
+++ b/command.c
@@ -332,7 +332,7 @@ void command_execute_ex(Ted *ted, Command c, const CommandArgument *full_argumen
buffer = &ted->line_buffer;
ted_switch_to_buffer(ted, buffer);
buffer_select_all(buffer);
- } else if (ted->autocomplete.open || ted->autocomplete.phantom) {
+ } else if (autocomplete_is_open(ted) || autocomplete_has_phantom(ted)) {
autocomplete_select_completion(ted);
} else if (buffer) {
if (buffer->selection)
@@ -476,13 +476,13 @@ void command_execute_ex(Ted *ted, Command c, const CommandArgument *full_argumen
}
break;
case CMD_AUTOCOMPLETE:
- if (ted->autocomplete.open)
+ if (autocomplete_is_open(ted))
autocomplete_next(ted);
else
autocomplete_open(ted, TRIGGER_INVOKED);
break;
case CMD_AUTOCOMPLETE_BACK:
- if (ted->autocomplete.open)
+ if (autocomplete_is_open(ted))
autocomplete_prev(ted);
break;
case CMD_GOTO_DEFINITION:
@@ -624,7 +624,7 @@ void command_execute_ex(Ted *ted, Command c, const CommandArgument *full_argumen
if (*ted->message_shown) {
// dismiss message box
*ted->message_shown = '\0';
- } else if (ted->autocomplete.open) {
+ } else if (autocomplete_is_open(ted)) {
autocomplete_close(ted);
} else if (ted->menu) {
menu_escape(ted);
diff --git a/ide-autocomplete.c b/ide-autocomplete.c
index 8cd3d91..c024e30 100644
--- a/ide-autocomplete.c
+++ b/ide-autocomplete.c
@@ -5,6 +5,9 @@
#define TAGS_MAX_COMPLETIONS 200 // max # of tag completions to scroll through
#define AUTOCOMPLETE_NCOMPLETIONS_VISIBLE 10 // max # of completions to show at once
+/// a single autocompletion suggestion
+typedef struct Autocompletion Autocompletion;
+
struct Autocompletion {
char *label;
char *filter;
@@ -17,6 +20,56 @@ struct Autocompletion {
SymbolKind kind;
};
+struct Autocomplete {
+ /// is the autocomplete box open?
+ bool open;
+ /// should the completions array be updated when more characters are typed?
+ bool is_list_complete;
+
+ /// what trigger caused the last request for completions:
+ /// either a character code (for trigger characters),
+ /// or one of the `TRIGGER_*` constants above
+ uint32_t trigger;
+
+ LSPServerRequestID last_request;
+ /// when we sent the request to the LSP for completions
+ /// (this is used to figure out when we should display "Loading...")
+ double last_request_time;
+
+ /// dynamic array of all completions
+ Autocompletion *completions;
+ /// dynamic array of completions to be suggested (indices into completions)
+ u32 *suggested;
+ /// position of cursor last time completions were generated. if this changes, we need to recompute completions.
+ BufferPos last_pos;
+ /// which completion is currently selected (index into suggested)
+ i32 cursor;
+ i32 scroll;
+
+ /// was the last request for phantom completion?
+ bool last_request_phantom;
+ /// current phantom completion to be displayed
+ char *phantom;
+ /// rectangle where the autocomplete menu is (needed to avoid interpreting autocomplete clicks as other clicks)
+ Rect rect;
+};
+
+void autocomplete_init(Ted *ted) {
+ ted->autocomplete = calloc(1, sizeof *ted->autocomplete);
+}
+
+bool autocomplete_is_open(Ted *ted) {
+ return ted->autocomplete->open;
+}
+
+bool autocomplete_has_phantom(Ted *ted) {
+ return ted->autocomplete->phantom != NULL;
+
+}
+
+bool autocomplete_box_contains_point(Ted *ted, vec2 point) {
+ return rect_contains_point(ted->autocomplete->rect, point);
+}
static void autocomplete_clear_completions(Autocomplete *ac) {
arr_foreach_ptr(ac->completions, Autocompletion, completion) {
@@ -37,7 +90,7 @@ static void autocomplete_clear_phantom(Autocomplete *ac) {
// should a phantom completion be displayed?
static bool autocomplete_should_display_phantom(Ted *ted) {
- Autocomplete *ac = &ted->autocomplete;
+ Autocomplete *ac = ted->autocomplete;
TextBuffer *buffer = ted->active_buffer;
bool show = !ac->open
&& buffer
@@ -63,7 +116,7 @@ static void autocomplete_complete(Ted *ted, Autocompletion completion) {
}
void autocomplete_select_completion(Ted *ted) {
- Autocomplete *ac = &ted->autocomplete;
+ Autocomplete *ac = ted->autocomplete;
if (ac->open) {
size_t nsuggestions = arr_len(ac->suggested);
if (nsuggestions) {
@@ -79,7 +132,7 @@ void autocomplete_select_completion(Ted *ted) {
}
static void autocomplete_correct_scroll(Ted *ted) {
- Autocomplete *ac = &ted->autocomplete;
+ Autocomplete *ac = ted->autocomplete;
i32 scroll = ac->scroll;
scroll = min_i32(scroll, (i32)arr_len(ac->suggested) - AUTOCOMPLETE_NCOMPLETIONS_VISIBLE);
scroll = max_i32(scroll, 0);
@@ -87,13 +140,13 @@ static void autocomplete_correct_scroll(Ted *ted) {
}
void autocomplete_scroll(Ted *ted, i32 by) {
- Autocomplete *ac = &ted->autocomplete;
+ Autocomplete *ac = ted->autocomplete;
ac->scroll += by;
autocomplete_correct_scroll(ted);
}
static void autocomplete_move_cursor(Ted *ted, i32 by) {
- Autocomplete *ac = &ted->autocomplete;
+ Autocomplete *ac = ted->autocomplete;
u32 ncompletions = arr_len(ac->suggested);
if (ncompletions == 0)
return;
@@ -114,7 +167,7 @@ void autocomplete_prev(Ted *ted) {
}
void autocomplete_close(Ted *ted) {
- Autocomplete *ac = &ted->autocomplete;
+ Autocomplete *ac = ted->autocomplete;
ac->open = false;
autocomplete_clear_phantom(ac);
autocomplete_clear_completions(ac);
@@ -122,7 +175,7 @@ void autocomplete_close(Ted *ted) {
}
static void autocomplete_update_suggested(Ted *ted) {
- Autocomplete *ac = &ted->autocomplete;
+ Autocomplete *ac = ted->autocomplete;
arr_clear(ac->suggested);
char *word = buffer_word_at_cursor_utf8(ted->active_buffer);
for (u32 i = 0; i < arr_len(ac->completions); ++i) {
@@ -138,7 +191,7 @@ static bool autocomplete_using_lsp(Ted *ted) {
}
static void autocomplete_no_suggestions(Ted *ted) {
- Autocomplete *ac = &ted->autocomplete;
+ Autocomplete *ac = ted->autocomplete;
if (ac->trigger == TRIGGER_INVOKED)
ted_flash_error_cursor(ted);
autocomplete_close(ted);
@@ -149,7 +202,7 @@ static void autocomplete_send_completion_request(Ted *ted, TextBuffer *buffer, B
return; // no can do
LSP *lsp = buffer_lsp(buffer);
- Autocomplete *ac = &ted->autocomplete;
+ Autocomplete *ac = ted->autocomplete;
ted_cancel_lsp_request(ted, &ac->last_request);
@@ -188,7 +241,7 @@ static void autocomplete_send_completion_request(Ted *ted, TextBuffer *buffer, B
}
static void autocomplete_find_completions(Ted *ted, uint32_t trigger, bool phantom) {
- Autocomplete *ac = &ted->autocomplete;
+ Autocomplete *ac = ted->autocomplete;
TextBuffer *buffer = ted->active_buffer;
if (!buffer)
return;
@@ -299,7 +352,7 @@ void autocomplete_process_lsp_response(Ted *ted, const LSPResponse *response) {
const LSPRequest *request = &response->request;
if (request->type != LSP_REQUEST_COMPLETION)
return;
- Autocomplete *ac = &ted->autocomplete;
+ Autocomplete *ac = ted->autocomplete;
if (request->id != ac->last_request.id)
return; // old request
ac->last_request.id = 0;
@@ -397,7 +450,7 @@ void autocomplete_process_lsp_response(Ted *ted, const LSPResponse *response) {
}
void autocomplete_open(Ted *ted, uint32_t trigger) {
- Autocomplete *ac = &ted->autocomplete;
+ Autocomplete *ac = ted->autocomplete;
if (ac->open) return;
TextBuffer *buffer = ted->active_buffer;
if (!buffer) return;
@@ -482,7 +535,7 @@ void autocomplete_frame(Ted *ted) {
autocomplete_find_phantom(ted);
- Autocomplete *ac = &ted->autocomplete;
+ Autocomplete *ac = ted->autocomplete;
if (autocomplete_should_display_phantom(ted) && ac->phantom) {
// display phantom completion
char *word_at_cursor = buffer_word_at_cursor_utf8(buffer);
diff --git a/main.c b/main.c
index 8bc1ec5..ec8af1e 100644
--- a/main.c
+++ b/main.c
@@ -500,6 +500,7 @@ int main(int argc, char **argv) {
gl_geometry_init();
text_init();
+ autocomplete_init(ted);
PROFILE_TIME(gl_end)
@@ -633,8 +634,7 @@ int main(int argc, char **argv) {
} else if (key_modifier == 0) {
// scroll with mouse wheel
Sint32 dx = event.wheel.x, dy = -event.wheel.y;
- Autocomplete *ac = &ted->autocomplete;
- if (ac->open && rect_contains_point(ac->rect, ted->mouse_pos)) {
+ if (autocomplete_box_contains_point(ted, ted->mouse_pos)) {
autocomplete_scroll(ted, dy);
} else {
ted->scroll_total_x += dx;
diff --git a/ted.h b/ted.h
index 65f4a26..36d5ce7 100644
--- a/ted.h
+++ b/ted.h
@@ -608,43 +608,8 @@ typedef enum {
SYMBOL_KEYWORD
} SymbolKind;
-/// a single autocompletion suggestion
-typedef struct Autocompletion Autocompletion;
-
/// data needed for autocompletion
-typedef struct {
- /// is the autocomplete window open?
- bool open;
- /// should the completions array be updated when more characters are typed?
- bool is_list_complete;
-
- /// what trigger caused the last request for completions:
- /// either a character code (for trigger characters),
- /// or one of the `TRIGGER_*` constants above
- uint32_t trigger;
-
- LSPServerRequestID last_request;
- /// when we sent the request to the LSP for completions
- /// (this is used to figure out when we should display "Loading...")
- double last_request_time;
-
- /// dynamic array of all completions
- Autocompletion *completions;
- /// dynamic array of completions to be suggested (indices into completions)
- u32 *suggested;
- /// position of cursor last time completions were generated. if this changes, we need to recompute completions.
- BufferPos last_pos;
- /// which completion is currently selected (index into suggested)
- i32 cursor;
- i32 scroll;
-
- /// was the last request for phantom completion?
- bool last_request_phantom;
- /// current phantom completion to be displayed
- char *phantom;
- /// rectangle where the autocomplete menu is (needed to avoid interpreting autocomplete clicks as other clicks)
- Rect rect;
-} Autocomplete;
+typedef struct Autocomplete Autocomplete;
/// data needed for finding usages
typedef struct {
@@ -833,7 +798,7 @@ struct Ted {
bool build_shown;
/// is the build process running?
bool building;
- Autocomplete autocomplete;
+ Autocomplete *autocomplete;
SignatureHelp signature_help;
DocumentLinks document_links;
Hover hover;
@@ -1512,6 +1477,15 @@ void gl_geometry_draw(void);
GLuint gl_load_texture_from_image(const char *path);
// === ide-autocomplete.c ===
+#if !TED_PLUGIN
+void autocomplete_init(Ted *ted);
+#endif
+/// is the autocomplete box open?
+bool autocomplete_is_open(Ted *ted);
+/// is there a phantom completion being displayed?
+bool autocomplete_has_phantom(Ted *ted);
+/// is this point in the autocomplete box?
+bool autocomplete_box_contains_point(Ted *ted, vec2 point);
/// open autocomplete
/// trigger should either be a character (e.g. '.') or one of the TRIGGER_* constants.
void autocomplete_open(Ted *ted, uint32_t trigger);