Checkpoint automation

This commit is contained in:
Krzosa Karol
2025-12-26 20:59:52 +01:00
parent 44bf7c68ff
commit 29ad3a8f08
9 changed files with 46 additions and 37 deletions

View File

@@ -17,12 +17,6 @@ Commands TODO:
- Turned off by default - Turned off by default
- Special: non editable, hotkeys don't work etc. - Special: non editable, hotkeys don't work etc.
- CONSIDER AUTOMATING: CheckpointBeforeGoto
- GotoBackward how to handle that in case we want to automate and create on every move?
- Add jump checkpoints
- Make sure the timing window works forward and backward in undo and jump
backlog backlog
FEATURE Search whole words, case sensitive etc. FEATURE Search whole words, case sensitive etc.
FEATURE Select all searched occurences FEATURE Select all searched occurences

View File

@@ -30,7 +30,7 @@ void BacktraceOnError(void *data, const char *msg, int errnum) {
int BacktraceOnPrint(void *data, uintptr_t pc, const char *filename, int lineno, const char *function) { int BacktraceOnPrint(void *data, uintptr_t pc, const char *filename, int lineno, const char *function) {
bool printed = false; bool printed = false;
if (filename != NULL) { if (filename != NULL) {
char buffer[512]; char buffer[1024];
char *f = realpath(filename, buffer); char *f = realpath(filename, buffer);
printf("%s:%d:1: ", f, lineno); printf("%s:%d:1: ", f, lineno);
printed = true; printed = true;

View File

@@ -975,7 +975,6 @@ API void UndoEdit(Buffer *buffer, Array<Caret> *carets) {
} }
} }
API void DeallocHistoryEntries(Array<HistoryEntry> *entries) { API void DeallocHistoryEntries(Array<HistoryEntry> *entries) {
For(*entries) { For(*entries) {
Dealloc(&it.carets); Dealloc(&it.carets);

View File

@@ -33,7 +33,6 @@ String GetMainDir() {
} }
void JumpGarbageBuffer(BSet *set, String buffer_name = "") { void JumpGarbageBuffer(BSet *set, String buffer_name = "") {
CheckpointBeforeGoto(set->window);
if (buffer_name.len == 0) { if (buffer_name.len == 0) {
buffer_name = GetUniqueBufferName(GetDir(set->buffer), "temp"); buffer_name = GetUniqueBufferName(GetDir(set->buffer), "temp");
} }
@@ -43,7 +42,6 @@ void JumpGarbageBuffer(BSet *set, String buffer_name = "") {
} }
void BeginJump(BSet *set, BufferID buffer_id = NullBufferID) { void BeginJump(BSet *set, BufferID buffer_id = NullBufferID) {
CheckpointBeforeGoto(set->window);
set->buffer = GetBuffer(buffer_id); set->buffer = GetBuffer(buffer_id);
set->view = WindowOpenBufferView(set->window, set->buffer->name); set->view = WindowOpenBufferView(set->window, set->buffer->name);
} }
@@ -444,7 +442,6 @@ BSet Exec(String cmd, String working_dir, bool set_active = true) {
BSet ExecBuild(String cmd) { BSet ExecBuild(String cmd) {
BSet main = GetBSet(LastActiveLayoutWindowID); BSet main = GetBSet(LastActiveLayoutWindowID);
ActiveWindowID = main.window->id; ActiveWindowID = main.window->id;
CheckpointBeforeGoto(main.window);
View *view = WindowOpenBufferView(main.window, BuildBuffer->name); View *view = WindowOpenBufferView(main.window, BuildBuffer->name);
ResetBuffer(BuildBuffer); ResetBuffer(BuildBuffer);
Exec(view->id, true, cmd, WorkDir); Exec(view->id, true, cmd, WorkDir);
@@ -614,7 +611,6 @@ BSet Open(Window *window, String path, String meta, bool set_active = true) {
ActiveWindowID = set.window->id; ActiveWindowID = set.window->id;
} }
if (IsDir(o.path)) { if (IsDir(o.path)) {
CheckpointBeforeGoto(set.window);
View *view = WindowOpenBufferView(set.window, o.path); View *view = WindowOpenBufferView(set.window, o.path);
Buffer *buffer = GetBuffer(view->active_buffer); Buffer *buffer = GetBuffer(view->active_buffer);
ResetBuffer(buffer); ResetBuffer(buffer);
@@ -623,7 +619,6 @@ BSet Open(Window *window, String path, String meta, bool set_active = true) {
RawAppendf(buffer, "%S\n", it.filename); RawAppendf(buffer, "%S\n", it.filename);
} }
} else { } else {
CheckpointBeforeGoto(set.window);
View *view = WindowOpenBufferView(set.window, o.path); View *view = WindowOpenBufferView(set.window, o.path);
Buffer *buffer = GetBuffer(view->active_buffer); Buffer *buffer = GetBuffer(view->active_buffer);
if (o.line != -1) { if (o.line != -1) {
@@ -845,11 +840,13 @@ void Command_CloseAll() {
void Command_GotoBackward() { void Command_GotoBackward() {
BSet main = GetBSet(LastActiveLayoutWindowID); BSet main = GetBSet(LastActiveLayoutWindowID);
main.window->skip_checkpoint = true;
GotoBackward(main.window); GotoBackward(main.window);
} RegisterCommand(Command_GotoBackward, "alt-q | mousex1"); } RegisterCommand(Command_GotoBackward, "alt-q | mousex1");
void Command_GotoForward() { void Command_GotoForward() {
BSet main = GetBSet(LastActiveLayoutWindowID); BSet main = GetBSet(LastActiveLayoutWindowID);
main.window->skip_checkpoint = true;
GotoForward(main.window); GotoForward(main.window);
} RegisterCommand(Command_GotoForward, "alt-shift-q | mousex2"); } RegisterCommand(Command_GotoForward, "alt-shift-q | mousex2");

View File

@@ -10,7 +10,6 @@ void CoRemove(String name) {
} }
} }
#define CoAdd(x) CoAddEx(x, #x) #define CoAdd(x) CoAddEx(x, #x)
mco_coro *CoAddEx(CoroutineProc *proc, String name) { mco_coro *CoAddEx(CoroutineProc *proc, String name) {
CoRemove(name); CoRemove(name);

View File

@@ -170,9 +170,14 @@ void OnCommand(Event event) {
// //
// Window cursor setting // Window cursor setting
// //
Scratch scratch; Scratch scratch;
Array<Window *> order = GetWindowZOrder(scratch); Array<Window *> order = GetWindowZOrder(scratch);
Window *window = GetWindow(ActiveWindowID);
{
}
// Handle wheel scrolling // Handle wheel scrolling
if (event.xwheel || event.ywheel) { if (event.xwheel || event.ywheel) {
@@ -330,8 +335,6 @@ void OnCommand(Event event) {
bool mouse_in_line_numbers = AreOverlapping(mouse, active.window->line_numbers_rect); bool mouse_in_line_numbers = AreOverlapping(mouse, active.window->line_numbers_rect);
if (mouse_in_document || mouse_in_line_numbers) { if (mouse_in_document || mouse_in_line_numbers) {
DocumentSelected = active.window->id; DocumentSelected = active.window->id;
CheckpointBeforeGoto(active.window);
Int p = ScreenSpaceToBufferPos(active.window, active.view, active.buffer, mouse); Int p = ScreenSpaceToBufferPos(active.window, active.view, active.buffer, mouse);
if (Alt()) Insert(&active.view->carets, MakeCaret(p, p), 0); if (Alt()) Insert(&active.view->carets, MakeCaret(p, p), 0);
@@ -502,7 +505,7 @@ void Update(Event event) {
ProfileFunction(); ProfileFunction();
LayoutWindows(event.xwindow, event.ywindow); LayoutWindows(event.xwindow, event.ywindow);
Scratch scratch; Scratch scratch;
Array<Window *> order = GetWindowZOrder(scratch); Array<Window *> order = GetWindowZOrder(scratch);
For(order) { For(order) {
if (!it->visible) { if (!it->visible) {
@@ -513,6 +516,12 @@ void Update(Event event) {
view->update_scroll = true; view->update_scroll = true;
} }
For (Windows) {
if (it->jump_history) {
View *view = GetView(it->active_view);
it->begin_frame_crumb = {it->active_view, view->carets[0], GetTimeSeconds()};
}
}
OnCommand(event); OnCommand(event);
StatusWindowUpdate(); StatusWindowUpdate();
@@ -521,17 +530,37 @@ void Update(Event event) {
SearchWindowUpdate(); SearchWindowUpdate();
UpdateProcesses(); UpdateProcesses();
CoUpdate(&event); CoUpdate(&event);
For (Buffers) it->begin_frame_change_id = it->change_id; // after last place we modify
// We update it here despite the name to make it sure that all the possible changes are
// included albeit with delayed response. If we did this at the beginning of the frame
// and the DebugWindowUpdated we wouldnt get to know that in the OnCommand.
For (Buffers) {
it->begin_frame_change_id = it->change_id;
}
{ {
ProfileScope(WindowEndOfFrameVisibilityAndLastActive); ProfileScope(WindowEndOfFrameVisibilityAndLastActive);
For (Windows) { For (Windows) {
if (it->goto_history.len > ConfigJumpHistorySize) { if (it->jump_history) {
RemoveByIndex(&it->goto_history, 0); View *view = GetView(it->active_view);
} bool are_equal = it->begin_frame_crumb.view_id == it->active_view && AreEqual(view->carets[0], it->begin_frame_crumb.caret);
if (it->goto_redo.len > ConfigJumpHistorySize) { if (!are_equal) {
RemoveByIndex(&it->goto_redo, 0); if (!it->skip_checkpoint) {
Add(&it->goto_history, it->begin_frame_crumb);
it->goto_redo.len = 0;
}
}
it->skip_checkpoint = false;
if (it->goto_history.len > ConfigJumpHistorySize) {
RemoveByIndex(&it->goto_history, 0);
}
if (it->goto_redo.len > ConfigJumpHistorySize) {
RemoveByIndex(&it->goto_redo, 0);
}
} }
if (it->sync_visibility_with_focus) { if (it->sync_visibility_with_focus) {
if (it->id == ActiveWindowID) { if (it->id == ActiveWindowID) {
it->visible = true; it->visible = true;

View File

@@ -235,17 +235,6 @@ Int ScreenSpaceToBufferPosErrorOutOfBounds(Window *window, View *view, Buffer *b
return result; return result;
} }
void CheckpointBeforeGoto(Window *window, View *view) {
if (window->jump_history == false) return;
Add(&window->goto_history, {view->id, view->carets[0], GetTimeSeconds()});
window->goto_redo.len = 0;
}
void CheckpointBeforeGoto(Window *window) {
CheckpointBeforeGoto(window, GetView(window->active_view));
}
GotoCrumb GetCrumb(Array<GotoCrumb> *cr) { GotoCrumb GetCrumb(Array<GotoCrumb> *cr) {
for (; cr->len;) { for (; cr->len;) {
GotoCrumb c = Pop(cr); GotoCrumb c = Pop(cr);

View File

@@ -17,6 +17,7 @@ struct Window {
double weight; double weight;
Caret search_bar_anchor; Caret search_bar_anchor;
GotoCrumb begin_frame_crumb;
Array<GotoCrumb> goto_history; Array<GotoCrumb> goto_history;
Array<GotoCrumb> goto_redo; Array<GotoCrumb> goto_redo;
@@ -36,6 +37,7 @@ struct Window {
bool lose_visibility_on_escape : 1; bool lose_visibility_on_escape : 1;
bool jump_history : 1; bool jump_history : 1;
bool eval_command : 1; bool eval_command : 1;
uint32_t skip_checkpoint : 1;
}; };
}; };

View File

@@ -83,11 +83,11 @@ void StatusWindowUpdate() {
// replace data up to separator with filename and stuff // replace data up to separator with filename and stuff
const char *reopen = main.buffer->changed_on_disk ? " Reopen()" : ""; const char *reopen = main.buffer->changed_on_disk ? " :Reopen" : "";
String s = Format(scratch, "# %S:%lld:%lld%s", main.buffer->name, (long long)xy.line + 1ll, (long long)xy.col + 1ll, reopen); String s = Format(scratch, "# %S:%lld:%lld%s", main.buffer->name, (long long)xy.line + 1ll, (long long)xy.col + 1ll, reopen);
For (ActiveProcesses) { For (ActiveProcesses) {
if (it.view_id == main.view->id.id) { if (it.view_id == main.view->id.id) {
s = Format(scratch, "%S %lld Kill()", s, (long long)it.id); s = Format(scratch, "%S %lld :KillProcess", s, (long long)it.id);
} }
} }