Working on resource management stuff

This commit is contained in:
Krzosa Karol
2024-07-23 22:33:01 +02:00
parent 4cb892133f
commit 1528ecac52
12 changed files with 167 additions and 287 deletions

View File

@@ -555,7 +555,7 @@ void Remove(Array<T> *arr, T &item) {
template <class T> template <class T>
void UnorderedRemove(Array<T> *arr, T &item) { void UnorderedRemove(Array<T> *arr, T &item) {
Assert(arr->len > 0); Assert(arr->len > 0);
Assert(&item >= arr->begin && &item < arr->end); Assert((&item >= arr->begin()) && (&item < arr->end()));
item = arr->data[--arr->len]; item = arr->data[--arr->len];
} }

View File

@@ -28,6 +28,9 @@ bool InitOS();
String GetExePath(Allocator allocator); String GetExePath(Allocator allocator);
String GetExeDir(Allocator allocator); String GetExeDir(Allocator allocator);
bool FileExists(String path);
bool IsDir(String path);
bool IsFile(String path);
struct Process { struct Process {
bool is_valid; bool is_valid;

View File

@@ -276,3 +276,26 @@ String GetExeDir(Allocator allocator) {
path = Copy(allocator, path); path = Copy(allocator, path);
return path; return path;
} }
bool FileExists(String path) {
wchar_t wbuff[1024];
CreateWidecharFromChar(wbuff, Lengthof(wbuff), path.data, path.len);
DWORD attribs = GetFileAttributesW(wbuff);
bool result = attribs == INVALID_FILE_ATTRIBUTES ? false : true;
return result;
}
bool IsDir(String path) {
wchar_t wbuff[1024];
CreateWidecharFromChar(wbuff, Lengthof(wbuff), path.data, path.len);
DWORD dwAttrib = GetFileAttributesW(wbuff);
return dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY);
}
bool IsFile(String path) {
wchar_t wbuff[1024];
CreateWidecharFromChar(wbuff, Lengthof(wbuff), path.data, path.len);
DWORD dwAttrib = GetFileAttributesW(wbuff);
bool is_file = (dwAttrib & FILE_ATTRIBUTE_DIRECTORY) == 0;
return dwAttrib != INVALID_FILE_ATTRIBUTES && is_file;
}

View File

@@ -3,17 +3,24 @@ https://code.visualstudio.com/blogs/2018/03/23/text-buffer-reimplementation
*/ */
#define BUFFER_DEBUG 0 #define BUFFER_DEBUG 0
void InitBuffer(Allocator allocator, Buffer *buffer, Int size = 4096) { void InitBuffer(Allocator allocator, Buffer *buffer, String name, Int size = 4096) {
buffer->id = AllocBufferID(); buffer->id = AllocBufferID();
buffer->name = name;
buffer->cap = size; buffer->cap = size;
buffer->data = AllocArray(allocator, U16, buffer->cap); buffer->data = AllocArray(allocator, U16, buffer->cap);
buffer->line_starts.allocator = allocator; buffer->line_starts.allocator = allocator;
Add(&buffer->line_starts, (Int)0); Add(&buffer->line_starts, (Int)0);
} }
Buffer *CreateBuffer(Allocator allocator, Int size = 4096) { Buffer *CreateBuffer(Allocator allocator, String name, Int size = 4096) {
Buffer *result = Alloc(&Buffers); Buffer *result = Alloc(&Buffers);
InitBuffer(allocator, result, size); InitBuffer(allocator, result, name, size);
return result;
}
Buffer *CreateTempBuffer(Allocator allocator, Int size = 4096) {
Buffer *result = AllocType(allocator, Buffer);
InitBuffer(allocator, result, "*temp*", size);
return result; return result;
} }
@@ -187,166 +194,3 @@ void ReplaceText(Buffer *buffer, Range range, String16 string) {
ValidateLineStarts(buffer); ValidateLineStarts(buffer);
#endif #endif
} }
Buffer *OpenFile(String path) {
Scratch scratch;
String string = ReadFile(scratch, path);
Allocator sys_allocator = GetSystemAllocator();
Buffer *buffer = CreateBuffer(sys_allocator, string.len * 4);
for (Int i = 0; i < string.len;) {
if (string.data[i] == '\r') {
i += 1;
continue;
}
if (string.data[i] == '\t') {
// @WARNING: DONT INCREASE THE SIZE CARELESSLY, WE NEED TO ADJUST BUFFER SIZE
for (Int i = 0; i < 4; i += 1) buffer->data[buffer->len++] = L' ';
i += 1;
continue;
}
uint32_t u32 = '?';
UTF32Result decode = UTF8ToUTF32(string.data + i, (int64_t)(string.len - i));
if (!decode.error) {
i += decode.advance;
u32 = decode.out_str;
} else {
i += 1;
}
UTF16Result encode = UTF32ToUTF16(decode.out_str);
if (!encode.error) {
for (int64_t encode_i = 0; encode_i < encode.len; encode_i += 1) {
buffer->data[buffer->len++] = encode.out_str[encode_i];
Assert(buffer->len < buffer->cap);
}
} else {
buffer->data[buffer->len++] = L'?';
}
}
UpdateLines(buffer, {}, String16{(wchar_t *)buffer->data, buffer->len});
return buffer;
}
void TestBuffer() {
Scratch scratch;
{
Buffer buffer = {};
InitBuffer(scratch, &buffer);
Assert(buffer.line_starts.len == 1);
String16 test_string = L"Thing itself";
{
ReplaceText(&buffer, Rng(), test_string);
Assert(buffer.cap == 4096);
Assert(buffer.len == 12);
String16 a = GetString(buffer);
Assert(a == test_string);
Assert(buffer.line_starts.len == 1);
Assert(buffer.line_starts[0] == 0);
Assert(PosToLine(buffer, 4) == 0);
}
{
ReplaceText(&buffer, {0, 5}, L"");
Assert(buffer.cap == 4096);
Assert(buffer.len == 12 - 5);
String16 a = GetString(buffer);
Assert(a == L" itself");
Assert(buffer.line_starts.len == 1);
Assert(buffer.line_starts[0] == 0);
Assert(PosToLine(buffer, 4) == 0);
}
{
ReplaceText(&buffer, GetEndAsRange(buffer), L" and");
Assert(buffer.cap == 4096);
Assert(buffer.len == 12 - 5 + 4);
String16 a = GetString(buffer);
Assert(a == L" itself and");
Assert(buffer.line_starts.len == 1);
Assert(buffer.line_starts[0] == 0);
Assert(PosToLine(buffer, 4) == 0);
}
{
ReplaceText(&buffer, GetRange(buffer), L"");
Assert(buffer.cap == 4096);
Assert(buffer.len == 0);
String16 a = GetString(buffer);
Assert(a == L"");
Assert(buffer.line_starts.len == 1);
Assert(buffer.line_starts[0] == 0);
}
{
ReplaceText(&buffer, GetEndAsRange(buffer), L"Memes and other\nthings");
Assert(buffer.line_starts.len == 2);
Assert(PosToLine(buffer, 17) == 1);
Assert(PosToLine(buffer, 16) == 1);
Assert(PosToLine(buffer, 15) == 0);
Assert(buffer.data[15] == L'\n');
Assert(buffer.data[16] == L't');
ReplaceText(&buffer, GetBeginAsRange(buffer), L"Things as is\nand stuff\n");
Assert(buffer.line_starts.len == 4);
Assert(PosToLine(buffer, 12) == 0);
Assert(buffer.data[12] == L'\n');
Assert(PosToLine(buffer, 13) == 1);
Assert(PosToLine(buffer, 21) == 1);
Assert(PosToLine(buffer, 22) == 1);
Assert(buffer.data[22] == L'\n');
Assert(PosToLine(buffer, 23) == 2);
Assert(PosToLine(buffer, 37) == 2);
Assert(PosToLine(buffer, 38) == 2);
Assert(buffer.data[38] == L'\n');
Assert(PosToLine(buffer, 39) == 3);
Assert(buffer.data[39] == L't');
ReplaceText(&buffer, GetBeginAsRange(buffer), L"a");
Assert(buffer.line_starts.len == 4);
Assert(PosToLine(buffer, 13) == 0);
Assert(PosToLine(buffer, 14) == 1);
}
}
{
Buffer buffer = {};
InitBuffer(scratch, &buffer);
ReplaceText(&buffer, {}, L"Thing\nmeme");
Assert(PosToLine(buffer, 5) == 0);
Assert(PosToLine(buffer, 6) == 1);
ReplaceText(&buffer, {0, 1}, L"");
Assert(PosToLine(buffer, 4) == 0);
Assert(PosToLine(buffer, 5) == 1);
ReplaceText(&buffer, {4, 5}, L"");
Assert(buffer.line_starts.len == 1);
ValidateLineStarts(&buffer);
}
{
Buffer buffer = {};
InitBuffer(scratch, &buffer);
ReplaceText(&buffer, {}, L"Thing\nmeme");
ReplaceText(&buffer, {0, 5}, L"per\ncop");
Assert(buffer.line_starts.len == (Int)3);
Assert(PosToLine(buffer, 3) == 0);
Assert(PosToLine(buffer, 4) == 1);
ValidateLineStarts(&buffer);
ReplaceText(&buffer, {0, 8}, L"Thing\nmeme");
ReplaceText(&buffer, {0, 3}, L"Thing\nmeme");
ReplaceText(&buffer, {9, 13}, L"Thing\nmeme");
ReplaceText(&buffer, {4, 5}, L"Thing\nmeme\n\n\n");
ReplaceText(&buffer, {22, 23}, L"\n\n\nThing\nmeme\n\n\n");
ReplaceText(&buffer, {22, 23}, L"\n\n\nThing\nmeme\n\n\n");
ReplaceText(&buffer, {22, 23}, L"\n\n\nThing\nmeme\n\n\n");
ReplaceText(&buffer, {22, 23}, L"\n\n\nThing\nmeme\n\n\n");
ValidateLineStarts(&buffer);
}
{
Buffer buffer = {};
InitBuffer(scratch, &buffer);
ReplaceText(&buffer, {}, L"Thing\nmeme");
ReplaceText(&buffer, GetEndAsRange(buffer), L"\nnewThing");
}
}

