Move up down and multi cursor
This commit is contained in:
@@ -29,16 +29,17 @@ struct Line {
|
||||
Range range;
|
||||
};
|
||||
|
||||
struct LineAndColumn {
|
||||
Line line;
|
||||
int64_t column;
|
||||
};
|
||||
|
||||
struct Edit {
|
||||
Range range;
|
||||
String string;
|
||||
};
|
||||
|
||||
// :buffer_initialized
|
||||
// @todo: it's very tempting to ensure that buffer is initialized
|
||||
// then we know:
|
||||
// - we always have at least one thing in lines array.
|
||||
// - I think it would be probably easy enough to enforce
|
||||
// - Buffer should be initialized before use!
|
||||
struct Buffer {
|
||||
Allocator allocator;
|
||||
char *data[2];
|
||||
@@ -228,30 +229,6 @@ String CopyNullTerminated(Allocator allocator, Buffer &buffer, Range range) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Line GetLine(Buffer &buffer, int64_t line) {
|
||||
// :buffer_initialized
|
||||
// @todo: do I enfore initialized state of the buffer +
|
||||
// lines array maybe should always have something
|
||||
Assert(buffer.lines.len);
|
||||
|
||||
line = Clamp(line, (int64_t)0, buffer.lines.len - 1);
|
||||
Range range = buffer.lines[line];
|
||||
Line result = {line, range};
|
||||
return result;
|
||||
}
|
||||
|
||||
Line FindLine(Buffer &buffer, int64_t pos) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
int64_t AdjustUTF8Pos(String string, int64_t pos, int64_t direction) {
|
||||
for (; pos >= 0 && pos < string.len;) {
|
||||
if (IsUTF8ContinuationByte(string.data[pos])) {
|
||||
@@ -329,14 +306,14 @@ void Advance(BufferIter *iter) {
|
||||
iter->item = GetUTF32(*iter->buffer, iter->pos, &iter->utf8_codepoint_size);
|
||||
}
|
||||
|
||||
BufferIter Iterate(Buffer *buffer, Range range, int64_t direction = ITERATE_FORWARD) {
|
||||
BufferIter Iterate(Buffer &buffer, Range range, int64_t direction = ITERATE_FORWARD) {
|
||||
Assert(direction == ITERATE_FORWARD || direction == ITERATE_BACKWARD);
|
||||
Assert(!IsUTF8ContinuationByte(GetChar(*buffer, range.min)));
|
||||
Assert(!IsUTF8ContinuationByte(GetChar(buffer, range.min)));
|
||||
Assert(range.max >= range.min);
|
||||
range.min = Clamp(*buffer, range.min);
|
||||
range.max = Clamp(*buffer, range.max);
|
||||
range.min = Clamp(buffer, range.min);
|
||||
range.max = Clamp(buffer, range.max);
|
||||
|
||||
BufferIter result = {buffer, range.min, range.max, direction};
|
||||
BufferIter result = {&buffer, range.min, range.max, direction};
|
||||
if (direction == ITERATE_BACKWARD) {
|
||||
result.end = range.min;
|
||||
result.pos = range.max;
|
||||
@@ -346,6 +323,52 @@ BufferIter Iterate(Buffer *buffer, Range range, int64_t direction = ITERATE_FORW
|
||||
return result;
|
||||
}
|
||||
|
||||
Line GetLine(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};
|
||||
return result;
|
||||
}
|
||||
|
||||
Line FindLine(Buffer &buffer, int64_t pos) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
LineAndColumn FindLineAndColumn(Buffer &buffer, int64_t pos) {
|
||||
LineAndColumn result = {};
|
||||
result.column = 1;
|
||||
result.line = FindLine(buffer, pos);
|
||||
for (BufferIter iter = Iterate(buffer, result.line.range); IsValid(iter); Advance(&iter)) {
|
||||
if (iter.pos == pos) {
|
||||
result.column = iter.codepoint_index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t FindPos(Buffer &buffer, int64_t line_number, int64_t column) {
|
||||
Line line = GetLine(buffer, line_number);
|
||||
int64_t result = line.range.max;
|
||||
for (BufferIter iter = Iterate(buffer, line.range); IsValid(iter); Advance(&iter)) {
|
||||
if (iter.codepoint_index == column) {
|
||||
result = iter.pos;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void RunBufferTests() {
|
||||
Scratch scratch;
|
||||
{
|
||||
@@ -407,7 +430,7 @@ void RunBufferTests() {
|
||||
|
||||
{
|
||||
Array<char> s = {scratch};
|
||||
for (BufferIter iter = Iterate(&buffer, {0, 6}); IsValid(iter); Advance(&iter)) {
|
||||
for (BufferIter iter = Iterate(buffer, {0, 6}); IsValid(iter); Advance(&iter)) {
|
||||
Assert(iter.item < 255);
|
||||
|
||||
s.add((char)iter.item);
|
||||
@@ -417,7 +440,7 @@ void RunBufferTests() {
|
||||
}
|
||||
{
|
||||
Array<char> s = {scratch};
|
||||
for (BufferIter iter = Iterate(&buffer, {0, 6}, ITERATE_BACKWARD); IsValid(iter); Advance(&iter)) {
|
||||
for (BufferIter iter = Iterate(buffer, {0, 6}, ITERATE_BACKWARD); IsValid(iter); Advance(&iter)) {
|
||||
Assert(iter.item < 255);
|
||||
|
||||
s.add((char)iter.item);
|
||||
@@ -427,7 +450,7 @@ void RunBufferTests() {
|
||||
}
|
||||
{
|
||||
Array<char> s = {scratch};
|
||||
for (BufferIter iter = Iterate(&buffer, {0, buffer.len}); IsValid(iter); Advance(&iter)) {
|
||||
for (BufferIter iter = Iterate(buffer, {0, buffer.len}); IsValid(iter); Advance(&iter)) {
|
||||
Assert(iter.item < 255);
|
||||
|
||||
s.add((char)iter.item);
|
||||
@@ -438,7 +461,7 @@ void RunBufferTests() {
|
||||
}
|
||||
{
|
||||
Array<char> s = {scratch};
|
||||
for (BufferIter iter = Iterate(&buffer, {0, buffer.len}, ITERATE_BACKWARD); IsValid(iter); Advance(&iter)) {
|
||||
for (BufferIter iter = Iterate(buffer, {0, buffer.len}, ITERATE_BACKWARD); IsValid(iter); Advance(&iter)) {
|
||||
Assert(iter.item < 255);
|
||||
|
||||
s.add((char)iter.item);
|
||||
|
||||
Reference in New Issue
Block a user