Writing text
This commit is contained in:
@@ -119,6 +119,12 @@ void ApplyEdits(Buffer *buffer, Array<Edit> edits) {
|
|||||||
edits = edits_copy;
|
edits = edits_copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG_BUILD
|
||||||
|
for (int64_t i = 0; i < edits.len - 1; i += 1) {
|
||||||
|
Assert(edits[i].range.min <= edits[i + 1].range.min);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// @optimize: we can do all edits in one go with less memory copies probably
|
// @optimize: we can do all edits in one go with less memory copies probably
|
||||||
// or something else entirely
|
// or something else entirely
|
||||||
Int offset = 0;
|
Int offset = 0;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ int main(void) {
|
|||||||
view.buffer = CreateBuffer(Perm);
|
view.buffer = CreateBuffer(Perm);
|
||||||
{
|
{
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
for (int i = 0; i < 150; i += 1) {
|
for (int i = 0; i < 2; i += 1) {
|
||||||
String s = Format(scratch, "line1: %d line2: %d line3: %d line4: %d line5: %d line6: %d line1: %d line2: %d line3: %d line4: %d line5: %d line6: %d\n", i, i, i, i, i, i, i, i, i, i, i, i);
|
String s = Format(scratch, "line1: %d line2: %d line3: %d line4: %d line5: %d line6: %d line1: %d line2: %d line3: %d line4: %d line5: %d line6: %d\n", i, i, i, i, i, i, i, i, i, i, i, i);
|
||||||
String16 s16 = ToString16(scratch, s);
|
String16 s16 = ToString16(scratch, s);
|
||||||
ReplaceText(view.buffer, GetEndAsRange(*view.buffer), s16);
|
ReplaceText(view.buffer, GetEndAsRange(*view.buffer), s16);
|
||||||
|
|||||||
@@ -122,10 +122,37 @@ Int MoveCaret(Buffer &buffer, Int pos, int direction, bool ctrl_pressed) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AfterEdit(View *view, Array<Edit> edits) {
|
||||||
|
//
|
||||||
|
// Offset all cursors by edits
|
||||||
|
//
|
||||||
|
Scratch scratch;
|
||||||
|
Array<Caret> new_cursors = TightCopy(scratch, view->carets);
|
||||||
|
ForItem(edit, edits) {
|
||||||
|
Int remove_size = GetSize(edit.range);
|
||||||
|
Int insert_size = edit.string.len;
|
||||||
|
Int offset = insert_size - remove_size;
|
||||||
|
|
||||||
|
for (Int i = 0; i < view->carets.len; i += 1) {
|
||||||
|
Caret &old_cursor = view->carets.data[i];
|
||||||
|
Caret &new_cursor = new_cursors.data[i];
|
||||||
|
if (old_cursor.range.min == edit.range.min) {
|
||||||
|
new_cursor.range.min = new_cursor.range.max = new_cursor.range.min + insert_size;
|
||||||
|
} else if (old_cursor.range.min > edit.range.min) {
|
||||||
|
new_cursor.range.min = new_cursor.range.max = new_cursor.range.min + offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Int i = 0; i < view->carets.len; i += 1) view->carets[i] = new_cursors[i];
|
||||||
|
|
||||||
|
// Make sure all cursors are in range
|
||||||
|
For(view->carets) it.range = Clamp(*view->buffer, it.range);
|
||||||
|
}
|
||||||
|
|
||||||
void HandleKeybindings(View *_view) {
|
void HandleKeybindings(View *_view) {
|
||||||
View &view = *_view;
|
View &view = *_view;
|
||||||
Buffer &buf = *view.buffer;
|
Buffer &buf = *view.buffer;
|
||||||
Caret main_cursor_on_begin_frame = view.carets[0];
|
Caret main_caret_on_begin_frame = view.carets[0];
|
||||||
|
|
||||||
if (IsKeyDown(KEY_F1)) {
|
if (IsKeyDown(KEY_F1)) {
|
||||||
view.scroll.x -= GetMouseWheelMove() * 48;
|
view.scroll.x -= GetMouseWheelMove() * 48;
|
||||||
@@ -148,12 +175,26 @@ void HandleKeybindings(View *_view) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int c = GetCharPressed(); c; c = GetCharPressed()) {
|
||||||
|
String16 string = L"?";
|
||||||
|
UTF16Result result = UTF32ToUTF16((uint32_t)c);
|
||||||
|
if (!result.error) string = {(wchar_t *)result.out_str, result.len};
|
||||||
|
// we interpret 2 byte sequences as 1 byte when rendering but we still
|
||||||
|
// want to read them properly.
|
||||||
|
MergeCarets(&view.carets);
|
||||||
|
Scratch scratch;
|
||||||
|
Array<Edit> edits = {scratch};
|
||||||
|
For(view.carets) AddEdit(&edits, it.range, string);
|
||||||
|
ApplyEdits(view.buffer, edits);
|
||||||
|
AfterEdit(&view, edits);
|
||||||
|
}
|
||||||
|
|
||||||
// Scrolling with caret
|
// Scrolling with caret
|
||||||
// @refactor: this should happen after we calculate rect for the view
|
// @refactor: this should happen after we calculate rect for the view
|
||||||
// Usually in other text editors apart from view there is also a 'window'
|
// Usually in other text editors apart from view there is also a 'window'
|
||||||
// which is exactly the thing which shows the view, will need
|
// which is exactly the thing which shows the view, will need
|
||||||
// to think about this later
|
// to think about this later
|
||||||
if (!AreEqual(main_cursor_on_begin_frame, view.carets[0])) {
|
if (!AreEqual(main_caret_on_begin_frame, view.carets[0])) {
|
||||||
|
|
||||||
Caret c = view.carets[0];
|
Caret c = view.carets[0];
|
||||||
Int front = GetFront(c);
|
Int front = GetFront(c);
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ void DrawCaret(const View &view, Caret it) {
|
|||||||
XY max = PosToXY(buf, it.range.max);
|
XY max = PosToXY(buf, it.range.max);
|
||||||
|
|
||||||
Rect2I vlines = GetVisibleCells(view);
|
Rect2I vlines = GetVisibleCells(view);
|
||||||
for (Int line = vlines.min.y; line <= vlines.max.y; line += 1) {
|
for (Int line = vlines.min.y; line <= vlines.max.y && line >= 0 && line < view.buffer->line_starts.len; line += 1) {
|
||||||
Range range = GetLine(buf, line);
|
Range range = GetLine(buf, line);
|
||||||
range -= range.min;
|
range -= range.min;
|
||||||
range.min = Clamp(range.min, vlines.min.x, vlines.max.x);
|
range.min = Clamp(range.min, vlines.min.x, vlines.max.x);
|
||||||
|
|||||||
Reference in New Issue
Block a user