From 3618d906e681d45149cd7fe148ff3a185fd9d7a0 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Sat, 24 Jan 2026 18:14:38 +0100 Subject: [PATCH] Begin WordComplete --- src/basic/math_int.cpp | 4 ++ src/text_editor/plugin_word_complete.cpp | 78 ++++++++++++++++++++++++ src/text_editor/text_editor.cpp | 2 + src/text_editor/view.cpp | 9 ++- 4 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 src/text_editor/plugin_word_complete.cpp diff --git a/src/basic/math_int.cpp b/src/basic/math_int.cpp index c79074d..dcb95d7 100644 --- a/src/basic/math_int.cpp +++ b/src/basic/math_int.cpp @@ -142,4 +142,8 @@ Int SafeDivide(Int a, Int b) { bool AreOverlapping(Vec2I point, Rect2I rec) { bool result = (point.x >= rec.min.x) && (point.x < rec.max.x) && (point.y >= rec.min.y) && (point.y < rec.max.y); return result; +} + +Int Absolute(Int value) { + return llabs(value); } \ No newline at end of file diff --git a/src/text_editor/plugin_word_complete.cpp b/src/text_editor/plugin_word_complete.cpp new file mode 100644 index 0000000..8ded20d --- /dev/null +++ b/src/text_editor/plugin_word_complete.cpp @@ -0,0 +1,78 @@ +struct Lexer2 { + char16_t *at; +}; + +Lexer2 BeginLexing(String16 data) { + Lexer2 result = {data.data}; + return result; +} + +String16 Next(Lexer2 *lexer) { + while (lexer->at[0] != 0 && !IsAlphanumeric(lexer->at[0])) { + lexer->at += 1; + } + String16 result = {lexer->at, 0}; + while (IsAlphanumeric(lexer->at[0])) { + lexer->at += 1; + result.len += 1; + } + return result; +} + +struct WordCompleteS { + String16 string; + Int distance; +}; + +bool Contains(Array *arr, String16 string) { + For (*arr) { + if (it.string == string) return true; + } + return false; +} + +inline bool MergeSortCompare(WordCompleteS *EntryA, WordCompleteS *EntryB) { + bool result = EntryA->distance > EntryB->distance; + return result; +} + +void CMD_WordComplete() { + // @todo: handle multiple carets + // @todo: indent when shift otherwise wordcomplte + // @todo: loop through buffers + // @todo: iterate by pressing 'tab' continously + Scratch scratch; + BSet active = GetBSet(ActiveWindowID); + Caret caret = active.view->carets[0]; + Range range = caret.range; + if (GetSize(range) != 0) { + return; + } + range.min = GetWordStart(active.buffer, range.min); + String16 prefix = GetString(active.buffer, range); + + String16 string = GetString(active.buffer); + + Array idents = {scratch}; + Lexer2 lexer = BeginLexing(string.data); + for (int i = 0;; i += 1) { + String16 token = Next(&lexer); + if (token.len <= 0) break; + if (StartsWith(token, prefix) && token != prefix && !Contains(&idents, token)) { + Int pos = token.data - active.buffer->str; + Int distance = Absolute(range.min - pos); + Add(&idents, {token, distance}); + } + } + + if (idents.len > 1) { + Array temp = TightCopy(scratch, idents); + MergeSort(idents.len, idents.data, temp.data); + } + if (idents.len > 0) { + String16 ident = idents[0].string; + ident = Skip(ident, prefix.len); + ident = Copy16(scratch, ident); + Replace(active.view, ident); + } +} RegisterCommand(CMD_WordComplete, "ctrl-b", "Completes the current word"); \ No newline at end of file diff --git a/src/text_editor/text_editor.cpp b/src/text_editor/text_editor.cpp index 5b2f973..57273fb 100644 --- a/src/text_editor/text_editor.cpp +++ b/src/text_editor/text_editor.cpp @@ -36,6 +36,7 @@ #define PLUGIN_LOAD_VCVARS OS_WINDOWS #define PLUGIN_REMEDYBG OS_WINDOWS #define PLUGIN_FILE_COMMANDS 1 +#define PLUGIN_WORD_COMPLETE 1 #include "plugin_directory_navigation.h" #include "plugin_search_window.h" @@ -74,6 +75,7 @@ #include "plugin_remedybg.cpp" #include "plugin_profiler.cpp" #include "plugin_file_commands.cpp" +#include "plugin_word_complete.cpp" #if OS_WASM EM_JS(void, JS_SetMouseCursor, (const char *cursor_str), { diff --git a/src/text_editor/view.cpp b/src/text_editor/view.cpp index 8b3ce5c..d0b4b08 100644 --- a/src/text_editor/view.cpp +++ b/src/text_editor/view.cpp @@ -604,8 +604,13 @@ void IndentSelectedLines(View *view, bool shift = false) { for (Int i = 0; i < saved_xy.len; i += 1) { Caret &caret = view->carets[i]; XYPair &xypair = saved_xy[i]; - xypair.front.x += IndentSize; - xypair.back.x += IndentSize; + if (!shift) { + xypair.front.x += IndentSize; + xypair.back.x += IndentSize; + } else { + xypair.front.x -= IndentSize; + xypair.back.x -= IndentSize; + } Int front = XYToPos(buffer, xypair.front); Int back = XYToPos(buffer, xypair.back); caret = MakeCaret(front, back);