Finite size jump history, improving backtrace, redo, undo grouping, similar for jump history
This commit is contained in:
@@ -2,8 +2,6 @@
|
||||
- From a user (novice) point of view, how does it look like?
|
||||
|
||||
- Open with seek string (open at pattern) filename:32 filename:/^Window$/
|
||||
- ctrl+f should insert selected text into search
|
||||
- Do we need constrained jump history????? So that we can finally collect garbage buffers at some point. Or maybe only constrained to garbage buffers
|
||||
- build console window
|
||||
- Show what process/coroutines are running and allow to kill (active process buffer?)
|
||||
- Database idea: use special buffers to store information
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
typedef void OSErrorReport(const char *, ...);
|
||||
|
||||
#if OS_POSIX
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -54,13 +56,19 @@ void RegisterCrashHandler(void) {
|
||||
struct sigaction sa;
|
||||
sa.sa_sigaction = CrashHandler;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_RESTART | SA_SIGINFO;
|
||||
sa.sa_flags = SA_SIGINFO | SA_NODEFER | SA_RESETHAND; // Important flags!
|
||||
|
||||
sigaction(SIGSEGV, &sa, NULL);
|
||||
sigaction(SIGABRT, &sa, NULL);
|
||||
sigaction(SIGBUS, &sa, NULL);
|
||||
sigaction(SIGILL, &sa, NULL);
|
||||
sigaction(SIGFPE, &sa, NULL);
|
||||
|
||||
sigaction(SIGSEGV, &sa, NULL); // Segmentation fault
|
||||
sigaction(SIGABRT, &sa, NULL); // Abort
|
||||
sigaction(SIGBUS, &sa, NULL); // Bus error
|
||||
sigaction(SIGILL, &sa, NULL); // Illegal instruction
|
||||
sigaction(SIGFPE, &sa, NULL); // Floating point exception
|
||||
sigaction(SIGTRAP, &sa, NULL); // Breakpoint/trap
|
||||
sigaction(SIGSYS, &sa, NULL); // Bad system call
|
||||
sigaction(SIGXCPU, &sa, NULL); // CPU time limit exceeded
|
||||
sigaction(SIGXFSZ, &sa, NULL); // File size limit exceeded
|
||||
sigaction(SIGTERM, &sa, NULL); // Termination request (optional)
|
||||
}
|
||||
|
||||
API void InitOS(void (*error_proc)(const char *, ...)) {
|
||||
|
||||
@@ -878,12 +878,13 @@ API void AddEdit(Array<Edit> *e, Range range, String16 string) {
|
||||
// multicursor + history
|
||||
///////////////////////////////
|
||||
|
||||
void SaveHistoryBeforeMergeCursor(Buffer *buffer, Array<HistoryEntry> *stack, Array<Caret> &carets) {
|
||||
if (buffer->no_history) return;
|
||||
HistoryEntry *SaveHistoryBeforeMergeCursor(Buffer *buffer, Array<HistoryEntry> *stack, Array<Caret> &carets) {
|
||||
if (buffer->no_history) return NULL;
|
||||
HistoryEntry entry = {};
|
||||
entry.time = GetTimeSeconds();
|
||||
entry.carets = TightCopy(GetSystemAllocator(), carets);
|
||||
Add(stack, entry);
|
||||
return GetLast(*stack);
|
||||
}
|
||||
|
||||
void SaveHistoryBeforeApplyEdits(Buffer *buffer, Array<HistoryEntry> *stack, Array<Edit> &edits) {
|
||||
@@ -928,7 +929,8 @@ API void RedoEdit(Buffer *buffer, Array<Caret> *carets) {
|
||||
|
||||
HistoryEntry entry = Pop(&buffer->redo_stack);
|
||||
|
||||
SaveHistoryBeforeMergeCursor(buffer, &buffer->undo_stack, *carets);
|
||||
HistoryEntry *e = SaveHistoryBeforeMergeCursor(buffer, &buffer->undo_stack, *carets);
|
||||
e->time = entry.time;
|
||||
SaveHistoryBeforeApplyEdits(buffer, &buffer->undo_stack, entry.edits);
|
||||
ApplyEditsMultiCursor(buffer, entry.edits);
|
||||
|
||||
@@ -938,6 +940,13 @@ API void RedoEdit(Buffer *buffer, Array<Caret> *carets) {
|
||||
Allocator sys_allocator = GetSystemAllocator();
|
||||
For(entry.edits) Dealloc(sys_allocator, it.string.data);
|
||||
Dealloc(&entry.edits);
|
||||
|
||||
if (buffer->redo_stack.len > 0) {
|
||||
HistoryEntry *next = GetLast(buffer->redo_stack);
|
||||
if (next->time - entry.time <= ConfigUndoMergeTimeWindow) {
|
||||
RedoEdit(buffer, carets);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
API void UndoEdit(Buffer *buffer, Array<Caret> *carets) {
|
||||
@@ -946,8 +955,8 @@ API void UndoEdit(Buffer *buffer, Array<Caret> *carets) {
|
||||
if (buffer->undo_stack.len <= 0) return;
|
||||
|
||||
HistoryEntry entry = Pop(&buffer->undo_stack);
|
||||
|
||||
SaveHistoryBeforeMergeCursor(buffer, &buffer->redo_stack, *carets);
|
||||
HistoryEntry *e = SaveHistoryBeforeMergeCursor(buffer, &buffer->redo_stack, *carets);
|
||||
e->time = entry.time;
|
||||
SaveHistoryBeforeApplyEdits(buffer, &buffer->redo_stack, entry.edits);
|
||||
ApplyEditsMultiCursor(buffer, entry.edits);
|
||||
|
||||
@@ -960,7 +969,7 @@ API void UndoEdit(Buffer *buffer, Array<Caret> *carets) {
|
||||
|
||||
if (buffer->undo_stack.len > 0) {
|
||||
HistoryEntry *next = GetLast(buffer->undo_stack);
|
||||
if (entry.time - next->time <= ConfigUndoMergeTimeout) {
|
||||
if (entry.time - next->time <= ConfigUndoMergeTimeWindow) {
|
||||
UndoEdit(buffer, carets);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -851,7 +851,7 @@ void Command_GotoBackward() {
|
||||
void Command_GotoForward() {
|
||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
||||
GotoForward(main.window);
|
||||
} RegisterCommand(Command_GotoForward, "mousex2");
|
||||
} RegisterCommand(Command_GotoForward, "alt-shift-q | mousex2");
|
||||
|
||||
void Command_OpenUpFolder() {
|
||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
||||
|
||||
@@ -157,5 +157,7 @@ RegisterVariable(Int, ConfigFontSize, 15);
|
||||
RegisterVariable(Int, ConfigFontFilter, 0);
|
||||
RegisterVariable(String, ConfigFont, "/home/krz/text_editor/package/CascadiaMono.ttf");
|
||||
RegisterVariable(String, ConfigVCVarsall, "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat");
|
||||
RegisterVariable(Float, ConfigUndoMergeTimeout, 0.3);
|
||||
RegisterVariable(Float, ConfigUndoMergeTimeWindow, 0.3);
|
||||
RegisterVariable(Float, ConfigJumpHistoryMergeTimeWindow, 0.3);
|
||||
RegisterVariable(Int, ConfigJumpHistorySize, 512);
|
||||
RegisterVariable(String, ConfigInternetBrowser, "firefox");
|
||||
|
||||
34
src/text_editor/scratch.cpp
Normal file
34
src/text_editor/scratch.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
|
||||
|
||||
void RunRingBufferTest() {
|
||||
// Scratch scratch;
|
||||
// RingBuffer<int> buff = {};
|
||||
// Init(scratch, &buff, 4);
|
||||
|
||||
// for (int i = 0; i < 4; i += 1) {
|
||||
// Add(&buff, i);
|
||||
// }
|
||||
// for (int i = 0; i < 4; i += 1) {
|
||||
// Assert(buff.data[i] == i);
|
||||
// }
|
||||
|
||||
// Add(&buff, 4);
|
||||
// Assert(buff.data[0] == 4);
|
||||
// Add(&buff, 5);
|
||||
// Assert(buff.data[1] == 5);
|
||||
// Assert(buff.data[2] == 2);
|
||||
|
||||
// Assert(Pop(&buff) == 5);
|
||||
// Assert(Pop(&buff) == 4);
|
||||
// Assert(Pop(&buff) == 3);
|
||||
// Assert(Pop(&buff) == 2);
|
||||
// Assert(Pop(&buff) == 0);
|
||||
// Assert(Pop(&buff) == 0);
|
||||
// Assert(Pop(&buff) == 0);
|
||||
// Assert(Pop(&buff) == 0);
|
||||
// Assert(Pop(&buff) == 0);
|
||||
|
||||
// // Assert(Pop(&buff) == 2);
|
||||
|
||||
|
||||
} RegisterFunction(&TestFunctions, RunRingBufferTest);
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "commands.cpp"
|
||||
#include "commands_clipboard.cpp"
|
||||
|
||||
#include "scratch.cpp"
|
||||
#include "draw.cpp"
|
||||
#include "test/tests.cpp"
|
||||
|
||||
@@ -540,6 +541,15 @@ void Update(Event event) {
|
||||
LastActiveLayoutWindowID = ActiveWindowID;
|
||||
}
|
||||
}
|
||||
|
||||
For (Windows) {
|
||||
if (it->goto_history.len > ConfigJumpHistorySize) {
|
||||
RemoveByIndex(&it->goto_history, 0);
|
||||
}
|
||||
if (it->goto_redo.len > ConfigJumpHistorySize) {
|
||||
RemoveByIndex(&it->goto_redo, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -641,6 +651,7 @@ extern char **environ;
|
||||
int main(int argc, char **argv)
|
||||
#endif
|
||||
{
|
||||
InitOS((OSErrorReport *)printf);
|
||||
#if _WIN32
|
||||
int argc = __argc;
|
||||
char **argv = __argv;
|
||||
|
||||
@@ -147,9 +147,6 @@ struct Register_Function {
|
||||
struct Register_Command { Register_Command(Array<CommandData> *fucs, Function *function, String name, String binding) { if (StartsWith(name, "Command_")) name = Skip(name, 8); Add(fucs, {name, binding, function}); } };
|
||||
#define RegisterCommand(name, binding) Register_Command RC__##name(&CommandFunctions, name, #name, binding)
|
||||
|
||||
struct Register_Hook { Register_Hook(Array<PFunctionData> *functions, PFunction *function, String name) { if (StartsWith(name, "Hook_")) name = Skip(name, 5); Add(functions, {name, function}); } };
|
||||
#define RegisterHook(functions, name) Register_Hook RC__##name(functions, (PFunction *)name, #name)
|
||||
|
||||
const int DIR_RIGHT = 0;
|
||||
const int DIR_LEFT = 1;
|
||||
const int DIR_DOWN = 2;
|
||||
|
||||
@@ -249,7 +249,7 @@ void CheckpointBeforeGoto(Window *window) {
|
||||
GotoCrumb GetCrumb(Array<GotoCrumb> *cr) {
|
||||
for (; cr->len;) {
|
||||
GotoCrumb c = Pop(cr);
|
||||
View *view = GetView(c.view_id);
|
||||
View *view = FindView(c.view_id, NULL);
|
||||
if (view) {
|
||||
return c;
|
||||
}
|
||||
@@ -271,15 +271,15 @@ void GotoBackward(Window *window) {
|
||||
|
||||
if (window->goto_history.len) {
|
||||
GotoCrumb *next = GetLast(window->goto_history);
|
||||
if (c.time - next->time <= ConfigUndoMergeTimeout) {
|
||||
if (c.view_id == next->view_id && c.time - next->time <= ConfigJumpHistoryMergeTimeWindow) {
|
||||
GotoBackward(window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GotoForward(Window *window) {
|
||||
if (window->goto_redo.len <= 0) return;
|
||||
if (window->jump_history == false) return;
|
||||
if (window->goto_redo.len <= 0) return;
|
||||
BSet set = GetBSet(window);
|
||||
Add(&window->goto_history, {set.view->id, set.view->carets[0], GetTimeSeconds()});
|
||||
|
||||
@@ -291,7 +291,7 @@ void GotoForward(Window *window) {
|
||||
|
||||
if (window->goto_redo.len) {
|
||||
GotoCrumb *next = GetLast(window->goto_redo);
|
||||
if (c.time - next->time <= ConfigUndoMergeTimeout) {
|
||||
if (c.view_id == next->view_id && next->time - c.time <= ConfigJumpHistoryMergeTimeWindow) {
|
||||
GotoForward(window);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ void DebugWindowInit() {
|
||||
window->visible = false;
|
||||
window->z = 2;
|
||||
window->layout = false;
|
||||
window->jump_history = false;
|
||||
|
||||
Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(WorkDir, "debug"));
|
||||
DebugBufferID = buffer->id;
|
||||
|
||||
@@ -15,6 +15,7 @@ void SearchWindowInit() {
|
||||
window->layout = false;
|
||||
window->visible = false;
|
||||
window->lose_visibility_on_escape = true;
|
||||
window->jump_history = false;
|
||||
}
|
||||
|
||||
void SearchWindowLayout(Rect2I *rect, Int wx, Int wy) {
|
||||
|
||||
Reference in New Issue
Block a user