Line range refactor

This commit is contained in:
Krzosa Karol
2024-07-24 13:23:20 +02:00
parent 039d2f9350
commit 8b8229f73a
6 changed files with 85 additions and 69 deletions

View File

@@ -64,6 +64,25 @@ Range GetLineRange(Buffer &buffer, Int line, Int *end_of_buffer = NULL) {
return result; return result;
} }
String16 GetLineString(Buffer &buffer, Int line, Int *end_of_buffer = NULL) {
Range range = GetLineRange(buffer, line, end_of_buffer);
String16 string = GetString(buffer, range);
return string;
}
Range GetLineRangeWithoutNL(Buffer &buffer, Int line) {
Int end_of_buffer = 0;
Range line_range = GetLineRange(buffer, line, &end_of_buffer);
line_range.max = line_range.max - 1 + end_of_buffer;
return line_range;
}
String16 GetLineStringWithoutNL(Buffer &buffer, Int line) {
Range range = GetLineRangeWithoutNL(buffer, line);
String16 string = GetString(buffer, range);
return string;
}
Int PosToLine(Buffer &buffer, Int pos) { Int PosToLine(Buffer &buffer, Int pos) {
Add(&buffer.line_starts, buffer.len + 1); Add(&buffer.line_starts, buffer.len + 1);

View File

@@ -0,0 +1,52 @@
struct FuzzyPair {
Int index;
Int rating;
};
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;
}
Array<FuzzyPair> FuzzySearchLines(Allocator allocator, Buffer *buffer, Int line_min, Int line_max, String16 needle) {
Assert(line_min >= 0 && line_min < buffer->line_starts.len);
Assert(line_max >= 0 && line_max <= buffer->line_starts.len);
Array<FuzzyPair> ratings = {allocator};
for (Int i = line_min; i < line_max; i += 1) {
String16 s = GetLineStringWithoutNL(*buffer, i);
int64_t rating = FuzzyRate(s, needle);
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) {
FuzzyPair temp = ratings[j];
ratings[j] = ratings[j + 1];
ratings[j + 1] = temp;
}
}
}
return ratings;
}

View File

