Improve edit api

This commit is contained in:
Krzosa Karol
2024-08-06 18:21:52 +02:00
parent 4aaae7773d
commit b036e48cee
5 changed files with 42 additions and 55 deletions

View File

@@ -98,7 +98,7 @@ void ClearRedoStack(Buffer *buffer) {
// We can invoke this before caret altering commands to save caret history
// and then call some editing command to edit which is not going to save carets
// @todo: this needs to be actually tested though!!!
void BeforeEdit(Buffer *buffer, Array<Caret> &carets) {
Array<Edit> BeginEdit(Allocator allocator, Buffer *buffer, Array<Caret> &carets) {
Assert(buffer->edit_phase == 0 || buffer->edit_phase == 1);
if (buffer->edit_phase == 0) {
buffer->edit_phase += 1;
@@ -106,11 +106,19 @@ void BeforeEdit(Buffer *buffer, Array<Caret> &carets) {
SaveHistoryBeforeMergeCursor(buffer, &buffer->undo_stack, carets);
ClearRedoStack(buffer);
}
Array<Edit> result = {allocator};
return result;
}
void PreBeginEdit_SaveCaretHistory(Buffer *buffer, Array<Caret> &carets) {
BeginEdit({}, buffer, carets);
}
bool KILL_SELECTION = true;
void AfterEdit(Buffer *buffer, Array<Edit> *edits, Array<Caret> *carets, bool kill_selection = true) {
void EndEdit(Buffer *buffer, Array<Edit> *edits, Array<Caret> *carets, bool kill_selection = true) {
ProfileFunction();
ApplyEdits(buffer, *edits);
Assert(buffer->edit_phase == 2);
buffer->edit_phase -= 2;

View File

@@ -463,6 +463,7 @@ void AppendToConsole(String16 string) {
// @todo: ?
View *view = FindView(buffer->id);
Assert(view);
bool scroll_to_end = false;
if (view) {

View File

@@ -47,24 +47,20 @@ void Command_Paste(View *view) {
// Regular paste
if (string != SavedClipboardString || SavedClipboardCursors.len != view->carets.len) {
BeforeEdit(buffer, view->carets);
Array<Edit> edits = BeginEdit(scratch, buffer, view->carets);
MergeCarets(view);
Array<Edit> edits = {scratch};
For(view->carets) AddEdit(&edits, it.range, string);
ApplyEdits(buffer, edits);
AfterEdit(buffer, &edits, &view->carets);
EndEdit(buffer, &edits, &view->carets);
return;
}
// Multicursor paste
BeforeEdit(buffer, view->carets);
Array<Edit> edits = BeginEdit(scratch, buffer, view->carets);
MergeCarets(view);
Array<Edit> edits = {scratch};
for (int64_t i = 0; i < view->carets.len; i += 1) {
String16 string = SavedClipboardCursors[i];
Caret &it = view->carets[i];
AddEdit(&edits, it.range, string);
}
ApplyEdits(buffer, edits);
AfterEdit(buffer, &edits, &view->carets);
EndEdit(buffer, &edits, &view->carets);
}

View File

@@ -162,11 +162,10 @@ void Command_MoveLine(View *view, int direction) {
XY back;
};
Buffer *buffer = GetBuffer(view->active_buffer);
BeforeEdit(buffer, view->carets);
Buffer *buffer = GetBuffer(view->active_buffer);
Array<Edit> edits = BeginEdit(scratch, buffer, view->carets);
MergeCarets(view);
Array<XYPair> saved_xy = {scratch};
Array<Edit> edits = {scratch};
For(view->carets) {
Add(&saved_xy, {PosToXY(*buffer, GetFront(it)), PosToXY(*buffer, GetBack(it))});
Range lines_to_move_range = {GetFullLineStart(buffer, it.range.min), GetFullLineEnd(buffer, it.range.max)};
@@ -187,8 +186,7 @@ void Command_MoveLine(View *view, int direction) {
AddEdit(&edits, Rng(prev_line_start), string);
}
}
ApplyEdits(buffer, edits);
AfterEdit(buffer, &edits, &view->carets);
EndEdit(buffer, &edits, &view->carets);
Int line_offset = direction == DIR_UP ? -1 : +1;
for (Int i = 0; i < saved_xy.len; i += 1) {
@@ -204,24 +202,24 @@ void Command_MoveLine(View *view, int direction) {
}
void Command_Replace(View *view, String16 string) {
Buffer *buffer = GetBuffer(view->active_buffer);
Scratch scratch;
BeforeEdit(buffer, view->carets);
Buffer *buffer = GetBuffer(view->active_buffer);
Array<Edit> edits = BeginEdit(scratch, buffer, view->carets);
MergeCarets(view);
Array<Edit> edits = {scratch};
For(view->carets) AddEdit(&edits, it.range, string);
ApplyEdits(buffer, edits);
AfterEdit(buffer, &edits, &view->carets);
EndEdit(buffer, &edits, &view->carets);
}
void Command_DuplicateLine(View *view, int direction) {
Assert(direction == DIR_UP || direction == DIR_DOWN);
Scratch scratch;
Buffer *buffer = GetBuffer(view->active_buffer);
BeforeEdit(buffer, view->carets);
BeginEdit(scratch, buffer, view->carets);
For(view->carets) it = MakeCaret(GetFront(it));
MergeCarets(view);
Scratch scratch;
Array<Edit> edits = {scratch};
For(view->carets) {
Int line = PosToLine(*buffer, it.range.min);
@@ -230,8 +228,7 @@ void Command_DuplicateLine(View *view, int direction) {
Int pos = direction == DIR_UP ? range.min : range.max;
AddEdit(&edits, Rng(pos), string);
}
ApplyEdits(buffer, edits);
AfterEdit(buffer, &edits, &view->carets);
EndEdit(buffer, &edits, &view->carets);
Command_Move(view, direction);
}
@@ -292,11 +289,10 @@ void Command_IndentSelectedLines(View *view, bool shift = false) {
Scratch scratch;
Buffer *buffer = GetBuffer(view->active_buffer);
BeforeEdit(buffer, view->carets);
Array<Edit> edits = BeginEdit(scratch, buffer, view->carets);
MergeCarets(view);
Array<Range> line_ranges_to_indent = GetSelectedLinesSorted(scratch, view);
Array<Edit> edits = {scratch};
For(line_ranges_to_indent) {
for (Int i = it.min; i < it.max; i += 1) {
Range pos_range_of_line = GetLineRange(*buffer, i);
@@ -315,9 +311,7 @@ void Command_IndentSelectedLines(View *view, bool shift = false) {
}
}
}
ApplyEdits(buffer, edits);
AfterEdit(buffer, &edits, &view->carets, !KILL_SELECTION);
EndEdit(buffer, &edits, &view->carets, !KILL_SELECTION);
view->update_scroll = false;
}
@@ -325,13 +319,12 @@ void Command_TrimTrailingWhitespace(View *view, bool dont_trim_lines_with_cursor
Scratch scratch;
Buffer *buffer = GetBuffer(view->active_buffer);
BeforeEdit(buffer, view->carets);
Array<Edit> edits = BeginEdit(scratch, buffer, view->carets);
MergeCarets(view);
Array<Range> lines_to_skip_triming = {};
if (dont_trim_lines_with_cursor) lines_to_skip_triming = GetSelectedLinesSorted(scratch, view);
Array<Edit> edits = {scratch};
for (Int i = 0; i < buffer->line_starts.len; i += 1) {
Int range_index = FindRangeByPos(lines_to_skip_triming, i);
if (range_index != -1) continue;
@@ -348,8 +341,7 @@ void Command_TrimTrailingWhitespace(View *view, bool dont_trim_lines_with_cursor
AddEdit(&edits, whitespace_range, L"");
}
ApplyEdits(buffer, edits);
AfterEdit(buffer, &edits, &view->carets, !KILL_SELECTION);
EndEdit(buffer, &edits, &view->carets, !KILL_SELECTION);
view->update_scroll = false;
}
@@ -357,13 +349,12 @@ void Command_ConvertLineEndings(View *view, bool dont_trim_lines_with_cursor) {
Scratch scratch;
Buffer *buffer = GetBuffer(view->active_buffer);
BeforeEdit(buffer, view->carets);
Array<Edit> edits = BeginEdit(scratch, buffer, view->carets);
MergeCarets(view);
Array<Range> lines_to_skip_triming = {};
if (dont_trim_lines_with_cursor) lines_to_skip_triming = GetSelectedLinesSorted(scratch, view);
Array<Edit> edits = {scratch};
for (Int i = 0; i < buffer->line_starts.len; i += 1) {
Int range_index = FindRangeByPos(lines_to_skip_triming, i);
if (range_index != -1) continue;
@@ -375,9 +366,7 @@ void Command_ConvertLineEndings(View *view, bool dont_trim_lines_with_cursor) {
AddEdit(&edits, {range.max - 1, range.max}, L"");
}
}
ApplyEdits(buffer, edits);
AfterEdit(buffer, &edits, &view->carets, !KILL_SELECTION);
EndEdit(buffer, &edits, &view->carets, !KILL_SELECTION);
view->update_scroll = false;
}
@@ -385,11 +374,10 @@ void Command_KillSelectedLines(View *view) {
Scratch scratch;
Buffer *buffer = GetBuffer(view->active_buffer);
BeforeEdit(buffer, view->carets);
Array<Edit> edits = BeginEdit(scratch, buffer, view->carets);
MergeCarets(view);
Array<Range> lines = GetSelectedLinesSorted(scratch, view);
Array<Edit> edits = {scratch};
For(lines) {
Range add_range = GetLineRange(*buffer, it.min);
@@ -406,16 +394,15 @@ void Command_KillSelectedLines(View *view) {
it.range.min = it.range.max = range.min;
}
ApplyEdits(buffer, edits);
AfterEdit(buffer, &edits, &view->carets, KILL_SELECTION);
EndEdit(buffer, &edits, &view->carets, KILL_SELECTION);
}
void Command_Delete(View *view, int direction, bool ctrl = false) {
Assert(direction == DIR_LEFT || direction == DIR_RIGHT);
Scratch scratch;
Buffer *buffer = GetBuffer(view->active_buffer);
BeforeEdit(buffer, view->carets);
Buffer *buffer = GetBuffer(view->active_buffer);
Array<Edit> edits = BeginEdit(scratch, buffer, view->carets);
// Select things to delete
For(view->carets) {
@@ -442,10 +429,8 @@ void Command_Delete(View *view, int direction, bool ctrl = false) {
}
MergeCarets(view);
Array<Edit> edits = {scratch};
For(view->carets) AddEdit(&edits, it.range, {});
ApplyEdits(buffer, edits);
AfterEdit(buffer, &edits, &view->carets);
EndEdit(buffer, &edits, &view->carets);
}
void Command_SelectAll(View *view, String16 needle) {
@@ -577,11 +562,10 @@ Array<Range> FindAllInBuffer(Allocator allocator, Buffer *buffer, String16 needl
}
void Command_IdentedNewLine(View *view) {
Buffer *buffer = GetBuffer(view->active_buffer);
Scratch scratch;
BeforeEdit(buffer, view->carets);
Buffer *buffer = GetBuffer(view->active_buffer);
Scratch scratch;
Array<Edit> edits = BeginEdit(scratch, buffer, view->carets);
MergeCarets(view);
Array<Edit> edits = {scratch};
For(view->carets) {
Int front = GetFront(it);
Int line = PosToLine(*buffer, front);
@@ -590,8 +574,7 @@ void Command_IdentedNewLine(View *view) {
String16 string16 = ToString16(scratch, string);
AddEdit(&edits, it.range, string16);
}
ApplyEdits(buffer, edits);
AfterEdit(buffer, &edits, &view->carets);
EndEdit(buffer, &edits, &view->carets);
}
void WindowCommand(Event event, Window *window, View *view) {
@@ -675,7 +658,7 @@ void WindowCommand(Event event, Window *window, View *view) {
} else if (Ctrl(SDLK_V)) {
Command_Paste(view);
} else if (Ctrl(SDLK_X)) {
BeforeEdit(buffer, view->carets);
PreBeginEdit_SaveCaretHistory(buffer, view->carets);
Command_Copy(view);
Command_Replace(view, L"");
}

View File

@@ -1,5 +1,4 @@
- search as a command to execute which is going to be in the title bar
- maybe modify api BeginEdit - EndEdit
- search backwards
- draw indentation levels like in sublime (those lines) - we render chars one by one so seems relatively easy to figure out if whitespace belongs to beginning of line (make sure to add max value like 40 because of big files)