Refactored lines to contain 'new line'
This commit is contained in:
@@ -27,6 +27,7 @@ struct Range {
|
||||
struct Line {
|
||||
int64_t number;
|
||||
Range range;
|
||||
int64_t max_without_new_line;
|
||||
};
|
||||
|
||||
struct LineAndColumn {
|
||||
@@ -91,6 +92,11 @@ Range MakeRange(int64_t a, int64_t b) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Range MakeRange(int64_t a) {
|
||||
Range result = {a, a};
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t GetFront(Cursor cursor) {
|
||||
int64_t result = cursor.pos[cursor.ifront];
|
||||
return result;
|
||||
@@ -342,7 +348,7 @@ void ApplyEdits(Buffer *buffer, Array<Edit> edits) {
|
||||
int64_t index = 0;
|
||||
int64_t base_index = 0;
|
||||
while (Seek(string, delimiter, &index)) {
|
||||
buffer->lines.add({base_index, base_index + index});
|
||||
buffer->lines.add({base_index, base_index + index + delimiter.len});
|
||||
base_index += index + delimiter.len;
|
||||
string = string.skip(index + delimiter.len);
|
||||
}
|
||||
@@ -457,25 +463,28 @@ BufferIter Iterate(Buffer &buffer, Range range, int64_t direction = ITERATE_FORW
|
||||
return result;
|
||||
}
|
||||
|
||||
Line GetLine(Buffer &buffer, int64_t line) {
|
||||
Line GetLineByIndex(Buffer &buffer, int64_t line) {
|
||||
Assert(buffer.lines.len);
|
||||
|
||||
line = Clamp(line, (int64_t)0, buffer.lines.len - 1);
|
||||
Range range = buffer.lines[line];
|
||||
Line result = {line, range};
|
||||
Line result = {line, range, range.max};
|
||||
if (GetChar(buffer, range.max - 1) == '\n') result.max_without_new_line -= 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
Line FindLine(Buffer &buffer, int64_t pos) {
|
||||
Line result = {};
|
||||
For(buffer.lines) {
|
||||
// The program is doing '<= it.max' so as to include the new line.
|
||||
// Otherwise this function wouldn't be able to find certain positions.
|
||||
if (pos >= it.min && pos <= it.max) {
|
||||
Line result = {buffer.lines.get_index(it), it};
|
||||
return result;
|
||||
bool found_last = (pos == it.min && pos == it.max);
|
||||
bool found = pos >= it.min && pos < it.max;
|
||||
if (found || found_last) {
|
||||
result = {buffer.lines.get_index(it), it, it.max};
|
||||
if (GetChar(buffer, it.max - 1) == '\n') result.max_without_new_line -= 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
return result;
|
||||
}
|
||||
|
||||
LineAndColumn FindLineAndColumn(Buffer &buffer, int64_t pos) {
|
||||
@@ -493,8 +502,8 @@ LineAndColumn FindLineAndColumn(Buffer &buffer, int64_t pos) {
|
||||
}
|
||||
|
||||
int64_t FindPos(Buffer &buffer, int64_t line_number, int64_t column) {
|
||||
Line line = GetLine(buffer, line_number);
|
||||
int64_t result = line.range.max;
|
||||
Line line = GetLineByIndex(buffer, line_number);
|
||||
int64_t result = line.max_without_new_line;
|
||||
for (BufferIter iter = Iterate(buffer, line.range); IsValid(iter); Advance(&iter)) {
|
||||
if (iter.codepoint_index == column) {
|
||||
result = iter.pos;
|
||||
@@ -552,146 +561,3 @@ int64_t Seek(Buffer &buffer, int64_t pos, int64_t direction = ITERATE_FORWARD) {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void RunBufferTests() {
|
||||
Scratch scratch;
|
||||
{
|
||||
Buffer buffer = {scratch};
|
||||
Array<Edit> edits = {scratch};
|
||||
AddEdit(&edits, {0, 0}, "Things and other things");
|
||||
ApplyEdits(&buffer, edits);
|
||||
String string = {buffer.data[buffer.bi], buffer.len};
|
||||
Assert(string == "Things and other things");
|
||||
Assert(buffer.lines.len == 1);
|
||||
Assert(GetString(buffer, buffer.lines[0]) == "Things and other things");
|
||||
|
||||
edits.clear();
|
||||
AddEdit(&edits, GetEnd(buffer), " memes");
|
||||
ApplyEdits(&buffer, edits);
|
||||
Assert(GetString(buffer, buffer.lines[0]) == "Things and other things memes");
|
||||
}
|
||||
{
|
||||
Buffer buffer = {scratch};
|
||||
Array<Edit> edits = {scratch};
|
||||
edits.add({});
|
||||
ApplyEdits(&buffer, edits);
|
||||
Assert("" == GetString(buffer));
|
||||
Assert(buffer.lines.len == 1);
|
||||
}
|
||||
{
|
||||
Buffer buffer = {scratch};
|
||||
Array<Edit> edits = {scratch};
|
||||
edits.add({
|
||||
{0, 0},
|
||||
"Things and other things"
|
||||
});
|
||||
ApplyEdits(&buffer, edits);
|
||||
edits.clear();
|
||||
|
||||
AddEdit(&edits, {0, 6}, "Memes");
|
||||
AddEdit(&edits, {7, 10}, "dna");
|
||||
AddEdit(&edits, {11, 16}, "BigOther");
|
||||
ApplyEdits(&buffer, edits);
|
||||
|
||||
String string = {buffer.data[buffer.bi], buffer.len};
|
||||
Assert(string == "Memes dna BigOther things");
|
||||
Assert(buffer.lines.len == 1);
|
||||
Assert(GetString(buffer, buffer.lines[0]) == "Memes dna BigOther things");
|
||||
}
|
||||
{
|
||||
Buffer buffer = {scratch};
|
||||
Array<Edit> edits = {scratch};
|
||||
edits.add({
|
||||
{0, 0},
|
||||
"Things and other things\n"
|
||||
"Things and other things\n"
|
||||
});
|
||||
ApplyEdits(&buffer, edits);
|
||||
Assert(buffer.lines.len == 3);
|
||||
Assert(GetString(buffer, buffer.lines[1]) == "Things and other things");
|
||||
Assert(GetString(buffer, buffer.lines[0]) == "Things and other things");
|
||||
Assert(GetString(buffer, buffer.lines[2]) == "");
|
||||
|
||||
{
|
||||
Array<char> s = {scratch};
|
||||
for (BufferIter iter = Iterate(buffer, {0, 6}); IsValid(iter); Advance(&iter)) {
|
||||
Assert(iter.item < 255);
|
||||
|
||||
s.add((char)iter.item);
|
||||
}
|
||||
String str = {s.data, s.len};
|
||||
Assert(str == "Things");
|
||||
}
|
||||
{
|
||||
Array<char> s = {scratch};
|
||||
for (BufferIter iter = Iterate(buffer, {0, 6}, ITERATE_BACKWARD); IsValid(iter); Advance(&iter)) {
|
||||
Assert(iter.item < 255);
|
||||
|
||||
s.add((char)iter.item);
|
||||
}
|
||||
String str = {s.data, s.len};
|
||||
Assert(str == "sgnihT");
|
||||
}
|
||||
{
|
||||
Array<char> s = {scratch};
|
||||
for (BufferIter iter = Iterate(buffer, {0, buffer.len}); IsValid(iter); Advance(&iter)) {
|
||||
Assert(iter.item < 255);
|
||||
|
||||
s.add((char)iter.item);
|
||||
}
|
||||
String str = {s.data, s.len};
|
||||
String b = {GetCharP(buffer, 0), buffer.len};
|
||||
Assert(str == b);
|
||||
}
|
||||
{
|
||||
Array<char> s = {scratch};
|
||||
for (BufferIter iter = Iterate(buffer, {0, buffer.len}, ITERATE_BACKWARD); IsValid(iter); Advance(&iter)) {
|
||||
Assert(iter.item < 255);
|
||||
|
||||
s.add((char)iter.item);
|
||||
}
|
||||
String str = {s.data, s.len};
|
||||
String b = {GetCharP(buffer, 0), buffer.len};
|
||||
Assert(str.len == b.len);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Arena *arena = AllocArena();
|
||||
Buffer buffer = {*arena};
|
||||
Array<Edit> edits = {*arena};
|
||||
edits.add({
|
||||
{0, 0},
|
||||
"Things and other things\n"
|
||||
"Things and other things\n"
|
||||
});
|
||||
|
||||
int iters = 100;
|
||||
for (int i = 0; i < iters; i += 1) {
|
||||
ApplyEdits(&buffer, edits);
|
||||
for (int64_t j = 0; j < i; j += 1) {
|
||||
String string = GetString(buffer, {edits[0].string.len * j, edits[0].string.len * (j + 1)});
|
||||
Assert(string == edits[0].string);
|
||||
}
|
||||
}
|
||||
Assert(edits[0].string.len * iters == buffer.len);
|
||||
Assert(buffer.lines.len == iters * 2 + 1);
|
||||
|
||||
Line l0 = FindLine(buffer, 4);
|
||||
Assert(l0.number == 0);
|
||||
Assert(l0.range.min == 0);
|
||||
Assert(l0.range.max < 30);
|
||||
|
||||
Line l1 = FindLine(buffer, 30);
|
||||
Assert(l1.number == 1);
|
||||
Assert(l1.range.min > 20);
|
||||
Assert(l1.range.max < 50);
|
||||
Assert(l1.range.max == GetLine(buffer, 1).range.max);
|
||||
|
||||
// Make sure there are no gaps
|
||||
for (int64_t i = 100; i < 600; i += 1) {
|
||||
Line l2 = FindLine(buffer, i);
|
||||
Assert(l2.number > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user