@@ -59,12 +59,11 @@ void Command_MoveCursorsToSide(Window *window, int direction, bool shift = false
Buffer *buffer = GetBuffer(view.buffer_id); Buffer *buffer = GetBuffer(view.buffer_id);
For(view.carets) { For(view.carets) {
Int end_of_buffer = 0; Range line_range = GetLineRangeWithoutNL(*buffer, PosToLine(*buffer, GetFront(it)));
Range line_range = GetLineRange(*buffer, PosToLine(*buffer, GetFront(it)), &end_of_buffer);
Int pos = line_range.min; Int pos = line_range.min;
if (direction == DIR_RIGHT) { if (direction == DIR_RIGHT) {
pos = line_range.max - (1 - end_of_buffer); pos = line_range.max;
} }
if (shift) { if (shift) {
@@ -124,30 +123,6 @@ void Command_SelectEntireBuffer(View *view) {
view->carets[0] = MakeCaret(0, buffer->len); view->carets[0] = MakeCaret(0, buffer->len);
} }
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) {
View &view = *GetActiveView(window); View &view = *GetActiveView(window);
Buffer *buffer = GetBuffer(view.buffer_id); Buffer *buffer = GetBuffer(view.buffer_id);
@@ -334,39 +309,14 @@ void HandleActiveWindowBindings(Window *window) {
} }
if (window->fuzzy_search && search) { if (window->fuzzy_search && search) {
Range line_range = GetLineRange(*buffer, 0); Scratch scratch;
String16 string = GetString(*buffer, line_range); String16 first_line_string = GetLineStringWithoutNL(*buffer, 0);
Array<FuzzyPair> ratings = FuzzySearchLines(scratch, buffer, 1, buffer->line_starts.len, first_line_string);
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); Buffer *temp_buffer = CreateTempBuffer(scratch, buffer->cap);
ReplaceText(temp_buffer, {}, string); ReplaceText(temp_buffer, GetEndAsRange(*temp_buffer), first_line_string);
For(ratings) { For(ratings) {
Range l = GetLineRange(*buffer, it.index); String16 s = GetLineString(*buffer, it.index);
String16 s = GetString(*buffer, l);
ReplaceText(temp_buffer, GetEndAsRange(*temp_buffer), s); ReplaceText(temp_buffer, GetEndAsRange(*temp_buffer), s);
} }
@@ -380,8 +330,7 @@ void HandleActiveWindowBindings(Window *window) {
if (Press(KEY_ENTER)) { if (Press(KEY_ENTER)) {
Scratch scratch; Scratch scratch;
Int line = PosToLine(*buffer, GetFront(view.carets[0])); Int line = PosToLine(*buffer, GetFront(view.carets[0]));
Range range = GetLineRange(*buffer, line); String16 string = GetLineStringWithoutNL(*buffer, line);
String16 string = GetString(*buffer, range);
String16 eval_result = EvalString(scratch, string); String16 eval_result = EvalString(scratch, string);
if (Ctrl() && eval_result.len) { if (Ctrl() && eval_result.len) {
@@ -405,10 +354,7 @@ void HandleActiveWindowBindings(Window *window) {
Command_Replace(view, eval_result); Command_Replace(view, eval_result);
} }
Int end_of_buffer = 0; Range range = GetLineRangeWithoutNL(*buffer, 0);
Range range = GetLineRange(*buffer, 0, &end_of_buffer);
range.max -= 1;
range.max += end_of_buffer;
Command_SelectRange(&view, range); Command_SelectRange(&view, range);
Command_Replace(&view, {}); Command_Replace(&view, {});
} }

View File

@@ -17,6 +17,7 @@
#include "buffer.cpp" #include "buffer.cpp"
#include "buffer_multi_cursor.cpp" #include "buffer_multi_cursor.cpp"
#include "buffer_history.cpp" #include "buffer_history.cpp"
#include "buffer_fuzzy_search.cpp"
#include "buffer_test_load.cpp" #include "buffer_test_load.cpp"
#include "management.cpp" #include "management.cpp"

View File

@@ -106,8 +106,8 @@ Int FrameID;
Int LastFrameIDWhenScrolled; Int LastFrameIDWhenScrolled;
Int LastFrameIDWhenSwitchedActiveWindow; Int LastFrameIDWhenSwitchedActiveWindow;
Array<WindowID> WindowSwitchHistory; Array<WindowID> WindowSwitchHistory; // @todo: probably better as a circular buffer
WindowID ActiveWindow = {}; WindowID ActiveWindow;
String16 EvalString(Allocator allocator, String16 string16); String16 EvalString(Allocator allocator, String16 string16);
Rect2I GetVisibleCells(Window &window); Rect2I GetVisibleCells(Window &window);

View File

@@ -46,8 +46,7 @@ void DrawVisibleText(Window &window) {
Rect2I visible = GetVisibleCells(window); Rect2I visible = GetVisibleCells(window);
for (Int line_index = visible.min.y; line_index < visible.max.y && line_index >= 0 && line_index < buffer->line_starts.len; line_index += 1) { for (Int line_index = visible.min.y; line_index < visible.max.y && line_index >= 0 && line_index < buffer->line_starts.len; line_index += 1) {
Range line_range = GetLineRange(*buffer, line_index); String16 line_string = GetLineString(*buffer, line_index);
String16 line_string = GetString(*buffer, line_range);
Vec2I pos = {visible.min.x * (Int)FontCharSpacing, line_index * (Int)FontLineSpacing}; Vec2I pos = {visible.min.x * (Int)FontCharSpacing, line_index * (Int)FontLineSpacing};
pos -= view.scroll; pos -= view.scroll;
@@ -118,8 +117,7 @@ void DrawSelection(Window &window, Caret &it) {
Color color = ColorSelection; Color color = ColorSelection;
Rect2I vlines = GetVisibleCells(window); Rect2I vlines = GetVisibleCells(window);
for (Int line = vlines.min.y; line <= vlines.max.y && line >= 0 && line < buffer->line_starts.len; line += 1) { for (Int line = vlines.min.y; line <= vlines.max.y && line >= 0 && line < buffer->line_starts.len; line += 1) {
Range range = GetLineRange(*buffer, line); String16 line_string = GetLineString(*buffer, line);
String16 line_string = GetString(*buffer, range);
for (Int col = vlines.min.x; col < vlines.max.x && col >= 0 && col < line_string.len; col += 1) { for (Int col = vlines.min.x; col < vlines.max.x && col >= 0 && col < line_string.len; col += 1) {
bool a = line > min.line && line < max.line; bool a = line > min.line && line < max.line;