View File

@@ -1,7 +1,11 @@
void MergeCarets(Array<Caret> *_carets, Range *mouse_selection_anchor = NULL) { void MergeCarets(Buffer &buffer, Array<Caret> *_carets, Range *mouse_selection_anchor = NULL) {
ProfileFunction(); ProfileFunction();
Array<Caret> &carets = *_carets; Array<Caret> &carets = *_carets;
Scratch scratch; Scratch scratch;
// Clamp carets
For(carets) it.range = Clamp(buffer, it.range);
// Merge carets that overlap, this needs to be handled before any edits to // Merge carets that overlap, this needs to be handled before any edits to
// make sure overlapping edits won't happen. // make sure overlapping edits won't happen.
@@ -145,21 +149,3 @@ void _ApplyEdits(Buffer *buffer, Array<Edit> edits) {
void AddEdit(Array<Edit> *e, Range range, String16 string) { void AddEdit(Array<Edit> *e, Range range, String16 string) {
Add(e, {range, string}); Add(e, {range, string});
} }
void TestBufferMultiCaret() {
Scratch scratch;
{
Buffer buffer = {};
InitBuffer(scratch, &buffer);
ReplaceText(&buffer, {}, L"Testing\nthings");
Array<Edit> edits = {scratch};
AddEdit(&edits, {0, 7}, L"t");
AddEdit(&edits, {8, 9}, L"T");
AddEdit(&edits, GetEndAsRange(buffer), L"\nnewThing");
_ApplyEdits(&buffer, edits);
String16 s = GetString(buffer);
Assert(s == L"t\nThings\nnewThing");
}
}

View File

@@ -219,11 +219,11 @@ void HandleGlobalCommands() {
} }
if (CtrlPress(KEY_ONE)) { if (CtrlPress(KEY_ONE)) {
SetActiveWindow({1}); SetActiveWindow({0});
} else if (CtrlPress(KEY_TWO)) { } else if (CtrlPress(KEY_TWO)) {
SetActiveWindow({2}); SetActiveWindow({1});
} else if (CtrlPress(KEY_THREE)) { } else if (CtrlPress(KEY_THREE)) {
SetActiveWindow({3}); SetActiveWindow({2});
} }
} }

