From c8fe98bf37f5364543b365d6d423a785c3c66452 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Thu, 4 Mar 2021 09:48:53 -0500 Subject: completion working, it seems --- autocomplete.c | 31 +++++++++++++++++++++++++++---- command.c | 13 +++++++++++-- command.h | 2 ++ main.c | 2 -- ted.c | 1 + ted.cfg | 2 ++ ted.h | 1 + windows_installer/ted/ted/ted.vdproj | 4 ++-- 8 files changed, 46 insertions(+), 10 deletions(-) diff --git a/autocomplete.c b/autocomplete.c index da4ade3..063a3d2 100644 --- a/autocomplete.c +++ b/autocomplete.c @@ -1,3 +1,6 @@ + + #define AUTOCOMPLETE_NCOMPLETIONS 10 // max # of completions to show + // get the thing to be completed (and what buffer it's in) // returns false if this is a read only buffer or something // call free() on *startp when you're done with it @@ -33,11 +36,27 @@ static void autocomplete_complete(Ted *ted, char *start, TextBuffer *buffer, cha ted->autocomplete = false; } +static void autocomplete_select_cursor_completion(Ted *ted) { + char *start; TextBuffer *buffer; + if (autocomplete_get(ted, &start, &buffer)) { + char *completions[AUTOCOMPLETE_NCOMPLETIONS]; + size_t ncompletions = tags_beginning_with(ted, start, completions, arr_count(completions)); + if (ncompletions) { + i64 cursor = mod_i64(ted->autocomplete_cursor, (i64)ncompletions); + autocomplete_complete(ted, start, buffer, completions[cursor]); + for (size_t i = 0; i < ncompletions; ++i) + free(completions[i]); + } + free(start); + } +} + // open autocomplete, or just do the completion if there's only one suggestion static void autocomplete_open(Ted *ted) { char *start; TextBuffer *buffer; ted->cursor_error_time = 0; + ted->autocomplete_cursor = 0; if (autocomplete_get(ted, &start, &buffer)) { char *completions[2] = {0}; size_t ncompletions = tags_beginning_with(ted, start, completions, 2); @@ -60,7 +79,6 @@ static void autocomplete_open(Ted *ted) { } } -#define AUTOCOMPLETE_NCOMPLETIONS 10 // max # of completions to show static void autocomplete_frame(Ted *ted) { Settings const *settings = &ted->settings; u32 const *colors = settings->colors; @@ -82,6 +100,7 @@ static void autocomplete_frame(Ted *ted) { return; } + ted->autocomplete_cursor = (i32)mod_i64(ted->autocomplete_cursor, ncompletions); v2 cursor_pos = buffer_pos_to_pixels(buffer, buffer->cursor_pos); bool open_up = cursor_pos.y > 0.5f * (buffer->y1 + buffer->y2); // should the completion menu open upwards? @@ -96,6 +115,7 @@ static void autocomplete_frame(Ted *ted) { Rect menu_rect = rect(V2(x, start_y), V2(menu_width, menu_height)); gl_geometry_rect(menu_rect, colors[COLOR_MENU_BG]); //gl_geometry_rect_border(menu_rect, 1, colors[COLOR_BORDER]); + ted->autocomplete_rect = menu_rect; } // vertical padding @@ -104,11 +124,14 @@ static void autocomplete_frame(Ted *ted) { u16 cursor_entry = (u16)((ted->mouse_pos.y - start_y) / char_height); if (cursor_entry < ncompletions) { - // highlight cursor entry + // highlight moused over entry Rect r = rect(V2(x, start_y + cursor_entry * char_height), V2(menu_width, char_height)); gl_geometry_rect(r, colors[COLOR_MENU_HL]); - ted->cursor = ted->cursor_hand; - ted->autocomplete_rect = r; + ted->cursor = ted->cursor_hand; + } + { // highlight cursor entry + Rect r = rect(V2(x, start_y + ted->autocomplete_cursor * char_height), V2(menu_width, char_height)); + gl_geometry_rect(r, colors[COLOR_MENU_HL]); } for (uint i = 0; i < ted->nmouse_clicks[SDL_BUTTON_LEFT]; ++i) { diff --git a/command.c b/command.c index f246f64..9521b77 100644 --- a/command.c +++ b/command.c @@ -101,6 +101,8 @@ void command_execute(Ted *ted, Command c, i64 argument) { if (ted->replace && buffer == &ted->find_buffer) { ted_switch_to_buffer(ted, &ted->replace_buffer); buffer_select_all(buffer); + } else if (ted->autocomplete) { + autocomplete_select_cursor_completion(ted); } else if (buffer) { if (buffer->selection) buffer_indent_selection(buffer); @@ -206,7 +208,14 @@ void command_execute(Ted *ted, Command c, i64 argument) { break; case CMD_AUTOCOMPLETE: - autocomplete_open(ted); + if (ted->autocomplete) + ++ted->autocomplete_cursor; + else + autocomplete_open(ted); + break; + case CMD_AUTOCOMPLETE_BACK: + if (ted->autocomplete) + --ted->autocomplete_cursor; break; case CMD_UNDO: if (buffer) buffer_undo(buffer, argument); @@ -289,7 +298,7 @@ void command_execute(Ted *ted, Command c, i64 argument) { } break; case CMD_TAB_MOVE_RIGHT: { u16 active_tab = node->active_tab; - if (active_tab + 1 < arr_len(node->tabs)) + if ((uint)active_tab + 1 < arr_len(node->tabs)) node_tabs_swap(node, active_tab, active_tab + 1); } break; case CMD_FIND: diff --git a/command.h b/command.h index 1c9be20..ab5d010 100644 --- a/command.h +++ b/command.h @@ -52,6 +52,7 @@ ENUM_U16 { CMD_QUIT, CMD_AUTOCOMPLETE, + CMD_AUTOCOMPLETE_BACK, CMD_COPY, CMD_CUT, @@ -141,6 +142,7 @@ static CommandName const command_names[] = { {"cut", CMD_CUT}, {"paste", CMD_PASTE}, {"autocomplete", CMD_AUTOCOMPLETE}, + {"autocomplete-back", CMD_AUTOCOMPLETE_BACK}, {"find", CMD_FIND}, {"find-replace", CMD_FIND_REPLACE}, {"tab-close", CMD_TAB_CLOSE}, diff --git a/main.c b/main.c index 4a70160..674d121 100644 --- a/main.c +++ b/main.c @@ -1,6 +1,4 @@ // @TODO: -// - completion - // - more instructions (basic stuff + how to open config) // - update screenshot in README // - test windows 7 diff --git a/ted.c b/ted.c index 325755f..cc9eb06 100644 --- a/ted.c +++ b/ted.c @@ -103,6 +103,7 @@ static void ted_load_fonts(Ted *ted) { // you can pass NULL to buffer to make it so no buffer is active. void ted_switch_to_buffer(Ted *ted, TextBuffer *buffer) { ted->active_buffer = buffer; + ted->autocomplete = false; if (ted->find) find_update(ted, true); if (buffer >= ted->buffers && buffer < ted->buffers + TED_MAX_BUFFERS) { diff --git a/ted.cfg b/ted.cfg index ff8ff87..68e2b67 100644 --- a/ted.cfg +++ b/ted.cfg @@ -88,6 +88,8 @@ Ctrl+Shift+s = :save-as Ctrl+q = :quit Ctrl+Space = :autocomplete +# go to previous completion +Ctrl+Shift+Space = :autocomplete-back Ctrl+z = :undo Ctrl+Shift+z = :redo diff --git a/ted.h b/ted.h index baad978..c99cab8 100644 --- a/ted.h +++ b/ted.h @@ -280,6 +280,7 @@ typedef struct Ted { bool building; // is the build process running? bool autocomplete; // is the autocomplete window open? + i32 autocomplete_cursor; // which completion is currently selected Rect autocomplete_rect; // rectangle where the autocomplete menu is (needed to avoid interpreting autocomplete clicks as other clicks) FILE *log; diff --git a/windows_installer/ted/ted/ted.vdproj b/windows_installer/ted/ted/ted.vdproj index 0991400..afd8125 100644 --- a/windows_installer/ted/ted/ted.vdproj +++ b/windows_installer/ted/ted/ted.vdproj @@ -506,12 +506,12 @@ "Name" = "8:Microsoft Visual Studio" "ProductName" = "8:ted" "ProductCode" = "8:{DC9B53A1-5413-4C17-8594-40D570A7DB86}" - "PackageCode" = "8:{805B171D-F95A-4D67-8FBE-DADB06138F73}" + "PackageCode" = "8:{F2851905-7112-446B-B20C-B7E0CA04C0D7}" "UpgradeCode" = "8:{844F6C2B-DF3B-4A81-9BD5-603401BBA651}" "AspNetVersion" = "8:2.0.50727.0" "RestartWWWService" = "11:FALSE" "RemovePreviousVersions" = "11:TRUE" - "DetectNewerInstalledVersion" = "11:TRUE" + "DetectNewerInstalledVersion" = "11:FALSE" "InstallAllUsers" = "11:FALSE" "ProductVersion" = "8:1.0" "Manufacturer" = "8:ted" -- cgit v1.2.3