Optimizing search, buggy BlockArena on emscripten, cleanup MergeSort, address sanitizer, compile web on linux
This commit is contained in:
6
build.sh
6
build.sh
@@ -3,10 +3,12 @@
|
|||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
|
|
||||||
FLAGS="-nostdlib++ -fno-exceptions -fdiagnostics-absolute-paths -g -Wno-writable-strings -I../src -DDEBUG_BUILD=1"
|
FLAGS="-Wall -Wno-missing-braces -Wno-writable-strings -nostdlib++ -fsanitize=address -fno-exceptions -fdiagnostics-absolute-paths -g -Wno-writable-strings -I../src -DDEBUG_BUILD=1"
|
||||||
# clang -o metaprogram $FLAGS ../src/metaprogram/metaprogram.cpp
|
# clang -o metaprogram $FLAGS ../src/metaprogram/metaprogram.cpp
|
||||||
# ./metaprogram
|
# ./metaprogram
|
||||||
|
|
||||||
I="-I../src/external/SDL/include -I../src/external/lua/src -I../src/external/glad"
|
I="-I../src/external/SDL/include -I../src/external/lua/src -I../src/external/glad"
|
||||||
clang -o te $FLAGS ../src/text_editor/text_editor.cpp $I -lSDL3 -lm -lbacktrace
|
clang -o te $FLAGS ../src/text_editor/text_editor.cpp $I -lSDL3 -lm -lbacktrace
|
||||||
cp te ../data/te
|
cp te ../data/te
|
||||||
|
|
||||||
|
# -v -Wl,--verbose
|
||||||
@@ -6,10 +6,4 @@ set flags=-Wall -Wno-missing-braces -Wno-writable-strings -nostdlib++ -fno-excep
|
|||||||
set dbg=-g -DDEBUG_BUILD=1 -gsource-map
|
set dbg=-g -DDEBUG_BUILD=1 -gsource-map
|
||||||
set rel=-O3 -DDEBUG_BUILD=0
|
set rel=-O3 -DDEBUG_BUILD=0
|
||||||
|
|
||||||
mkdir build
|
emcc -o text_editor.html --shell-file=data/shell.html %flags% %incs% %wasmflags% %dbg% -lm -lSDL3 src/text_editor/text_editor.cpp
|
||||||
cd build
|
|
||||||
clang ../src/metaprogram/metaprogram.cpp -o metaprogram.exe %flags% -g -DDEBUG_BUILD=1 -I../src
|
|
||||||
metaprogram.exe
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
emcc -o text_editor.html --shell-file=data/shell.html %flags% %incs% %wasmflags% %dbg% -lm -lSDL3 src/text_editor/text_editor.cpp
|
|
||||||
|
|||||||
11
build_web.sh
11
build_web.sh
@@ -1,8 +1,9 @@
|
|||||||
#!/usr/bin/bash
|
#!/usr/bin/bash
|
||||||
|
|
||||||
mkdir build
|
incs="-Isrc/external/SDL/include -Isrc/external/lua/src -Isrc/external/glad -Lsrc/external/SDL/build_web -Isrc"
|
||||||
cd build
|
wasmflags="-sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=1gb -msimd128 -sTOTAL_STACK=5MB -sINITIAL_MEMORY=256mb -sUSE_WEBGL2 -sFULL_ES3=1 -sUSE_SDL=3 -sASYNCIFY -sASSERTIONS=2"
|
||||||
|
flags="-Wall -Wno-missing-braces -Wno-writable-strings -nostdlib++ -fno-exceptions -fdiagnostics-absolute-paths"
|
||||||
|
dbg="-g -DDEBUG_BUILD=1 -gsource-map"
|
||||||
|
rel="-O3 -DDEBUG_BUILD=0"
|
||||||
|
|
||||||
echo todo
|
emcc -o text_editor.html --shell-file=data/shell.html $flags $incs $wasmflags $dbg -lm -lSDL3 src/text_editor/text_editor.cpp
|
||||||
|
|
||||||
cd ..
|
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ Debug session:
|
|||||||
- Should highlight main buffer when clicking on status?
|
- Should highlight main buffer when clicking on status?
|
||||||
- Report errorf - use coroutine dialogs
|
- Report errorf - use coroutine dialogs
|
||||||
- Replace in render layer also
|
- Replace in render layer also
|
||||||
|
- BlockAllocator something is not working there which only showed after executing OpenCode on many files
|
||||||
|
- Some bad allocating happening in Clipboard for sure
|
||||||
|
|
||||||
New UI Session
|
New UI Session
|
||||||
- Move CommandWindow hooks to hooks
|
- Move CommandWindow hooks to hooks
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ void AddBlock(BlockArena *arena, size_t size = MiB(1)) {
|
|||||||
if (arena->allocator.proc == NULL) {
|
if (arena->allocator.proc == NULL) {
|
||||||
arena->allocator = GetSystemAllocator();
|
arena->allocator = GetSystemAllocator();
|
||||||
}
|
}
|
||||||
BlockArenaNode *new_block = (BlockArenaNode *)AllocSize(arena->allocator, block_size + sizeof(BlockArenaNode) + 16);
|
BlockArenaNode *new_block = (BlockArenaNode *)AllocSize(arena->allocator, block_size + sizeof(BlockArenaNode));
|
||||||
Assert(GetAlignOffset((size_t)new_block->start, DEFAULT_ALIGNMENT) == 0);
|
Assert(GetAlignOffset((size_t)new_block->start, DEFAULT_ALIGNMENT) == 0);
|
||||||
arena->start = new_block->start;
|
arena->start = new_block->start;
|
||||||
new_block->end = arena->end = new_block->start + block_size;
|
new_block->end = arena->end = new_block->start + block_size;
|
||||||
@@ -294,9 +294,7 @@ API void Release(BlockArena *arena) {
|
|||||||
next = it->next;
|
next = it->next;
|
||||||
Dealloc(arena->allocator, it);
|
Dealloc(arena->allocator, it);
|
||||||
}
|
}
|
||||||
bool safe = arena->when_unwinding_make_sure_to_keep_last_block_alive;
|
|
||||||
MemoryZero(arena, sizeof(BlockArena));
|
MemoryZero(arena, sizeof(BlockArena));
|
||||||
arena->when_unwinding_make_sure_to_keep_last_block_alive = safe;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
API void Unwind(BlockArena *arena, U8 *pos) {
|
API void Unwind(BlockArena *arena, U8 *pos) {
|
||||||
@@ -307,16 +305,11 @@ API void Unwind(BlockArena *arena, U8 *pos) {
|
|||||||
contains = true;
|
contains = true;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
bool keep = arena->when_unwinding_make_sure_to_keep_last_block_alive && arena->blocks->next == NULL;
|
arena->blocks = arena->blocks->next;
|
||||||
if (keep) {
|
Dealloc(arena->allocator, it);
|
||||||
pos = arena->blocks->start;
|
|
||||||
} else {
|
|
||||||
arena->blocks = arena->blocks->next;
|
|
||||||
Dealloc(arena->allocator, it);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Assert(contains || pos == NULL || (arena->when_unwinding_make_sure_to_keep_last_block_alive && pos == arena->blocks->start));
|
Assert(contains || pos == NULL);
|
||||||
arena->start = pos;
|
arena->start = pos;
|
||||||
arena->end = arena->blocks ? arena->blocks->end : NULL;
|
arena->end = arena->blocks ? arena->blocks->end : NULL;
|
||||||
}
|
}
|
||||||
@@ -332,8 +325,11 @@ API void *BlockArenaAllocatorProc(void *object, int kind, void *p, size_t size)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if OS_WASM
|
||||||
|
API void InitScratch() {
|
||||||
|
}
|
||||||
|
#else
|
||||||
thread_local VirtualArena ScratchArenas[4];
|
thread_local VirtualArena ScratchArenas[4];
|
||||||
|
|
||||||
API void InitScratch() {
|
API void InitScratch() {
|
||||||
for (int i = 0; i < 4; i += 1) {
|
for (int i = 0; i < 4; i += 1) {
|
||||||
InitArena(&ScratchArenas[i]);
|
InitArena(&ScratchArenas[i]);
|
||||||
@@ -362,6 +358,7 @@ API VirtualArena *GetScratchEx(VirtualArena **conflicts, int conflict_count) {
|
|||||||
Assert(unoccupied);
|
Assert(unoccupied);
|
||||||
return unoccupied;
|
return unoccupied;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void RunArenaTest() {
|
void RunArenaTest() {
|
||||||
Allocator memory_tracking_allocator = GetTrackingAllocator();
|
Allocator memory_tracking_allocator = GetTrackingAllocator();
|
||||||
@@ -380,7 +377,6 @@ void RunArenaTest() {
|
|||||||
|
|
||||||
{
|
{
|
||||||
BlockArena arena = {};
|
BlockArena arena = {};
|
||||||
U8 *start = arena.start;
|
|
||||||
arena.allocator = memory_tracking_allocator;
|
arena.allocator = memory_tracking_allocator;
|
||||||
int *vals = (int *)PushSize(&arena, sizeof(int) * 32);
|
int *vals = (int *)PushSize(&arena, sizeof(int) * 32);
|
||||||
for (int i = 0; i < 32; i += 1) vals[i] = i;
|
for (int i = 0; i < 32; i += 1) vals[i] = i;
|
||||||
@@ -402,7 +398,7 @@ void RunArenaTest() {
|
|||||||
|
|
||||||
U8 *p = arena.start;
|
U8 *p = arena.start;
|
||||||
U8 *a = (U8 *)PushSize(&arena, KiB(32));
|
U8 *a = (U8 *)PushSize(&arena, KiB(32));
|
||||||
U8 *b = (U8 *)PushSize(&arena, KiB(1000));
|
PushSize(&arena, KiB(1000));
|
||||||
Assert(arena.blocks);
|
Assert(arena.blocks);
|
||||||
Assert(arena.blocks->next);
|
Assert(arena.blocks->next);
|
||||||
Assert(arena.blocks->next->next == NULL);
|
Assert(arena.blocks->next->next == NULL);
|
||||||
@@ -418,7 +414,7 @@ void RunArenaTest() {
|
|||||||
{
|
{
|
||||||
BlockArena arena = {};
|
BlockArena arena = {};
|
||||||
arena.allocator = memory_tracking_allocator;
|
arena.allocator = memory_tracking_allocator;
|
||||||
U8 *a = (U8 *)PushSize(&arena, KiB(2000));
|
PushSize(&arena, KiB(2000));
|
||||||
Assert((size_t)(arena.blocks[0].end - arena.blocks[0].start) == KiB(2000));
|
Assert((size_t)(arena.blocks[0].end - arena.blocks[0].start) == KiB(2000));
|
||||||
Release(&arena);
|
Release(&arena);
|
||||||
Assert(MemoryTrackingRecord.len == 0);
|
Assert(MemoryTrackingRecord.len == 0);
|
||||||
@@ -427,15 +423,14 @@ void RunArenaTest() {
|
|||||||
{
|
{
|
||||||
BlockArena arena = {};
|
BlockArena arena = {};
|
||||||
arena.allocator = memory_tracking_allocator;
|
arena.allocator = memory_tracking_allocator;
|
||||||
arena.when_unwinding_make_sure_to_keep_last_block_alive = true;
|
|
||||||
PushSize(&arena, KiB(2000));
|
PushSize(&arena, KiB(2000));
|
||||||
Unwind(&arena, 0);
|
Unwind(&arena, 0);
|
||||||
Assert(MemoryTrackingRecord.len == 1);
|
Assert(MemoryTrackingRecord.len == 0);
|
||||||
PushSize(&arena, MiB(1));
|
PushSize(&arena, MiB(1));
|
||||||
PushSize(&arena, MiB(3));
|
PushSize(&arena, MiB(3));
|
||||||
Assert(MemoryTrackingRecord.len == 2);
|
Assert(MemoryTrackingRecord.len == 2);
|
||||||
Unwind(&arena, 0);
|
Unwind(&arena, 0);
|
||||||
Assert(MemoryTrackingRecord.len == 1);
|
Assert(MemoryTrackingRecord.len == 0);
|
||||||
Release(&arena);
|
Release(&arena);
|
||||||
Assert(MemoryTrackingRecord.len == 0);
|
Assert(MemoryTrackingRecord.len == 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ struct BlockArena {
|
|||||||
U8 *end;
|
U8 *end;
|
||||||
BlockArenaNode *blocks;
|
BlockArenaNode *blocks;
|
||||||
Allocator allocator;
|
Allocator allocator;
|
||||||
bool when_unwinding_make_sure_to_keep_last_block_alive;
|
|
||||||
|
|
||||||
operator Allocator() { return {BlockArenaAllocatorProc, this}; }
|
operator Allocator() { return {BlockArenaAllocatorProc, this}; }
|
||||||
};
|
};
|
||||||
@@ -96,9 +95,24 @@ API void Release(VirtualArena *arena);
|
|||||||
|
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
// Scratch
|
// Scratch
|
||||||
|
#if OS_WASM
|
||||||
|
struct Scratch {
|
||||||
|
BlockArena arena = {};
|
||||||
|
Scratch() {}
|
||||||
|
Scratch(BlockArena *conflict) {}
|
||||||
|
Scratch(BlockArena *c1, BlockArena *c2) {}
|
||||||
|
Scratch(Allocator conflict) {}
|
||||||
|
Scratch(Allocator c1, Allocator c2) {}
|
||||||
|
~Scratch() { Release(&arena); }
|
||||||
|
operator BlockArena *() { return &arena; }
|
||||||
|
operator Allocator() { return arena; }
|
||||||
|
private: // @Note: Disable copy constructors, cause its error prone
|
||||||
|
Scratch(Scratch &arena);
|
||||||
|
Scratch(Scratch &arena, Scratch &a2);
|
||||||
|
};
|
||||||
|
#else
|
||||||
extern thread_local VirtualArena ScratchArenas[4];
|
extern thread_local VirtualArena ScratchArenas[4];
|
||||||
API VirtualArena *GetScratchEx(VirtualArena **conflicts, int conflict_count);
|
API VirtualArena *GetScratchEx(VirtualArena **conflicts, int conflict_count);
|
||||||
|
|
||||||
struct Scratch {
|
struct Scratch {
|
||||||
VirtualArena *arena;
|
VirtualArena *arena;
|
||||||
U64 p;
|
U64 p;
|
||||||
@@ -131,6 +145,7 @@ struct Scratch {
|
|||||||
Scratch(Scratch &arena);
|
Scratch(Scratch &arena);
|
||||||
Scratch(Scratch &arena, Scratch &a2);
|
Scratch(Scratch &arena, Scratch &a2);
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
const int PAGE_SIZE = 4096;
|
const int PAGE_SIZE = 4096;
|
||||||
const int DEFAULT_ALIGNMENT = sizeof(void *);
|
const int DEFAULT_ALIGNMENT = sizeof(void *);
|
||||||
|
|||||||
@@ -408,6 +408,7 @@ API bool IsValid(Process *process) {
|
|||||||
int res = poll(&p, 1, 0);
|
int res = poll(&p, 1, 0);
|
||||||
if (res > 0) {
|
if (res > 0) {
|
||||||
pid_t result = waitpid(plat->pid, &status, 0);
|
pid_t result = waitpid(plat->pid, &status, 0);
|
||||||
|
Assert(result != -1);
|
||||||
process->exit_code = WEXITSTATUS(status);
|
process->exit_code = WEXITSTATUS(status);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1104,9 +1105,9 @@ API void Advance(FileIter *it) {
|
|||||||
|
|
||||||
const char *dir_char_ending = it->is_directory ? "/" : "";
|
const char *dir_char_ending = it->is_directory ? "/" : "";
|
||||||
const char *separator = it->path.data[it->path.len - 1] == '/' ? "" : "/";
|
const char *separator = it->path.data[it->path.len - 1] == '/' ? "" : "/";
|
||||||
it->relative_path = Format(it->allocator, "%.*s%s%s%s", FmtString(it->path), separator, file->d_name, dir_char_ending);
|
it->relative_path = Format(it->allocator, "%S%s%s%s", it->path, separator, file->d_name, dir_char_ending);
|
||||||
it->absolute_path = GetAbsolutePath(it->allocator, it->relative_path);
|
it->absolute_path = GetAbsolutePath(it->allocator, it->relative_path);
|
||||||
if (it->is_directory) it->absolute_path = Format(it->allocator, "%.*s/", FmtString(it->absolute_path));
|
if (it->is_directory) it->absolute_path = Format(it->allocator, "%S/", it->absolute_path);
|
||||||
it->is_valid = true;
|
it->is_valid = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
4
src/external/minicoro.h
vendored
4
src/external/minicoro.h
vendored
@@ -539,8 +539,8 @@ static void mco_dealloc(void *ptr, size_t size, void *allocator_data) {
|
|||||||
#define _MCO_USE_TSAN
|
#define _MCO_USE_TSAN
|
||||||
#endif
|
#endif
|
||||||
#ifdef _MCO_USE_ASAN
|
#ifdef _MCO_USE_ASAN
|
||||||
void __sanitizer_start_switch_fiber(void **fake_stack_save, const void *bottom, size_t size);
|
extern "C" void __sanitizer_start_switch_fiber(void **fake_stack_save, const void *bottom, size_t size);
|
||||||
void __sanitizer_finish_switch_fiber(void *fake_stack_save, const void **bottom_old, size_t *size_old);
|
extern "C" void __sanitizer_finish_switch_fiber(void *fake_stack_save, const void **bottom_old, size_t *size_old);
|
||||||
#endif
|
#endif
|
||||||
#ifdef _MCO_USE_TSAN
|
#ifdef _MCO_USE_TSAN
|
||||||
void *__tsan_get_current_fiber(void);
|
void *__tsan_get_current_fiber(void);
|
||||||
|
|||||||
@@ -712,98 +712,52 @@ API void RawAppendf(Buffer *buffer, const char *fmt, ...) {
|
|||||||
// multicursor
|
// multicursor
|
||||||
///////////////////////////////
|
///////////////////////////////
|
||||||
|
|
||||||
void MergeSort(int64_t Count, Caret *First, Caret *Temp) {
|
inline bool MergeSortCompare(Caret *EntryA, Caret *EntryB) {
|
||||||
ProfileFunction();
|
bool result = EntryA->range.min > EntryB->range.min;
|
||||||
// SortKey = range.min
|
return result;
|
||||||
if (Count == 1) {
|
|
||||||
// NOTE(casey): No work to do.
|
|
||||||
} else if (Count == 2) {
|
|
||||||
Caret *EntryA = First;
|
|
||||||
Caret *EntryB = First + 1;
|
|
||||||
if (EntryA->range.min > EntryB->range.min) {
|
|
||||||
Swap(EntryA, EntryB);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int64_t Half0 = Count / 2;
|
|
||||||
int64_t Half1 = Count - Half0;
|
|
||||||
|
|
||||||
Assert(Half0 >= 1);
|
|
||||||
Assert(Half1 >= 1);
|
|
||||||
|
|
||||||
Caret *InHalf0 = First;
|
|
||||||
Caret *InHalf1 = First + Half0;
|
|
||||||
Caret *End = First + Count;
|
|
||||||
|
|
||||||
MergeSort(Half0, InHalf0, Temp);
|
|
||||||
MergeSort(Half1, InHalf1, Temp);
|
|
||||||
|
|
||||||
Caret *ReadHalf0 = InHalf0;
|
|
||||||
Caret *ReadHalf1 = InHalf1;
|
|
||||||
|
|
||||||
Caret *Out = Temp;
|
|
||||||
for (int64_t Index = 0;
|
|
||||||
Index < Count;
|
|
||||||
++Index) {
|
|
||||||
if (ReadHalf0 == InHalf1) {
|
|
||||||
*Out++ = *ReadHalf1++;
|
|
||||||
} else if (ReadHalf1 == End) {
|
|
||||||
*Out++ = *ReadHalf0++;
|
|
||||||
} else if (ReadHalf0->range.min < ReadHalf1->range.min) {
|
|
||||||
*Out++ = *ReadHalf0++;
|
|
||||||
} else {
|
|
||||||
*Out++ = *ReadHalf1++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Assert(Out == (Temp + Count));
|
|
||||||
Assert(ReadHalf0 == InHalf1);
|
|
||||||
Assert(ReadHalf1 == End);
|
|
||||||
|
|
||||||
// TODO(casey): Not really necessary if we ping-pong
|
|
||||||
for (int64_t Index = 0;
|
|
||||||
Index < Count;
|
|
||||||
++Index) {
|
|
||||||
First[Index] = Temp[Index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MergeSort(int64_t Count, Edit *First, Edit *Temp) {
|
inline bool MergeSortCompare(Edit *EntryA, Edit *EntryB) {
|
||||||
|
bool result = EntryA->range.min > EntryB->range.min;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
void MergeSort(int64_t Count, T *First, T *Temp) {
|
||||||
ProfileFunction();
|
ProfileFunction();
|
||||||
// SortKey = range.min
|
// SortKey = range.min
|
||||||
if (Count == 1) {
|
if (Count == 1) {
|
||||||
// NOTE(casey): No work to do.
|
// NOTE(casey): No work to do.
|
||||||
} else if (Count == 2) {
|
} else if (Count == 2) {
|
||||||
Edit *EntryA = First;
|
T *EntryA = First;
|
||||||
Edit *EntryB = First + 1;
|
T *EntryB = First + 1;
|
||||||
if (EntryA->range.min > EntryB->range.min) {
|
if (MergeSortCompare(EntryA, EntryB)) {
|
||||||
Swap(EntryA, EntryB);
|
Swap(EntryA, EntryB);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int64_t Half0 = Count / 2;
|
Int Half0 = Count / 2;
|
||||||
int64_t Half1 = Count - Half0;
|
Int Half1 = Count - Half0;
|
||||||
|
|
||||||
Assert(Half0 >= 1);
|
Assert(Half0 >= 1);
|
||||||
Assert(Half1 >= 1);
|
Assert(Half1 >= 1);
|
||||||
|
|
||||||
Edit *InHalf0 = First;
|
T *InHalf0 = First;
|
||||||
Edit *InHalf1 = First + Half0;
|
T *InHalf1 = First + Half0;
|
||||||
Edit *End = First + Count;
|
T *End = First + Count;
|
||||||
|
|
||||||
MergeSort(Half0, InHalf0, Temp);
|
MergeSort(Half0, InHalf0, Temp);
|
||||||
MergeSort(Half1, InHalf1, Temp);
|
MergeSort(Half1, InHalf1, Temp);
|
||||||
|
|
||||||
Edit *ReadHalf0 = InHalf0;
|
T *ReadHalf0 = InHalf0;
|
||||||
Edit *ReadHalf1 = InHalf1;
|
T *ReadHalf1 = InHalf1;
|
||||||
|
|
||||||
Edit *Out = Temp;
|
T *Out = Temp;
|
||||||
for (int64_t Index = 0;
|
for (Int Index = 0; Index < Count; ++Index) {
|
||||||
Index < Count;
|
|
||||||
++Index) {
|
|
||||||
if (ReadHalf0 == InHalf1) {
|
if (ReadHalf0 == InHalf1) {
|
||||||
*Out++ = *ReadHalf1++;
|
*Out++ = *ReadHalf1++;
|
||||||
} else if (ReadHalf1 == End) {
|
} else if (ReadHalf1 == End) {
|
||||||
*Out++ = *ReadHalf0++;
|
*Out++ = *ReadHalf0++;
|
||||||
} else if (ReadHalf0->range.min < ReadHalf1->range.min) {
|
} else if (!MergeSortCompare(ReadHalf0, ReadHalf1)) {
|
||||||
*Out++ = *ReadHalf0++;
|
*Out++ = *ReadHalf0++;
|
||||||
} else {
|
} else {
|
||||||
*Out++ = *ReadHalf1++;
|
*Out++ = *ReadHalf1++;
|
||||||
@@ -814,9 +768,7 @@ void MergeSort(int64_t Count, Edit *First, Edit *Temp) {
|
|||||||
Assert(ReadHalf1 == End);
|
Assert(ReadHalf1 == End);
|
||||||
|
|
||||||
// TODO(casey): Not really necessary if we ping-pong
|
// TODO(casey): Not really necessary if we ping-pong
|
||||||
for (int64_t Index = 0;
|
for (Int Index = 0; Index < Count; ++Index) {
|
||||||
Index < Count;
|
|
||||||
++Index) {
|
|
||||||
First[Index] = Temp[Index];
|
First[Index] = Temp[Index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ struct Buffer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct FuzzyPair {
|
struct FuzzyPair {
|
||||||
Int index;
|
int32_t index;
|
||||||
Int rating;
|
int32_t rating;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -130,9 +130,7 @@ API Int GetLineIndent(Buffer *buffer, Int line);
|
|||||||
API Int GetIndentAtPos(Buffer *buffer, Int pos);
|
API Int GetIndentAtPos(Buffer *buffer, Int pos);
|
||||||
API Range GetIndentRangeAtPos(Buffer *buffer, Int pos);
|
API Range GetIndentRangeAtPos(Buffer *buffer, Int pos);
|
||||||
|
|
||||||
API Int FuzzyRate(String16 string, String16 with);
|
API Int FindRangeByPos(Array<Range> *ranges, Int pos);
|
||||||
API Array<FuzzyPair> FuzzySearchLines(Allocator allocator, Buffer *buffer, Int line_min, Int line_max, String16 needle);
|
|
||||||
API Int FindRangeByPos(Array<Range> *ranges, Int pos);
|
|
||||||
|
|
||||||
// These don't handle history, just raw operations on buffer memory
|
// These don't handle history, just raw operations on buffer memory
|
||||||
API void RawReplaceText(Buffer *buffer, Range range, String16 string);
|
API void RawReplaceText(Buffer *buffer, Range range, String16 string);
|
||||||
|
|||||||
@@ -669,7 +669,6 @@ String Coro_OpenCodeDir;
|
|||||||
void Coro_OpenCode(mco_coro *co) {
|
void Coro_OpenCode(mco_coro *co) {
|
||||||
Array<String> dirs = {CoCurr->arena};
|
Array<String> dirs = {CoCurr->arena};
|
||||||
Add(&dirs, Coro_OpenCodeDir);
|
Add(&dirs, Coro_OpenCodeDir);
|
||||||
int i = 0;
|
|
||||||
for (int diri = 0; diri < dirs.len; diri += 1) {
|
for (int diri = 0; diri < dirs.len; diri += 1) {
|
||||||
for (FileIter it = IterateFiles(CoCurr->arena, dirs[diri]); IsValid(it); Advance(&it)) {
|
for (FileIter it = IterateFiles(CoCurr->arena, dirs[diri]); IsValid(it); Advance(&it)) {
|
||||||
bool match = false;
|
bool match = false;
|
||||||
|
|||||||
@@ -134,7 +134,6 @@ Trigger *ParseKeyChord(Lexer *lex) {
|
|||||||
Trigger *left = ParseKeyAtom(lex);
|
Trigger *left = ParseKeyAtom(lex);
|
||||||
EatWhitespace(lex);
|
EatWhitespace(lex);
|
||||||
while (IsAlphanumeric(At(lex))) {
|
while (IsAlphanumeric(At(lex))) {
|
||||||
int op = At(lex);
|
|
||||||
left = TriggerBinary(lex, left, ParseKeyChord(lex), ' ');
|
left = TriggerBinary(lex, left, ParseKeyChord(lex), ' ');
|
||||||
EatWhitespace(lex);
|
EatWhitespace(lex);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ void DrawWindow(Window *window, Event &event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// darken the inactive windows
|
// darken the inactive windows
|
||||||
if (!is_active) {
|
if (!is_active && !active_layed_out_doc) {
|
||||||
ProfileScope(DarkenInactiveRect);
|
ProfileScope(DarkenInactiveRect);
|
||||||
SetScissor(screen_rect);
|
SetScissor(screen_rect);
|
||||||
DrawRect(window->total_rect, ColorInactiveWindow);
|
DrawRect(window->total_rect, ColorInactiveWindow);
|
||||||
|
|||||||
@@ -27,13 +27,13 @@ void CommandWindowLayout(Rect2I *rect, Int wx, Int wy) {
|
|||||||
n->document_rect = n->total_rect = CutBottom(rect, barsize);
|
n->document_rect = n->total_rect = CutBottom(rect, barsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
Int FuzzyRate(String16 string, String16 with) {
|
int32_t FuzzyRate(String16 string, String16 with) {
|
||||||
ProfileFunction();
|
ProfileFunction();
|
||||||
if (with.len == 0) return 0;
|
if (with.len == 0) return 0;
|
||||||
Int points = 0;
|
int32_t points = 0;
|
||||||
Int consecutive = 0;
|
int32_t consecutive = 0;
|
||||||
Int with_i = 0;
|
int32_t with_i = 0;
|
||||||
for (Int i = 0; i < string.len; i++) {
|
for (int32_t i = 0; i < string.len; i++) {
|
||||||
if (ToLowerCase(string.data[i]) == ToLowerCase(with[with_i])) {
|
if (ToLowerCase(string.data[i]) == ToLowerCase(with[with_i])) {
|
||||||
consecutive += 1;
|
consecutive += 1;
|
||||||
with_i += 1;
|
with_i += 1;
|
||||||
@@ -49,33 +49,25 @@ Int FuzzyRate(String16 string, String16 with) {
|
|||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool MergeSortCompare(FuzzyPair *a, FuzzyPair *b) {
|
||||||
|
bool result = a->rating > b->rating;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Array<FuzzyPair> FuzzySearchLines(Allocator allocator, Buffer *buffer, Int line_min, Int line_max, String16 needle) {
|
Array<FuzzyPair> FuzzySearchLines(Allocator allocator, Buffer *buffer, Int line_min, Int line_max, String16 needle) {
|
||||||
ProfileFunction();
|
ProfileFunction();
|
||||||
if (line_min < 0 || line_min >= buffer->line_starts.len) return {};
|
if (line_min < 0 || line_min >= buffer->line_starts.len) return {};
|
||||||
if (line_max < 0 || line_min > buffer->line_starts.len) return {};
|
if (line_max < 0 || line_min > buffer->line_starts.len) return {};
|
||||||
Array<FuzzyPair> ratings = {allocator};
|
Array<FuzzyPair> ratings = {allocator};
|
||||||
|
Reserve(&ratings, line_max - line_min + 4);
|
||||||
for (Int i = line_min; i < line_max; i += 1) {
|
for (Int i = line_min; i < line_max; i += 1) {
|
||||||
String16 s = GetLineStringWithoutNL(buffer, i);
|
String16 s = GetLineStringWithoutNL(buffer, i);
|
||||||
Int idx = 0;
|
int32_t rating = FuzzyRate(s, needle);
|
||||||
if (Seek(s, u" || ", &idx)) {
|
Add(&ratings, {(int32_t)i, rating});
|
||||||
s.len = idx;
|
|
||||||
}
|
|
||||||
s = Trim(s);
|
|
||||||
Int rating = FuzzyRate(s, needle);
|
|
||||||
Add(&ratings, {i, rating});
|
|
||||||
}
|
|
||||||
|
|
||||||
// bubble sort
|
|
||||||
for (Int i = 0; i < ratings.len - 1; i++) {
|
|
||||||
for (Int j = 0; j < ratings.len - 1; j++) {
|
|
||||||
if (ratings[j].rating > ratings[j + 1].rating) {
|
|
||||||
FuzzyPair temp = ratings[j];
|
|
||||||
ratings[j] = ratings[j + 1];
|
|
||||||
ratings[j + 1] = temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Array<FuzzyPair> temp = Copy(allocator, ratings);
|
||||||
|
MergeSort(ratings.len, ratings.data, temp.data);
|
||||||
return ratings;
|
return ratings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ void StatusWindowUpdate() {
|
|||||||
String16 string_to_replace = GetString(title.buffer, replace_range);
|
String16 string_to_replace = GetString(title.buffer, replace_range);
|
||||||
if (string_to_replace != string) {
|
if (string_to_replace != string) {
|
||||||
SelectRange(title.view, replace_range);
|
SelectRange(title.view, replace_range);
|
||||||
Array<Edit> edits = ReplaceEx(scratch, title.view, string);
|
ReplaceEx(scratch, title.view, string);
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectRange(title.view, MakeRange(0));
|
SelectRange(title.view, MakeRange(0));
|
||||||
|
|||||||
Reference in New Issue
Block a user