From 94b3bc832b11cc8bd7a13cb546107e727a93f058 Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Tue, 6 Jan 2026 10:50:55 +0100 Subject: [PATCH] Improve SearchProject and misc --- src/backup/todo.txt | 2 + src/basic/basic_string16.cpp | 9 ++++ src/text_editor/buffer.cpp | 16 ------- src/text_editor/buffer.h | 1 - src/text_editor/globals.cpp | 5 +- src/text_editor/view.cpp | 74 +++++++++++++++++------------- src/text_editor/window_command.cpp | 6 ++- 7 files changed, 60 insertions(+), 53 deletions(-) diff --git a/src/backup/todo.txt b/src/backup/todo.txt index c31d87c..52f416d 100644 --- a/src/backup/todo.txt +++ b/src/backup/todo.txt @@ -1,6 +1,7 @@ ! What precise workflow do I need for me to be viable to use this? ! From a user (novice) point of view, how does it look like? +- Search and replace - We need regex for: [FormatCode matching, IsCode matching, - IndentKind has issues with stuff still like cleaning whitespace etc. - Remedybg commands integrated! (like clicking f5 and opening up the window) @@ -13,6 +14,7 @@ - OnUpdate view hooks! - OnSave buffer hooks which will execute the config on save - Make the special view hooks also available for modification and registered but maybe under different name or something +- Maybe IPC for te.exe when it's already open and file arguments are passed it should perhaps open a buffer in current window?? Use session 4 - Add <> <> template strings to Open (Then remove SEtWorkdirhere) diff --git a/src/basic/basic_string16.cpp b/src/basic/basic_string16.cpp index 22c750c..1fdc96a 100644 --- a/src/basic/basic_string16.cpp +++ b/src/basic/basic_string16.cpp @@ -536,3 +536,12 @@ API Int ChopNumber(String16 *string) { Int result = strtoll(num_string.data, NULL, 10) - 1; return result; } + +API String16 Concat(Allocator allocator, String16 a, String16 b) { + char16_t *p = AllocArray(allocator, char16_t, a.len + b.len + 1); + MemoryCopy(p, a.data, sizeof(char16_t) * a.len); + MemoryCopy(p + a.len, b.data, sizeof(char16_t) * b.len); + String16 result = {p, a.len + b.len}; + result.data[result.len] = 0; + return result; +} \ No newline at end of file diff --git a/src/text_editor/buffer.cpp b/src/text_editor/buffer.cpp index f58c23a..5788dbe 100644 --- a/src/text_editor/buffer.cpp +++ b/src/text_editor/buffer.cpp @@ -519,22 +519,6 @@ API Int SkipSpaces(Buffer *buffer, Int seek) { return seek; } -API Int FindAnyScopeBegin(Buffer *buffer, Int pos) { - int inner_scope = 0; - for (Int i = pos - 1; i >= 0; i -= 1) { - if (buffer->str[i] == '{' || buffer->str[i] == '[' || buffer->str[i] == '(') { - if (inner_scope == 0) { - return i; - } - inner_scope -= 1; - } - if (buffer->str[i] == '}' || buffer->str[i] == ']' || buffer->str[i] == ')') { - inner_scope += 1; - } - } - return 0; -} - API Range EncloseLine(Buffer *buffer, Int pos) { Range result = {GetLineStart(buffer, pos), GetLineEnd(buffer, pos)}; return result; diff --git a/src/text_editor/buffer.h b/src/text_editor/buffer.h index 0b1884a..65c4c13 100644 --- a/src/text_editor/buffer.h +++ b/src/text_editor/buffer.h @@ -119,7 +119,6 @@ API Int GetNextEmptyLineStart(Buffer *buffer, Int pos); API Int GetPrevEmptyLineStart(Buffer *buffer, Int pos); API Range EncloseWord(Buffer *buffer, Int pos); API Int SkipSpaces(Buffer *buffer, Int seek); -API Int FindScopeEnd(Buffer *buffer, Int seek, Int max_seek, char16_t open, char16_t close); API Range EncloseLine(Buffer *buffer, Int pos); API Range EncloseFullLine(Buffer *buffer, Int pos); API Int OffsetByLine(Buffer *buffer, Int pos, Int line_offset); diff --git a/src/text_editor/globals.cpp b/src/text_editor/globals.cpp index fd6b3ae..e13013d 100644 --- a/src/text_editor/globals.cpp +++ b/src/text_editor/globals.cpp @@ -167,8 +167,7 @@ RegisterVariable(String, WindowsVCVarsPathToLoadDevEnviroment, "C:/Program Files RegisterVariable(Float, UndoMergeTime, 0.3); RegisterVariable(Float, JumpHistoryMergeTime, 0.3); RegisterVariable(String, InternetBrowser, "firefox"); -RegisterVariable(String, OpenCodePatterns, ".c .h .cpp .hpp .cc .cxx .rs .go .zig .py .lua .js .ts .jsx .tsx .java .kt .swift .cs .rb .php .html .css .scss .sh .bash .zsh .sql .asm .s .cmake .make .json .yaml .toml .ini .txt .md .rst .Makefile .Dockerfile .gitignore .bashrc .zshrc"); +RegisterVariable(String, OpenCodePatterns, ".c .h .cpp .hpp .cc .cxx .rs .go .zig .py .lua .js .ts .jsx .tsx .java .kt .swift .cs .rb .php .html .css .scss .bat .sh .bash .zsh .sql .asm .s .cmake .make .json .yaml .toml .ini .txt .md .rst .Makefile .Dockerfile .gitignore .bashrc .zshrc"); RegisterVariable(String, OpenCodeExcludePatterns, ""); RegisterVariable(Int, TrimTrailingWhitespace, 1); -RegisterVariable(Int, FormatCode, 0); -RegisterVariable(Int, SetModifiesConfig, 1); \ No newline at end of file +RegisterVariable(Int, FormatCode, 0); \ No newline at end of file diff --git a/src/text_editor/view.cpp b/src/text_editor/view.cpp index 8be56e6..04fab35 100644 --- a/src/text_editor/view.cpp +++ b/src/text_editor/view.cpp @@ -134,6 +134,44 @@ String16 FetchFuzzyViewLoadLine(View *view) { return string; } +char16_t GetIndentChar() { + char16_t c = u' '; + if (IndentKindWhichIsTabsOrSpaces == "spaces") { + c = u' '; + } else if (IndentKindWhichIsTabsOrSpaces == "tabs") { + c = u'\t'; + } else { + ReportErrorf("Invalid IndentKindWhichIsTabsOrSpaces value: %S", IndentKindWhichIsTabsOrSpaces); + } + return c; +} + +String16 GetIndentString(Allocator allocator, Int indent_size) { + char16_t *result = AllocArray(allocator, char16_t, indent_size + 1); + char16_t c = GetIndentChar(); + + for (int i = 0; i < IndentSize; i += 1) { + result[i] = c; + } + result[IndentSize] = 0; + String16 res = {result, indent_size}; + return res; +} + +Int FindScopeIndent(Buffer *buffer, Int pos) { + for (Int i = pos - 1; i >= 0; i -= 1) { + if (buffer->str[i] == '{' || buffer->str[i] == '[' || buffer->str[i] == '(') { + Int line = PosToLine(buffer, pos); + return GetLineIndent(buffer, line) + IndentSize; + } + if (buffer->str[i] == '}' || buffer->str[i] == ']' || buffer->str[i] == ')') { + Int line = PosToLine(buffer, pos); + return GetLineIndent(buffer, line); + } + } + return 0; +} + void IndentedNewLine(View *view) { Buffer *buffer = GetBuffer(view->active_buffer); Scratch scratch; @@ -141,10 +179,8 @@ void IndentedNewLine(View *view) { MergeCarets(buffer, &view->carets); For(view->carets) { Int front = GetFront(it); - Int scope_begin = FindAnyScopeBegin(buffer, front); // @todo: this could be problematic in large source files! - Int line = PosToLine(buffer, scope_begin); - Int indent = GetLineIndent(buffer, line) + IndentSize; - String string = Format(scratch, "\n%.*s", (int)indent, " "); + Int indent = GetLineIndent(buffer, PosToLine(buffer, front)); + String string = Format(scratch, "\n%S", GetIndentString(scratch, indent)); String16 string16 = ToString16(scratch, string); AddEdit(&edits, it.range, string16); } @@ -507,30 +543,6 @@ Array GetSelectedLinesSorted(Allocator allocator, View *view) { return result; } -char16_t GetIndentChar() { - char16_t c = u' '; - if (IndentKindWhichIsTabsOrSpaces == "spaces") { - c = u' '; - } else if (IndentKindWhichIsTabsOrSpaces == "tabs") { - c = u'\t'; - } else { - ReportErrorf("Invalid IndentKindWhichIsTabsOrSpaces value: %S", IndentKindWhichIsTabsOrSpaces); - } - return c; -} - -String16 GetIndentString(Allocator allocator) { - char16_t *result = AllocArray(allocator, char16_t, IndentSize + 1); - char16_t c = GetIndentChar(); - - for (int i = 0; i < IndentSize; i += 1) { - result[i] = c; - } - result[IndentSize] = 0; - String16 res = {result, IndentSize}; - return res; -} - void IndentSelectedLines(View *view, bool shift = false) { Scratch scratch; Buffer *buffer = GetBuffer(view->active_buffer); @@ -539,7 +551,7 @@ void IndentSelectedLines(View *view, bool shift = false) { MergeCarets(buffer, &view->carets); char16_t indent_char = GetIndentChar(); - String16 indent_string = GetIndentString(scratch); + String16 indent_string = GetIndentString(scratch, IndentSize); Array line_ranges_to_indent = GetSelectedLinesSorted(scratch, view); For(line_ranges_to_indent) { for (Int i = it.min; i < it.max; i += 1) { @@ -548,8 +560,8 @@ void IndentSelectedLines(View *view, bool shift = false) { if (!shift) { AddEdit(&edits, {pos_range_of_line.min, pos_range_of_line.min}, indent_string); } else { - String16 string = GetString(buffer, pos_range_of_line); - Int whitespace_len = 0; + String16 string = GetString(buffer, pos_range_of_line); + Int whitespace_len = 0; for (Int i = 0; i < IndentSize && i < string.len && string.data[i] == indent_char; i += 1) { whitespace_len += 1; } diff --git a/src/text_editor/window_command.cpp b/src/text_editor/window_command.cpp index 7f338af..953bc2a 100644 --- a/src/text_editor/window_command.cpp +++ b/src/text_editor/window_command.cpp @@ -195,9 +195,11 @@ void Coro_SearchProject(mco_coro *co) { ForItem (caret, occurences) { Int pos = caret.range.min; Int line = PosToLine(it, pos); - String16 line_string = GetLineStringWithoutNL(it, line); + Range range = GetLineRangeWithoutNL(it, line); + Int column = pos - range.min; + String16 line_string = GetString(it, range); String line_string8 = ToString(scratch, line_string); - RawAppendf(out_buffer, "%S ||> %S:%lld\n", line_string8, it->name, (long long)line + 1); + RawAppendf(out_buffer, "%S ||> %S:%lld:%lld\n", line_string8, it->name, (long long)line + 1, (long long)column + 1); } } CoYield(co);