View File

@@ -47,7 +47,7 @@ void Command_Paste(View *view) {
// Regular paste // Regular paste
if (string != SavedClipboardString || SavedClipboardCursors.len != view->carets.len) { if (string != SavedClipboardString || SavedClipboardCursors.len != view->carets.len) {
BeforeEdit(buffer, view->carets); BeforeEdit(buffer, view->carets);
MergeCarets(&view->carets); MergeCarets(*buffer, &view->carets);
Array<Edit> edits = {scratch}; Array<Edit> edits = {scratch};
For(view->carets) AddEdit(&edits, it.range, string); For(view->carets) AddEdit(&edits, it.range, string);
ApplyEdits(buffer, edits); ApplyEdits(buffer, edits);
@@ -57,7 +57,7 @@ void Command_Paste(View *view) {
// Multicursor paste // Multicursor paste
BeforeEdit(buffer, view->carets); BeforeEdit(buffer, view->carets);
MergeCarets(&view->carets); MergeCarets(*buffer, &view->carets);
Array<Edit> edits = {scratch}; Array<Edit> edits = {scratch};
for (int64_t i = 0; i < view->carets.len; i += 1) { for (int64_t i = 0; i < view->carets.len; i += 1) {
String16 string = SavedClipboardCursors[i]; String16 string = SavedClipboardCursors[i];

View File

@@ -2,7 +2,7 @@ void Command_Replace(View *view, String16 string) {
Buffer *buffer = GetBuffer(view->buffer_id); Buffer *buffer = GetBuffer(view->buffer_id);
Scratch scratch; Scratch scratch;
BeforeEdit(buffer, view->carets); BeforeEdit(buffer, view->carets);
MergeCarets(&view->carets); MergeCarets(*buffer, &view->carets);
Array<Edit> edits = {scratch}; Array<Edit> edits = {scratch};
For(view->carets) AddEdit(&edits, it.range, string); For(view->carets) AddEdit(&edits, it.range, string);
ApplyEdits(buffer, edits); ApplyEdits(buffer, edits);
@@ -14,7 +14,7 @@ void Command_DuplicateLine(View *view, int direction) {
Buffer *buffer = GetBuffer(view->buffer_id); Buffer *buffer = GetBuffer(view->buffer_id);
BeforeEdit(buffer, view->carets); BeforeEdit(buffer, view->carets);
For(view->carets) it = MakeCaret(GetFront(it)); For(view->carets) it = MakeCaret(GetFront(it));
MergeCarets(&view->carets); MergeCarets(*buffer, &view->carets);
Scratch scratch; Scratch scratch;
Array<Edit> edits = {scratch}; Array<Edit> edits = {scratch};
@@ -109,7 +109,31 @@ void Command_CreateCursorVertical(View *_view, int direction) {
} }
} }
For(arr) Add(&view.carets, it); For(arr) Add(&view.carets, it);
MergeCarets(&view.carets); MergeCarets(*buffer, &view.carets);
}
int64_t FuzzyCloserWordBegin = 5;
int64_t FuzzyConsecutiveMultiplier = 3;
int64_t FuzzyRate(String16 string, String16 with) {
int64_t points = 0;
int64_t consecutive = 0;
int64_t with_i = 0;
for (int64_t i = 0; i < string.len; i++) {
if (string.data[i] == with[with_i]) {
int64_t closer_begin = ClampBottom((int64_t)0, FuzzyCloserWordBegin - i);
points += closer_begin;
consecutive++;
with_i += 1;
} else {
points += consecutive * FuzzyConsecutiveMultiplier;
consecutive = 0;
with_i = 0;
}
if (with_i >= with.len) with_i = 0;
}
points += consecutive * FuzzyConsecutiveMultiplier;
return points;
} }
void HandleActiveWindowBindings(Window *window) { void HandleActiveWindowBindings(Window *window) {
@@ -271,15 +295,6 @@ void HandleActiveWindowBindings(Window *window) {
Command_MoveCursorsToSide(window, DIR_RIGHT); Command_MoveCursorsToSide(window, DIR_RIGHT);
} }
if (CtrlPress(KEY_ENTER)) {
Int line = PosToLine(*buffer, GetFront(view.carets[0]));
Range range = GetLineRange(*buffer, line);
String16 string = GetString(*buffer, range);
EvalString(string);
} else if (Press(KEY_ENTER)) {
Command_Replace(&view, L"\n");
}
if (Press(KEY_TAB)) { if (Press(KEY_TAB)) {
Command_Replace(&view, L" "); Command_Replace(&view, L" ");
} }
@@ -296,6 +311,7 @@ void HandleActiveWindowBindings(Window *window) {
Command_Delete(&view, DIR_RIGHT); Command_Delete(&view, DIR_RIGHT);
} }
bool search = false;
for (int c = GetCharPressed(); c; c = GetCharPressed()) { for (int c = GetCharPressed(); c; c = GetCharPressed()) {
// we interpret 2 byte sequences as 1 byte when rendering but we still // we interpret 2 byte sequences as 1 byte when rendering but we still
// want to read them properly. // want to read them properly.
@@ -303,8 +319,65 @@ void HandleActiveWindowBindings(Window *window) {
UTF16Result result = UTF32ToUTF16((uint32_t)c); UTF16Result result = UTF32ToUTF16((uint32_t)c);
if (!result.error) string = {(wchar_t *)result.out_str, result.len}; if (!result.error) string = {(wchar_t *)result.out_str, result.len};
Command_Replace(&view, string); Command_Replace(&view, string);
search = true;
} }
if (window->fuzzy_search && search) {
Range line_range = GetLineRange(*buffer, 0);
String16 string = GetString(*buffer, line_range);
Scratch scratch;
struct Pair {
Int index;
Int rating;
};
Array<Pair> ratings = {scratch};
for (Int i = 1; i < buffer->line_starts.len; i += 1) {
Range l = GetLineRange(*buffer, i);
String16 s = GetString(*buffer, l);
int64_t rating = FuzzyRate(s, string);
Add(&ratings, {i, rating});
}
// bubble sort
for (int64_t i = 0; i < ratings.len - 1; i++) {
for (int64_t j = 0; j < ratings.len - 1; j++) {
if (ratings[j].rating < ratings[j + 1].rating) {
Pair temp = ratings[j];
ratings[j] = ratings[j + 1];
ratings[j + 1] = temp;
}
}
}
// Create a new buffer with
Buffer *temp_buffer = CreateTempBuffer(scratch, buffer->cap);
ReplaceText(temp_buffer, {}, string);
For(ratings) {
Range l = GetLineRange(*buffer, it.index);
String16 s = GetString(*buffer, l);
ReplaceText(temp_buffer, GetEndAsRange(*temp_buffer), s);
}
ReplaceText(buffer, {0, buffer->len}, GetString(*temp_buffer));
}
if (window->fuzzy_search) {
if (Press(KEY_ENTER)) {
Int line = PosToLine(*buffer, GetFront(view.carets[0]));
Range range = GetLineRange(*buffer, line);
String16 string = GetString(*buffer, range);
EvalString(string);
if (window->id.id == CommandWindowID.id) {
Window *command_window = GetWindow(CommandWindowID);
command_window->visible = !command_window->visible;
ActiveWindow = LastActiveWindow;
}
}
} else {
if (Press(KEY_ENTER)) {
Command_Replace(&view, L"\n");
}
}
{ {
ProfileScope(mouse); ProfileScope(mouse);
@@ -335,7 +408,7 @@ void HandleActiveWindowBindings(Window *window) {
view.selection_anchor = GetLast(view.carets)->range; view.selection_anchor = GetLast(view.carets)->range;
} }
MergeCarets(&view.carets); MergeCarets(*buffer, &view.carets);
} else if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { } else if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) {
window->mouse_selecting = true; window->mouse_selecting = true;
} }
@@ -351,7 +424,7 @@ void HandleActiveWindowBindings(Window *window) {
} else { } else {
caret = MakeCaret(view.selection_anchor.max, view.selection_anchor.min); caret = MakeCaret(view.selection_anchor.max, view.selection_anchor.min);
} }
MergeCarets(&view.carets, &view.selection_anchor); MergeCarets(*buffer, &view.carets, &view.selection_anchor);
} }
} else if (!(mouse_in_view || window->mouse_selecting) && mouse_in_scrollbar || window->mouse_selecting_scrollbar) { } else if (!(mouse_in_view || window->mouse_selecting) && mouse_in_scrollbar || window->mouse_selecting_scrollbar) {
Scroller s = ComputeScrollerRect(*window); Scroller s = ComputeScrollerRect(*window);

View File

@@ -1,11 +1,10 @@
lua_State *LuaState = NULL; lua_State *LuaState = NULL;
int LuaOpenFile(lua_State *L) { int LuaOpenFile(lua_State *L) {
const char *text = luaL_checkstring(L, 1); const char *text = luaL_checkstring(L, 1);
String string = text;
Buffer *buffer = OpenFile(string); View *view = ViewOpenFile(text);
View *view = CreateView(buffer->id); Window *window = GetWindow(LastActiveWindow);
Window *window = GetWindow(LastActiveWindow);
AddView(window, view->id); AddView(window, view->id);
window->active_view = view->id; window->active_view = view->id;
SetActiveWindow(window->id); SetActiveWindow(window->id);

View File

@@ -18,6 +18,7 @@
#include "buffer_multi_cursor.cpp" #include "buffer_multi_cursor.cpp"
#include "buffer_history.cpp" #include "buffer_history.cpp"
#include "buffer_test_load.cpp" #include "buffer_test_load.cpp"
#include "management.cpp"
#include "commands.cpp" #include "commands.cpp"
#include "commands_clipboard.cpp" #include "commands_clipboard.cpp"
@@ -29,6 +30,7 @@
#include "lua_api.cpp" #include "lua_api.cpp"
/* /*
- replace info bar with 2 windows
- Save file (utf16->utf8) - Save file (utf16->utf8)
- reuse buffers!! - reuse buffers!!
- resize windows - resize windows
@@ -54,8 +56,6 @@
int main(void) { int main(void) {
InitScratch(); InitScratch();
Test(); Test();
TestBuffer();
TestBufferMultiCaret();
BeginProfiler(); BeginProfiler();
BeginProfileScope("main"); BeginProfileScope("main");
@@ -82,18 +82,18 @@ int main(void) {
FontCharSpacing = GetCharSpacing(MainFont, FontSize, FontSpacing); FontCharSpacing = GetCharSpacing(MainFont, FontSize, FontSpacing);
Allocator sys_allocator = GetSystemAllocator(); Allocator sys_allocator = GetSystemAllocator();
// Create null // Create null
{ {
Buffer *buffer = CreateBuffer(sys_allocator); Buffer *buffer = CreateBuffer(sys_allocator, "*scratch*");
View *view = CreateView(buffer->id); // View *view = CreateView(buffer->id);
Window *window = CreateWindow(); // Window *window = CreateWindow();
window->visible = false; // window->visible = false;
AddView(window, view->id); // AddView(window, view->id);
} }
{ {
Window *w = CreateWindow(); Window *w = CreateWindow();
Buffer *b = CreateBuffer(sys_allocator); Buffer *b = CreateBuffer(sys_allocator, "*load_text_a*");
View *v = CreateView(b->id); View *v = CreateView(b->id);
LoadTextA(b); LoadTextA(b);
AddView(w, v->id); AddView(w, v->id);
@@ -102,14 +102,14 @@ int main(void) {
{ {
Window *w = CreateWindow(); Window *w = CreateWindow();
Buffer *b = CreateBuffer(sys_allocator); Buffer *b = CreateBuffer(sys_allocator, "*load_unicode*");
View *v = CreateView(b->id); View *v = CreateView(b->id);
LoadUnicode(b); LoadUnicode(b);
AddView(w, v->id); AddView(w, v->id);
} }
{ {
Window *w = CreateWindow(); Window *w = CreateWindow();
Buffer *b = CreateBuffer(sys_allocator); Buffer *b = CreateBuffer(sys_allocator, "*load_line*");
LoadLine(b); LoadLine(b);
View *v = CreateView(b->id); View *v = CreateView(b->id);
AddView(w, v->id); AddView(w, v->id);
@@ -119,9 +119,14 @@ int main(void) {
w->draw_scrollbar = false; w->draw_scrollbar = false;
w->draw_line_numbers = false; w->draw_line_numbers = false;
w->visible = false; w->visible = false;
Buffer *b = CreateBuffer(sys_allocator); w->fuzzy_search = true;
Buffer *b = CreateBuffer(sys_allocator, "*commands*");
View *v = CreateView(b->id); View *v = CreateView(b->id);
ReplaceText(b, {}, L"open \"C:/Work/text_editor/src/text_editor/text_editor.cpp\""); ReplaceText(b, GetEndAsRange(*b), L"\n");
ReplaceText(b, GetEndAsRange(*b), L"open \"C:/Work/text_editor/src/text_editor/text_editor.cpp\"\n");
ReplaceText(b, GetEndAsRange(*b), L"open \"C:/Work/text_editor/src/text_editor/text_editor.h\"\n");
ReplaceText(b, GetEndAsRange(*b), L"open \"C:/Work/text_editor/src/text_editor/commands.cpp\"\n");
ReplaceText(b, GetEndAsRange(*b), L"open \"C:/Work/text_editor/src/text_editor/commands_clipboard.cpp\"\n");
AddView(w, v->id); AddView(w, v->id);
CommandWindowID = w->id; CommandWindowID = w->id;
} }
@@ -134,28 +139,28 @@ int main(void) {
Rect2I infobar_rect = CutBottom(&screen_rect, (Int)MenuFontSize); Rect2I infobar_rect = CutBottom(&screen_rect, (Int)MenuFontSize);
float line_numbers_size = MeasureTextEx(MainFont, "12345", (float)FontSize, (float)FontSpacing).x; float line_numbers_size = MeasureTextEx(MainFont, "12345", (float)FontSize, (float)FontSpacing).x;
{ {
int i = 1; int i = 0;
Windows[i].total_rect = CutLeft(&screen_rect, (Int)((double)GetSize(screen_rect).x * 0.33)); Windows[i].total_rect = CutLeft(&screen_rect, (Int)((double)GetSize(screen_rect).x * 0.33));
Windows[i].document_rect = Windows[i].total_rect; Windows[i].document_rect = Windows[i].total_rect;
if (Windows[i].draw_scrollbar) Windows[i].scrollbar_rect = CutRight(&Windows[i].document_rect, 10); if (Windows[i].draw_scrollbar) Windows[i].scrollbar_rect = CutRight(&Windows[i].document_rect, 10);
if (Windows[i].draw_line_numbers) Windows[i].line_numbers_rect = CutLeft(&Windows[i].document_rect, (Int)line_numbers_size); if (Windows[i].draw_line_numbers) Windows[i].line_numbers_rect = CutLeft(&Windows[i].document_rect, (Int)line_numbers_size);
} }
{ {
int i = 2; int i = 1;
Windows[i].total_rect = CutLeft(&screen_rect, (Int)((double)GetSize(screen_rect).x * 0.5)); Windows[i].total_rect = CutLeft(&screen_rect, (Int)((double)GetSize(screen_rect).x * 0.5));
Windows[i].document_rect = Windows[i].total_rect; Windows[i].document_rect = Windows[i].total_rect;
if (Windows[i].draw_scrollbar) Windows[i].scrollbar_rect = CutRight(&Windows[i].document_rect, 10); if (Windows[i].draw_scrollbar) Windows[i].scrollbar_rect = CutRight(&Windows[i].document_rect, 10);
if (Windows[i].draw_line_numbers) Windows[i].line_numbers_rect = CutLeft(&Windows[i].document_rect, (Int)line_numbers_size); if (Windows[i].draw_line_numbers) Windows[i].line_numbers_rect = CutLeft(&Windows[i].document_rect, (Int)line_numbers_size);
} }
{ {
int i = 3; int i = 2;
Windows[i].total_rect = CutLeft(&screen_rect, (Int)((double)GetSize(screen_rect).x * 1.0)); Windows[i].total_rect = CutLeft(&screen_rect, (Int)((double)GetSize(screen_rect).x * 1.0));
Windows[i].document_rect = Windows[i].total_rect; Windows[i].document_rect = Windows[i].total_rect;
if (Windows[i].draw_scrollbar) Windows[i].scrollbar_rect = CutRight(&Windows[i].document_rect, 10); if (Windows[i].draw_scrollbar) Windows[i].scrollbar_rect = CutRight(&Windows[i].document_rect, 10);
if (Windows[i].draw_line_numbers) Windows[i].line_numbers_rect = CutLeft(&Windows[i].document_rect, (Int)line_numbers_size); if (Windows[i].draw_line_numbers) Windows[i].line_numbers_rect = CutLeft(&Windows[i].document_rect, (Int)line_numbers_size);
} }
{ {
int i = 4; int i = 3;
Rect2 screen_rect = GetScreenRectF(); Rect2 screen_rect = GetScreenRectF();
Vec2 size = GetSize(screen_rect); Vec2 size = GetSize(screen_rect);
CutTop(&screen_rect, size.y * 0.05f); CutTop(&screen_rect, size.y * 0.05f);

View File

@@ -22,6 +22,8 @@ struct HistoryEntry {
// @todo: gap buffer to improve speed of inserting on big files with only one cursor? // @todo: gap buffer to improve speed of inserting on big files with only one cursor?
struct Buffer { struct Buffer {
BufferID id; BufferID id;
String name;
union { union {
U16 *data; U16 *data;
wchar_t *str; wchar_t *str;
@@ -62,6 +64,7 @@ struct Window {
bool draw_scrollbar : 1; bool draw_scrollbar : 1;
bool draw_line_numbers : 1; bool draw_line_numbers : 1;
bool visible : 1; bool visible : 1;
bool fuzzy_search : 1;
}; };
}; };
@@ -101,34 +104,11 @@ Int LastFrameIDWhenScrolled;
WindowID LastActiveWindow; WindowID LastActiveWindow;
Int LastFrameIDWhenSwitchedActiveWindow; Int LastFrameIDWhenSwitchedActiveWindow;
inline Window *GetWindow(WindowID id) {
For(Windows) if (it.id.id == id.id) return &it;
return &Windows[0];
}
inline Buffer *GetBuffer(BufferID id) {
For(Buffers) if (it.id.id == id.id) return &it;
return &Buffers[0];
}
inline View *GetView(ViewID id) {
For(Views) if (it.id.id == id.id) return &it;
return &Views[0];
}
void SetActiveWindow(WindowID window);
inline ViewID AllocViewID() { return {ViewIDs.id++}; }
inline WindowID AllocWindowID() { return {WindowIDs.id++}; }
inline BufferID AllocBufferID() { return {BufferIDs.id++}; }
inline bool IsActive(Window *window) { return window->id.id == ActiveWindow.id; }
inline bool IsActive(Window *window, View *view) { return window->active_view.id == view->id.id; }
inline Window *GetActiveWindow() { return GetWindow(ActiveWindow); }
inline View *GetActiveView(Window *window) {
if (window->active_view.id == 0) return GetView(window->views[0]);
else return GetView(window->active_view);
}
void EvalString(String16 string16); void EvalString(String16 string16);
Rect2I GetVisibleCells(Window &window); Rect2I GetVisibleCells(Window &window);
void AfterEdit(View *view, Array<Edit> edits); void AfterEdit(View *view, Array<Edit> edits);
Scroller ComputeScrollerRect(Window &window); Scroller ComputeScrollerRect(Window &window);
inline ViewID AllocViewID() { return {ViewIDs.id++}; }
inline WindowID AllocWindowID() { return {WindowIDs.id++}; }
inline BufferID AllocBufferID() { return {BufferIDs.id++}; }

View File

@@ -1,26 +1,3 @@
Window *CreateWindow() {
Window *w = Alloc(&Windows);
w->visible = true;
w->draw_scrollbar = true;
w->draw_line_numbers = true;
w->id = AllocWindowID();
return w;
}
void AddView(Window *w, ViewID view) {
if (w->active_view.id == 0) w->active_view = view;
For(w->views) if (it.id == view.id) return;
Add(&w->views, view);
}
View *CreateView(BufferID buffer_id) {
View *w = Alloc(&Views);
w->id = AllocViewID();
w->buffer_id = buffer_id;
Add(&w->carets, {0, 0});
return w;
}
void SetMouseCursor() { void SetMouseCursor() {
Window *w = GetActiveWindow(); Window *w = GetActiveWindow();
Vec2 mouse = GetMousePosition(); Vec2 mouse = GetMousePosition();
@@ -45,13 +22,3 @@ Array<Int> GetWindowZOrder(Allocator allocator) {
For(Windows) if (it.z == 0 && it.visible) Add(&order, GetIndex(Windows, it)); For(Windows) if (it.z == 0 && it.visible) Add(&order, GetIndex(Windows, it));
return order; return order;
} }
void SetActiveWindow(WindowID window) {
if (LastFrameIDWhenSwitchedActiveWindow != FrameID) {
if (ActiveWindow.id != CommandWindowID.id) {
LastActiveWindow = ActiveWindow;
}
ActiveWindow = window;
LastFrameIDWhenSwitchedActiveWindow = FrameID;
}
}