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,26 +463,29 @@ 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};
|
||||
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 result;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
LineAndColumn FindLineAndColumn(Buffer &buffer, int64_t pos) {
|
||||
LineAndColumn result = {};
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,50 +40,130 @@ Layout CalculateLayout(Arena *arena, Buffer &buffer, Font font, float font_size,
|
||||
Layout layout = {};
|
||||
layout.rows.allocator = *arena;
|
||||
|
||||
Range *last_range = buffer.lines.last();
|
||||
float scaleFactor = font_size / font.baseSize; // Character quad scaling factor
|
||||
float text_offset_y = 0;
|
||||
float text_offset_x = 0;
|
||||
float line_spacing = font_size;
|
||||
ForItem(line_range, buffer.lines) {
|
||||
float textOffsetX = 0.0f;
|
||||
text_offset_x = 0.0f;
|
||||
if (&line_range == last_range && GetRangeSize(line_range) == 0) break; // end of buffer line
|
||||
|
||||
LayoutRow *row = layout.rows.alloc();
|
||||
row->columns.allocator = *arena;
|
||||
row->rect.min = {textOffsetX, text_offset_y};
|
||||
row->rect.min = {text_offset_x, text_offset_y};
|
||||
|
||||
BufferIter iter = Iterate(buffer, line_range);
|
||||
for (;; Advance(&iter)) {
|
||||
bool end_of_buffer = iter.pos == buffer.len;
|
||||
bool new_line = iter.pos == line_range.max;
|
||||
bool in_range = IsValid(iter);
|
||||
bool continue_looping = end_of_buffer || new_line || in_range;
|
||||
if (!continue_looping) break;
|
||||
|
||||
int codepoint = '\n'; // @todo: questionable choice
|
||||
if (in_range) codepoint = iter.item;
|
||||
|
||||
int index = GetGlyphIndex(font, codepoint);
|
||||
for (BufferIter iter = Iterate(buffer, line_range); IsValid(iter); Advance(&iter)) {
|
||||
int index = GetGlyphIndex(font, (int)iter.item);
|
||||
GlyphInfo *glyph = font.glyphs + index;
|
||||
Vec2 glyph_position = {textOffsetX, text_offset_y};
|
||||
Vec2 glyph_position = {text_offset_x, text_offset_y};
|
||||
|
||||
float x_to_offset_by = ((float)glyph->advanceX * scaleFactor + font_spacing);
|
||||
if (glyph->advanceX == 0) x_to_offset_by = ((float)font.recs[index].width * scaleFactor + font_spacing);
|
||||
|
||||
Vec2 cell_size = {x_to_offset_by, font_size};
|
||||
Rect2 cell_rect = {glyph_position, Vector2Add(glyph_position, cell_size)};
|
||||
row->columns.add({cell_rect, iter.pos, codepoint});
|
||||
row->columns.add({cell_rect, iter.pos, (int)iter.item});
|
||||
row->rect.max = cell_rect.max;
|
||||
|
||||
textOffsetX += x_to_offset_by;
|
||||
if (end_of_buffer || new_line) break;
|
||||
text_offset_x += x_to_offset_by;
|
||||
}
|
||||
|
||||
layout.buffer_world_pixel_size.x = Max(layout.buffer_world_pixel_size.x, textOffsetX);
|
||||
text_offset_y += font_size;
|
||||
layout.buffer_world_pixel_size.x = Max(layout.buffer_world_pixel_size.x, text_offset_x);
|
||||
text_offset_y += line_spacing;
|
||||
}
|
||||
|
||||
// Add end of buffer as layout cell at the end
|
||||
{
|
||||
LayoutRow *row = layout.rows.alloc();
|
||||
row->columns.allocator = *arena;
|
||||
if (last_range->min == last_range->max) {
|
||||
text_offset_x = 0;
|
||||
} else {
|
||||
text_offset_y -= line_spacing;
|
||||
}
|
||||
int index = GetGlyphIndex(font, ' ');
|
||||
GlyphInfo *glyph = font.glyphs + index;
|
||||
Vec2 glyph_position = {text_offset_x, text_offset_y};
|
||||
|
||||
float x_to_offset_by = ((float)glyph->advanceX * scaleFactor + font_spacing);
|
||||
if (glyph->advanceX == 0) x_to_offset_by = ((float)font.recs[index].width * scaleFactor + font_spacing);
|
||||
|
||||
Vec2 cell_size = {x_to_offset_by, line_spacing};
|
||||
Rect2 cell_rect = {glyph_position, Vector2Add(glyph_position, cell_size)};
|
||||
row->columns.add({cell_rect, buffer.len, '\0'});
|
||||
row->rect = {glyph_position, cell_rect.max};
|
||||
}
|
||||
|
||||
layout.buffer_world_pixel_size.y = text_offset_y;
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
void DrawString(Font font, String text, Vector2 position, float fontSize, float spacing, Color tint) {
|
||||
if (font.texture.id == 0) font = GetFontDefault(); // Security check in case of not valid font
|
||||
|
||||
float textOffsetX = 0.0f; // Offset X to next character to draw
|
||||
|
||||
float scaleFactor = fontSize / font.baseSize; // Character quad scaling factor
|
||||
|
||||
for (int i = 0; i < text.len;) {
|
||||
// Get next codepoint from byte string and glyph index in font
|
||||
int codepointByteCount = 0;
|
||||
int codepoint = GetCodepointNext(&text.data[i], &codepointByteCount);
|
||||
int index = GetGlyphIndex(font, codepoint);
|
||||
|
||||
if ((codepoint != ' ') && (codepoint != '\t')) {
|
||||
DrawTextCodepoint(font, codepoint, {position.x + textOffsetX, position.y}, fontSize, tint);
|
||||
}
|
||||
|
||||
if (font.glyphs[index].advanceX == 0) textOffsetX += ((float)font.recs[index].width * scaleFactor + spacing);
|
||||
else textOffsetX += ((float)font.glyphs[index].advanceX * scaleFactor + spacing);
|
||||
|
||||
i += codepointByteCount; // Move text bytes counter to next codepoint
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 MeasureString(Font font, String text, float fontSize, float spacing) {
|
||||
Vector2 textSize = {0};
|
||||
if ((font.texture.id == 0) || (text.data == NULL)) return textSize; // Security check
|
||||
|
||||
int size = (int)text.len; // Get size in bytes of text
|
||||
int tempByteCounter = 0; // Used to count longer text line num chars
|
||||
int byteCounter = 0;
|
||||
|
||||
float textWidth = 0.0f;
|
||||
float tempTextWidth = 0.0f; // Used to count longer text line width
|
||||
|
||||
float textHeight = fontSize;
|
||||
float scaleFactor = fontSize / (float)font.baseSize;
|
||||
|
||||
int letter = 0; // Current character
|
||||
int index = 0; // Index position in sprite font
|
||||
|
||||
for (int i = 0; i < size;) {
|
||||
byteCounter++;
|
||||
|
||||
int next = 0;
|
||||
letter = GetCodepointNext(&text.data[i], &next);
|
||||
index = GetGlyphIndex(font, letter);
|
||||
|
||||
i += next;
|
||||
|
||||
if (font.glyphs[index].advanceX != 0) textWidth += font.glyphs[index].advanceX;
|
||||
else textWidth += (font.recs[index].width + font.glyphs[index].offsetX);
|
||||
|
||||
if (tempByteCounter < byteCounter) tempByteCounter = byteCounter;
|
||||
}
|
||||
|
||||
if (tempTextWidth < textWidth) tempTextWidth = textWidth;
|
||||
|
||||
textSize.x = tempTextWidth * scaleFactor + (float)((tempByteCounter - 1) * spacing);
|
||||
textSize.y = textHeight;
|
||||
|
||||
return textSize;
|
||||
}
|
||||
|
||||
LayoutRow *GetLayoutRow(Window &window, float ypos_window_buffer_world_units) {
|
||||
float line_spacing = window.font_size;
|
||||
int64_t line = (int64_t)floorf(ypos_window_buffer_world_units / line_spacing);
|
||||
|
||||
@@ -17,70 +17,6 @@ Rect2 GetScreenRect() {
|
||||
return result;
|
||||
}
|
||||
|
||||
void DrawString(Font font, String text, Vector2 position, float fontSize, float spacing, Color tint) {
|
||||
if (font.texture.id == 0) font = GetFontDefault(); // Security check in case of not valid font
|
||||
|
||||
float textOffsetX = 0.0f; // Offset X to next character to draw
|
||||
|
||||
float scaleFactor = fontSize / font.baseSize; // Character quad scaling factor
|
||||
|
||||
for (int i = 0; i < text.len;) {
|
||||
// Get next codepoint from byte string and glyph index in font
|
||||
int codepointByteCount = 0;
|
||||
int codepoint = GetCodepointNext(&text.data[i], &codepointByteCount);
|
||||
int index = GetGlyphIndex(font, codepoint);
|
||||
|
||||
if ((codepoint != ' ') && (codepoint != '\t')) {
|
||||
DrawTextCodepoint(font, codepoint, {position.x + textOffsetX, position.y}, fontSize, tint);
|
||||
}
|
||||
|
||||
if (font.glyphs[index].advanceX == 0) textOffsetX += ((float)font.recs[index].width * scaleFactor + spacing);
|
||||
else textOffsetX += ((float)font.glyphs[index].advanceX * scaleFactor + spacing);
|
||||
|
||||
i += codepointByteCount; // Move text bytes counter to next codepoint
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 MeasureString(Font font, String text, float fontSize, float spacing) {
|
||||
Vector2 textSize = {0};
|
||||
if ((font.texture.id == 0) || (text.data == NULL)) return textSize; // Security check
|
||||
|
||||
int size = (int)text.len; // Get size in bytes of text
|
||||
int tempByteCounter = 0; // Used to count longer text line num chars
|
||||
int byteCounter = 0;
|
||||
|
||||
float textWidth = 0.0f;
|
||||
float tempTextWidth = 0.0f; // Used to count longer text line width
|
||||
|
||||
float textHeight = fontSize;
|
||||
float scaleFactor = fontSize / (float)font.baseSize;
|
||||
|
||||
int letter = 0; // Current character
|
||||
int index = 0; // Index position in sprite font
|
||||
|
||||
for (int i = 0; i < size;) {
|
||||
byteCounter++;
|
||||
|
||||
int next = 0;
|
||||
letter = GetCodepointNext(&text.data[i], &next);
|
||||
index = GetGlyphIndex(font, letter);
|
||||
|
||||
i += next;
|
||||
|
||||
if (font.glyphs[index].advanceX != 0) textWidth += font.glyphs[index].advanceX;
|
||||
else textWidth += (font.recs[index].width + font.glyphs[index].offsetX);
|
||||
|
||||
if (tempByteCounter < byteCounter) tempByteCounter = byteCounter;
|
||||
}
|
||||
|
||||
if (tempTextWidth < textWidth) tempTextWidth = textWidth;
|
||||
|
||||
textSize.x = tempTextWidth * scaleFactor + (float)((tempByteCounter - 1) * spacing);
|
||||
textSize.y = textHeight;
|
||||
|
||||
return textSize;
|
||||
}
|
||||
|
||||
int64_t MoveRight(Buffer &buffer, int64_t pos) {
|
||||
pos = pos + 1;
|
||||
pos = AdjustUTF8Pos(buffer, pos);
|
||||
@@ -192,8 +128,6 @@ void Dbg_Draw() {
|
||||
|
||||
int main() {
|
||||
InitScratch();
|
||||
RunBufferTests();
|
||||
|
||||
InitWindow(800, 600, "Hello");
|
||||
SetTargetFPS(60);
|
||||
|
||||
@@ -218,11 +152,14 @@ int main() {
|
||||
|
||||
InitBuffer(&window.buffer);
|
||||
if (1) {
|
||||
for (int i = 0; i < 50; i += 1) {
|
||||
Array<Edit> edits = {FrameArena};
|
||||
AddEdit(&edits, GetEnd(window.buffer), Format(FrameArena, "line number line number line number line number: %d\n", i));
|
||||
AddEdit(&edits, GetEnd(window.buffer), Format(FrameArena, "line number: 1"));
|
||||
ApplyEdits(&window.buffer, edits);
|
||||
}
|
||||
// for (int i = 0; i < 5; i += 1) {
|
||||
// Array<Edit> edits = {FrameArena};
|
||||
// AddEdit(&edits, GetEnd(window.buffer), Format(FrameArena, "line number: %d\n", i));
|
||||
// ApplyEdits(&window.buffer, edits);
|
||||
// }
|
||||
}
|
||||
|
||||
window.cursors.add({});
|
||||
@@ -321,8 +258,8 @@ int main() {
|
||||
For(focused_window->cursors) {
|
||||
int64_t front = GetFront(it);
|
||||
Line line = FindLine(focused_window->buffer, front);
|
||||
String string = GetString(focused_window->buffer, {line.range.min, line.range.max + 1});
|
||||
AddEdit(&edits, {line.range.max + 1, line.range.max + 1}, string);
|
||||
String string = GetString(focused_window->buffer, line.range);
|
||||
AddEdit(&edits, {line.range.max, line.range.max}, string);
|
||||
}
|
||||
ApplyEdits(&focused_window->buffer, edits);
|
||||
AfterEdit(focused_window, edits);
|
||||
@@ -355,7 +292,7 @@ int main() {
|
||||
For(focused_window->cursors) {
|
||||
int64_t front = GetFront(it);
|
||||
Line line = FindLine(focused_window->buffer, front);
|
||||
String string = GetString(focused_window->buffer, {line.range.min, line.range.max + 1});
|
||||
String string = GetString(focused_window->buffer, line.range);
|
||||
AddEdit(&edits, {line.range.min, line.range.min}, string);
|
||||
}
|
||||
ApplyEdits(&focused_window->buffer, edits);
|
||||
@@ -376,6 +313,32 @@ int main() {
|
||||
}
|
||||
}
|
||||
|
||||
For(focused_window->cursors) {
|
||||
if (IsKeyPressed(KEY_HOME) || IsKeyPressedRepeat(KEY_HOME)) {
|
||||
if (IsKeyDown(KEY_LEFT_SHIFT)) {
|
||||
int64_t front = GetFront(it);
|
||||
Line line = FindLine(focused_window->buffer, front);
|
||||
it = ChangeFront(it, line.range.min);
|
||||
} else {
|
||||
int64_t front = GetFront(it);
|
||||
Line line = FindLine(focused_window->buffer, front);
|
||||
it.range.min = it.range.max = line.range.min;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_END) || IsKeyPressedRepeat(KEY_END)) {
|
||||
if (IsKeyDown(KEY_LEFT_SHIFT)) {
|
||||
int64_t front = GetFront(it);
|
||||
Line line = FindLine(focused_window->buffer, front);
|
||||
it = ChangeFront(it, line.max_without_new_line);
|
||||
} else {
|
||||
int64_t front = GetFront(it);
|
||||
Line line = FindLine(focused_window->buffer, front);
|
||||
it.range.min = it.range.max = line.max_without_new_line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @todo: improve behaviour of all copy pasting
|
||||
if (IsKeyDown(KEY_LEFT_CONTROL) && IsKeyPressed(KEY_C)) {
|
||||
Array<String> strings = {FrameArena};
|
||||
@@ -402,7 +365,7 @@ int main() {
|
||||
For(focused_window->cursors) {
|
||||
if (GetRangeSize(it.range) == 0) {
|
||||
Line line = FindLine(focused_window->buffer, it.range.min);
|
||||
it.range = {line.range.min, line.range.max + 1};
|
||||
it.range = line.range;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,24 +383,6 @@ int main() {
|
||||
AfterEdit(focused_window, edits);
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_ENTER)) {
|
||||
if (IsKeyDown(KEY_LEFT_CONTROL)) {
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_HOME) || IsKeyPressedRepeat(KEY_HOME)) {
|
||||
if (IsKeyDown(KEY_LEFT_SHIFT)) {
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_END) || IsKeyPressedRepeat(KEY_END)) {
|
||||
if (IsKeyDown(KEY_LEFT_SHIFT)) {
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
if (IsKeyDown(KEY_LEFT_CONTROL) && (IsKeyPressed(KEY_D) || IsKeyPressedRepeat(KEY_D))) {
|
||||
}
|
||||
|
||||
@@ -460,6 +405,22 @@ int main() {
|
||||
}
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_ENTER)) {
|
||||
if (IsKeyDown(KEY_LEFT_CONTROL)) {
|
||||
For(focused_window->cursors) {
|
||||
int64_t front = GetFront(it);
|
||||
Line line = FindLine(focused_window->buffer, front);
|
||||
it.range = MakeRange(line.max_without_new_line);
|
||||
}
|
||||
}
|
||||
|
||||
BeforeEdit(focused_window);
|
||||
Array<Edit> edits = {FrameArena};
|
||||
For(focused_window->cursors) AddEdit(&edits, it.range, "\n");
|
||||
ApplyEdits(&focused_window->buffer, edits);
|
||||
AfterEdit(focused_window, edits);
|
||||
}
|
||||
|
||||
// Handle user input
|
||||
for (;;) {
|
||||
int c = GetCharPressed();
|
||||
@@ -584,8 +545,9 @@ int main() {
|
||||
}
|
||||
|
||||
if (col.codepoint == '\n') {
|
||||
Vec2 mid = GetMid(rect);
|
||||
DrawCircle((int)mid.x, (int)mid.y, font_size / 8, {0, 0, 0, 120});
|
||||
DrawTextEx(font, "\\n", rect.min, font_size, font_spacing, GRAY);
|
||||
} else if (col.codepoint == '\0') {
|
||||
DrawTextEx(font, "\\0", rect.min, font_size, font_spacing, {255, 0, 0, 150});
|
||||
} else if ((col.codepoint != ' ') && (col.codepoint != '\t')) {
|
||||
DrawTextCodepoint(font, col.codepoint, rect.min, font_size, BLACK);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user