From e8ebc051bd606df22622c012d68804e275ef1dd5 Mon Sep 17 00:00:00 2001 From: pommicket Date: Fri, 23 Dec 2022 11:57:59 -0500 Subject: close autocomplete on CMD_UP/insert non-word char/etc. --- buffer.c | 38 ++++++++++++++++++++++++++++++++++++++ command.c | 21 +++++++++++++++++++++ main.c | 7 +++---- 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/buffer.c b/buffer.c index bdc23d2..949f19e 100644 --- a/buffer.c +++ b/buffer.c @@ -1455,11 +1455,25 @@ BufferPos buffer_insert_text_at_pos(TextBuffer *buffer, BufferPos pos, String32 str.str = str_copy; } + if (buffer->is_line_buffer) { // remove all the newlines from str. str32_remove_all_instances_of_char(&str, '\n'); } str32_remove_all_instances_of_char(&str, '\r'); + + if (buffer->ted->autocomplete.open) { + // close completions if a non-word character is typed + bool close_completions = false; + for (u32 i = 0; i < str.len; ++i) { + if (!is_word(str.str[i])) { + close_completions = true; + break; + } + } + if (close_completions) + autocomplete_close(buffer->ted); + } LSP *lsp = buffer_lsp(buffer); @@ -1709,6 +1723,30 @@ void buffer_delete_chars_at_pos(TextBuffer *buffer, BufferPos pos, i64 nchars_) // When generating undo events, we allocate nchars characters of memory (see buffer_edit below). // 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) { + // close completions if a non-word character is deleted + bool close_completions = false; + if (nchars > 256) { + // this is a massive deletion + // even if it's all word characters, let's close the completion menu anyways + close_completions = true; + } else { + char32_t text[256]; + size_t n = buffer_get_text_at_pos(buffer, pos, text, nchars); + (void)n; + assert(n == nchars); + for (u32 i = 0; i < nchars; ++i) { + if (!is_word(text[i])) { + close_completions = true; + break; + } + } + } + if (close_completions) + autocomplete_close(buffer->ted); + } + LSP *lsp = buffer_lsp(buffer); if (lsp) diff --git a/command.c b/command.c index 5ed30b7..b330f54 100644 --- a/command.c +++ b/command.c @@ -44,72 +44,93 @@ void command_execute(Ted *ted, Command c, i64 argument) { case CMD_LEFT: if (buffer) buffer_cursor_move_left(buffer, argument); + autocomplete_close(ted); break; case CMD_RIGHT: if (buffer) buffer_cursor_move_right(buffer, argument); + autocomplete_close(ted); break; case CMD_UP: if (ted->selector_open) selector_up(ted, ted->selector_open, argument); else if (ted->menu == MENU_SHELL && buffer == &ted->line_buffer) menu_shell_up(ted); else if (buffer) buffer_cursor_move_up(buffer, argument); + autocomplete_close(ted); break; case CMD_DOWN: if (ted->selector_open) selector_down(ted, ted->selector_open, argument); else if (ted->menu == MENU_SHELL && buffer == &ted->line_buffer) menu_shell_down(ted); else if (buffer) buffer_cursor_move_down(buffer, argument); + autocomplete_close(ted); break; case CMD_SELECT_LEFT: if (buffer) buffer_select_left(buffer, argument); + autocomplete_close(ted); break; case CMD_SELECT_RIGHT: if (buffer) buffer_select_right(buffer, argument); + autocomplete_close(ted); break; case CMD_SELECT_UP: if (buffer) buffer_select_up(buffer, argument); + autocomplete_close(ted); break; case CMD_SELECT_DOWN: if (buffer) buffer_select_down(buffer, argument); + autocomplete_close(ted); break; case CMD_LEFT_WORD: if (buffer) buffer_cursor_move_left_words(buffer, argument); + autocomplete_close(ted); break; case CMD_RIGHT_WORD: if (buffer) buffer_cursor_move_right_words(buffer, argument); + autocomplete_close(ted); break; case CMD_SELECT_LEFT_WORD: if (buffer) buffer_select_left_words(buffer, argument); + autocomplete_close(ted); break; case CMD_SELECT_RIGHT_WORD: if (buffer) buffer_select_right_words(buffer, argument); + autocomplete_close(ted); break; case CMD_START_OF_LINE: if (buffer) buffer_cursor_move_to_start_of_line(buffer); + autocomplete_close(ted); break; case CMD_END_OF_LINE: if (buffer) buffer_cursor_move_to_end_of_line(buffer); + autocomplete_close(ted); break; case CMD_SELECT_START_OF_LINE: if (buffer) buffer_select_to_start_of_line(buffer); + autocomplete_close(ted); break; case CMD_SELECT_END_OF_LINE: if (buffer) buffer_select_to_end_of_line(buffer); + autocomplete_close(ted); break; case CMD_START_OF_FILE: if (buffer) buffer_cursor_move_to_start_of_file(buffer); + autocomplete_close(ted); break; case CMD_END_OF_FILE: if (buffer) buffer_cursor_move_to_end_of_file(buffer); + autocomplete_close(ted); break; case CMD_SELECT_START_OF_FILE: if (buffer) buffer_select_to_start_of_file(buffer); + autocomplete_close(ted); break; case CMD_SELECT_END_OF_FILE: if (buffer) buffer_select_to_end_of_file(buffer); + autocomplete_close(ted); break; case CMD_SELECT_ALL: if (buffer) buffer_select_all(buffer); + autocomplete_close(ted); break; case CMD_INSERT_TEXT: { diff --git a/main.c b/main.c index 5274922..147f4b1 100644 --- a/main.c +++ b/main.c @@ -1,11 +1,10 @@ /* @TODO: - trigger characters (with setting) +- scroll through completions - only show "Loading..." if it's taking some time (prevent flash) - LSP setting -- scroll through completions -- figure out under which circumstances backspace should close completions - - close completions when a non-word character is typed +- make sure "save as" works - rename buffer->filename to buffer->path - make buffer->path NULL for untitled buffers & fix resulting mess - run everything through valgrind ideally with leak checking @@ -17,7 +16,7 @@ FUTURE FEATURES: - multiple files with command line arguments - configurable max buffer size + max view-only buffer size - :set-build-command, don't let ../Cargo.toml override ./Makefile -- add numlock as a key modifier +- add numlock as a key modifier? (but make sure "Ctrl+S" handles both "No NumLock+Ctrl+S" and "NumLock+Ctrl+S" - better undo chaining (dechain on backspace?) - allow multiple fonts (fonts directory?) - regenerate tags for completion too if there are no results -- cgit v1.2.3