First prototype of coroutine based UI
This commit is contained in:
@@ -5,13 +5,14 @@ Use session 1:
|
|||||||
- OpenCommand in command window freezes the app
|
- OpenCommand in command window freezes the app
|
||||||
- SDL popups are not working on linux ...
|
- SDL popups are not working on linux ...
|
||||||
- CloseAll idea: should create a buffer interface with list of buffers, user would be able to select which buffers to save and which not, then button UICloseAll
|
- CloseAll idea: should create a buffer interface with list of buffers, user would be able to select which buffers to save and which not, then button UICloseAll
|
||||||
- Creating files more efficiently
|
- Creating files more efficiently, renaming
|
||||||
- Dialog popup on save? Or ctrl-shift-s?
|
- Dialog popup on save? Or ctrl-shift-s?
|
||||||
- Maybe rename in bar and do :Rename
|
- Maybe rename in bar and do :Rename
|
||||||
|
|
||||||
New UI Session
|
New UI Session
|
||||||
- Cleanup String16/String with Open and EvalCommands after lua refactor
|
- Cleanup String16/String with Open and EvalCommands after lua refactor
|
||||||
- Rename GotoBackward and others to Jump
|
- Uneditable buffers ?
|
||||||
|
- Maybe marked allocations??? So that we can associate allocations with a buffer or view and then dealloc all at the same time
|
||||||
|
|
||||||
- Open with seek string (open at pattern) filename:32 filename:/^Window$/
|
- Open with seek string (open at pattern) filename:32 filename:/^Window$/
|
||||||
- build console window
|
- build console window
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ EM_JS(void, JS_Breakpoint, (), {
|
|||||||
BREAK(); \
|
BREAK(); \
|
||||||
}
|
}
|
||||||
#define InvalidCodepath() Assert(!"invalid codepath")
|
#define InvalidCodepath() Assert(!"invalid codepath")
|
||||||
#define ElseInvalidCodepath() else {InvalidCodepath()}
|
#define ElseInvalidCodepath() else {InvalidCodepath();}
|
||||||
|
|
||||||
#define KiB(x) ((x##ull) * 1024ull)
|
#define KiB(x) ((x##ull) * 1024ull)
|
||||||
#define MiB(x) (KiB(x) * 1024ull)
|
#define MiB(x) (KiB(x) * 1024ull)
|
||||||
|
|||||||
@@ -186,6 +186,7 @@ void BeginFrameRender(float wx, float wy) {
|
|||||||
|
|
||||||
// ---------- EndFrameRender for ES3 ----------
|
// ---------- EndFrameRender for ES3 ----------
|
||||||
void EndFrameRender(float wx, float wy, Color color) {
|
void EndFrameRender(float wx, float wy, Color color) {
|
||||||
|
ProfileFunction();
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|||||||
@@ -152,5 +152,6 @@ void Test(mco_coro *co) {
|
|||||||
void InitTests() {
|
void InitTests() {
|
||||||
ConfigWaitForEvents = false;
|
ConfigWaitForEvents = false;
|
||||||
TestDir = Format(TestArena, "%S/test_env", GetExeDir(TestArena));
|
TestDir = Format(TestArena, "%S/test_env", GetExeDir(TestArena));
|
||||||
CoAdd(Test);
|
CoData *data = CoAdd(Test);
|
||||||
|
data->dont_wait_until_resolved = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1506,9 +1506,9 @@ String16 ToUnixString16(Allocator allocator, String string_) {
|
|||||||
Buffer *BufferOpenFile(String path) {
|
Buffer *BufferOpenFile(String path) {
|
||||||
ProfileFunction();
|
ProfileFunction();
|
||||||
Allocator sys_allocator = GetSystemAllocator();
|
Allocator sys_allocator = GetSystemAllocator();
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
|
|
||||||
path = GetAbsolutePath(scratch, path);
|
path = GetAbsolutePath(scratch, path);
|
||||||
Buffer *buffer = GetBuffer(path);
|
Buffer *buffer = GetBuffer(path);
|
||||||
if (!IsNull(buffer) || (IsNull(buffer) && buffer->name == path)) {
|
if (!IsNull(buffer) || (IsNull(buffer) && buffer->name == path)) {
|
||||||
return buffer;
|
return buffer;
|
||||||
@@ -1519,10 +1519,11 @@ Buffer *BufferOpenFile(String path) {
|
|||||||
} else if (IsDir(path)) {
|
} else if (IsDir(path)) {
|
||||||
buffer = CreateBuffer(sys_allocator, path);
|
buffer = CreateBuffer(sys_allocator, path);
|
||||||
buffer->is_dir = true;
|
buffer->is_dir = true;
|
||||||
|
buffer->garbage = true;
|
||||||
} else {
|
} else {
|
||||||
String string = ReadFile(scratch, path);
|
String string = ReadFile(scratch, path);
|
||||||
buffer = CreateBuffer(sys_allocator, path, string.len * 4 + 4096);
|
buffer = CreateBuffer(sys_allocator, path, string.len * 4 + 4096);
|
||||||
buffer->len = ConvertUTF8ToUTF16UnixLine(string, buffer->str, buffer->cap);
|
buffer->len = ConvertUTF8ToUTF16UnixLine(string, buffer->str, buffer->cap);
|
||||||
buffer->file_mod_time = GetFileModTime(path);
|
buffer->file_mod_time = GetFileModTime(path);
|
||||||
UpdateLines(buffer, {}, String16{(char16_t *)buffer->data, buffer->len});
|
UpdateLines(buffer, {}, String16{(char16_t *)buffer->data, buffer->len});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -730,7 +730,8 @@ void Coro_OpenCode(mco_coro *co) {
|
|||||||
|
|
||||||
void OpenCode(String dir) {
|
void OpenCode(String dir) {
|
||||||
Coro_OpenCodeDir = dir;
|
Coro_OpenCodeDir = dir;
|
||||||
CoAdd(Coro_OpenCode);
|
CoData *data = CoAdd(Coro_OpenCode);
|
||||||
|
data->dont_wait_until_resolved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Command_OpenCode() {
|
void Command_OpenCode() {
|
||||||
@@ -747,7 +748,7 @@ void Command_CloseWindow() {
|
|||||||
} RegisterCommand(Command_CloseWindow, "");
|
} RegisterCommand(Command_CloseWindow, "");
|
||||||
|
|
||||||
SaveResult TrySavingBuffer(Buffer *buffer) {
|
SaveResult TrySavingBuffer(Buffer *buffer) {
|
||||||
if (buffer->special || buffer->is_dir || buffer->garbage) {
|
if (buffer->special || buffer->garbage) {
|
||||||
return SAVE_NO;
|
return SAVE_NO;
|
||||||
}
|
}
|
||||||
if (buffer->dirty) {
|
if (buffer->dirty) {
|
||||||
@@ -781,15 +782,13 @@ SaveResult TrySavingAllBuffers() {
|
|||||||
return SAVE_YES;
|
return SAVE_YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Command_Close() {
|
void Coro_Close(mco_coro *co) {
|
||||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
BSet main = GetBSet(LastActiveLayoutWindowID);
|
||||||
if (TrySavingBuffer(main.buffer) == SAVE_CANCEL) {
|
if (main.buffer->special || main.buffer->garbage) {
|
||||||
|
Close(main.view->id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
main.window->active_view = FindInactiveView();
|
|
||||||
Close(main.view->id);
|
|
||||||
|
|
||||||
bool ref = false;
|
bool ref = false;
|
||||||
For (Views) {
|
For (Views) {
|
||||||
if (it->id == main.view->id) {
|
if (it->id == main.view->id) {
|
||||||
@@ -801,9 +800,56 @@ void Command_Close() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ref) {
|
if (ref) {
|
||||||
Close(main.buffer->id);
|
Close(main.view->id);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!main.buffer->dirty) {
|
||||||
|
Close(main.buffer->id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer *buffer = main.buffer;
|
||||||
|
JumpGarbageBuffer(&main);
|
||||||
|
NextActiveWindowID = main.window->id;
|
||||||
|
|
||||||
|
RawAppendf(main.buffer, R"==(
|
||||||
|
Do you want to save [%S] before closing?
|
||||||
|
|
||||||
|
:Yes :No :Cancel
|
||||||
|
)==", buffer->name);
|
||||||
|
main.view->carets[0] = FindNext(main.buffer, u":Yes", MakeCaret(0));
|
||||||
|
main.view->carets[0].range.min = main.view->carets[0].range.max;
|
||||||
|
Add(&main.view->hooks, {"Yes", "enter", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Yes";}, ParseKeyCached("enter")});
|
||||||
|
Add(&main.view->hooks, {"No", "", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "No";}, ParseKeyCached("")});
|
||||||
|
Add(&main.view->hooks, {"Cancel", "escape", [](){BSet active = GetBSet(ActiveWindowID); active.view->hook_cmd = "Cancel";}, ParseKeyCached("escape")});
|
||||||
|
for (;;) {
|
||||||
|
if (main.window->active_view != main.view->id || main.window->close) {
|
||||||
|
Close(main.buffer->id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (main.view->hook_cmd != "") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CoYield(co);
|
||||||
|
}
|
||||||
|
|
||||||
|
Close(main.buffer->id);
|
||||||
|
if (main.view->hook_cmd == "Yes") {
|
||||||
|
SaveBuffer(buffer);
|
||||||
|
Close(buffer->id);
|
||||||
|
} else if (main.view->hook_cmd == "No") {
|
||||||
|
Close(buffer->id);
|
||||||
|
} else if (main.view->hook_cmd == "Cancel") {
|
||||||
|
return;
|
||||||
|
} ElseInvalidCodepath();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Command_Close() {
|
||||||
|
CoAdd(Coro_Close);
|
||||||
} RegisterCommand(Command_Close, "ctrl-w");
|
} RegisterCommand(Command_Close, "ctrl-w");
|
||||||
|
|
||||||
void Command_Quit() {
|
void Command_Quit() {
|
||||||
@@ -829,63 +875,17 @@ void Command_CloseAll() {
|
|||||||
}
|
}
|
||||||
} RegisterCommand(Command_CloseAll, "");
|
} RegisterCommand(Command_CloseAll, "");
|
||||||
|
|
||||||
void Command_ForceClose() {
|
void Command_JumpBack() {
|
||||||
BSet active = GetBSet(ActiveWindowID);
|
|
||||||
Close(active.buffer->id);
|
|
||||||
Close(active.view->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// @todo: make these uneditable?
|
|
||||||
// @todo: maybe turn this into a coroutine???
|
|
||||||
String BufferIDea = R"==(
|
|
||||||
Do you want to save buffer? [C:/Programming/text_editor/build.sh]
|
|
||||||
|
|
||||||
:Yes :No
|
|
||||||
)==";
|
|
||||||
void Command_TestUIIdea() {
|
|
||||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
|
||||||
JumpGarbageBuffer(&main, "ui");
|
|
||||||
NextActiveWindowID = main.window->id;
|
|
||||||
|
|
||||||
Add(&main.view->hooks, {"Yes", "enter", [](){
|
|
||||||
BSet active = GetBSet(ActiveWindowID);
|
|
||||||
Caret a = FindNext(active.buffer, u"[", MakeCaret(0));
|
|
||||||
Caret b = FindNext(active.buffer, u"]", MakeCaret(0));
|
|
||||||
if (GetSize(a) == 0 || GetSize(b) == 0) {
|
|
||||||
ReportWarningf("Failed to save, '[' or ']' not found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Scratch scratch;
|
|
||||||
String16 string16 = GetString(active.buffer, {a.range.max, b.range.min});
|
|
||||||
String string = ToString(scratch, string16);
|
|
||||||
Buffer *buffer = GetBuffer(string, NULL);
|
|
||||||
if (buffer) {
|
|
||||||
SaveBuffer(buffer);
|
|
||||||
} else {
|
|
||||||
ReportWarningf("Failed to save, buffer not found: %S", string);
|
|
||||||
}
|
|
||||||
|
|
||||||
Close(active.buffer->id);
|
|
||||||
Close(active.view->id);
|
|
||||||
}, ParseKey(Perm, "enter", "Command_TestUIIdea_Yes")}); // @todo: fix memory leak
|
|
||||||
Add(&main.view->hooks, {"No", "escape", Command_ForceClose, ParseKeyCached("escape")});
|
|
||||||
RawAppend(main.buffer, BufferIDea);
|
|
||||||
main.view->carets[0] = FindNext(main.buffer, u":Yes", MakeCaret(0));
|
|
||||||
main.view->carets[0].range.min = main.view->carets[0].range.max;
|
|
||||||
} RegisterCommand(Command_TestUIIdea, "");
|
|
||||||
|
|
||||||
void Command_GotoBackward() {
|
|
||||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
BSet main = GetBSet(LastActiveLayoutWindowID);
|
||||||
main.window->skip_checkpoint = true;
|
main.window->skip_checkpoint = true;
|
||||||
GotoBackward(main.window);
|
JumpBack(main.window);
|
||||||
} RegisterCommand(Command_GotoBackward, "alt-q | mousex1");
|
} RegisterCommand(Command_JumpBack, "alt-q | mousex1");
|
||||||
|
|
||||||
void Command_GotoForward() {
|
void Command_JumpForward() {
|
||||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
BSet main = GetBSet(LastActiveLayoutWindowID);
|
||||||
main.window->skip_checkpoint = true;
|
main.window->skip_checkpoint = true;
|
||||||
GotoForward(main.window);
|
JumpForward(main.window);
|
||||||
} RegisterCommand(Command_GotoForward, "alt-shift-q | mousex2");
|
} RegisterCommand(Command_JumpForward, "alt-shift-q | mousex2");
|
||||||
|
|
||||||
void Command_OpenUpFolder() {
|
void Command_OpenUpFolder() {
|
||||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
BSet main = GetBSet(LastActiveLayoutWindowID);
|
||||||
|
|||||||
@@ -102,4 +102,4 @@ void Command_Cut() {
|
|||||||
SaveCaretHistoryBeforeBeginEdit(active.buffer, active.view->carets);
|
SaveCaretHistoryBeforeBeginEdit(active.buffer, active.view->carets);
|
||||||
ClipboardCopy(active.view);
|
ClipboardCopy(active.view);
|
||||||
Replace(active.view, u"");
|
Replace(active.view, u"");
|
||||||
} RegisterCommand(Command_Cut, "ctrl-x");
|
} RegisterCommand(Command_Cut, "ctrl-x");
|
||||||
|
|||||||
@@ -164,6 +164,9 @@ struct CachedTrigger {
|
|||||||
Array<CachedTrigger> CachedTriggers;
|
Array<CachedTrigger> CachedTriggers;
|
||||||
|
|
||||||
Trigger *ParseKeyCached(String key) {
|
Trigger *ParseKeyCached(String key) {
|
||||||
|
if (key.len == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
For (CachedTriggers) {
|
For (CachedTriggers) {
|
||||||
if (it.key == key) {
|
if (it.key == key) {
|
||||||
return it.trigger;
|
return it.trigger;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ void CoRemove(String name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define CoAdd(x) CoAddEx(x, #x)
|
#define CoAdd(x) CoAddEx(x, #x)
|
||||||
mco_coro *CoAddEx(CoroutineProc *proc, String name) {
|
CoData *CoAddEx(CoroutineProc *proc, String name) {
|
||||||
CoRemove(name);
|
CoRemove(name);
|
||||||
mco_desc desc = mco_desc_init(proc, 0);
|
mco_desc desc = mco_desc_init(proc, 0);
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ mco_coro *CoAddEx(CoroutineProc *proc, String name) {
|
|||||||
|
|
||||||
mco_resume(coro);
|
mco_resume(coro);
|
||||||
Add(&ActiveCoroutines, {coro, name});
|
Add(&ActiveCoroutines, {coro, name});
|
||||||
return coro;
|
return GetLast(ActiveCoroutines);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoUpdate(Event *event) {
|
void CoUpdate(Event *event) {
|
||||||
@@ -46,6 +46,8 @@ void CoUpdate(Event *event) {
|
|||||||
ReportWarningf("failed to resume coroutine %d", ok);
|
ReportWarningf("failed to resume coroutine %d", ok);
|
||||||
mco_destroy(it.co);
|
mco_destroy(it.co);
|
||||||
remove_item = true;
|
remove_item = true;
|
||||||
|
} else {
|
||||||
|
it.dont_wait_until_resolved = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,7 +64,7 @@ Event *CoYield(mco_coro *co) {
|
|||||||
Assert(ok == MCO_SUCCESS);
|
Assert(ok == MCO_SUCCESS);
|
||||||
|
|
||||||
Event *event = NULL;
|
Event *event = NULL;
|
||||||
ok = mco_pop(co, &event, sizeof(Event *));
|
ok = mco_pop(co, &event, sizeof(Event *));
|
||||||
Assert(ok == MCO_SUCCESS);
|
Assert(ok == MCO_SUCCESS);
|
||||||
|
|
||||||
return event;
|
return event;
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ Array<Variable> Variables;
|
|||||||
Array<Process> ActiveProcesses = {};
|
Array<Process> ActiveProcesses = {};
|
||||||
Array<String> ProcessEnviroment = {};
|
Array<String> ProcessEnviroment = {};
|
||||||
|
|
||||||
struct CoData { mco_coro *co; String name; };
|
struct CoData { mco_coro *co; String name; bool dont_wait_until_resolved; };
|
||||||
Array<CoData> ActiveCoroutines;
|
Array<CoData> ActiveCoroutines;
|
||||||
|
|
||||||
|
|
||||||
@@ -162,5 +162,5 @@ RegisterVariable(String, ConfigFont, "/home/krz/text_editor/package/CascadiaMono
|
|||||||
RegisterVariable(String, ConfigVCVarsall, "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat");
|
RegisterVariable(String, ConfigVCVarsall, "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat");
|
||||||
RegisterVariable(Float, ConfigUndoMergeTimeWindow, 0.3);
|
RegisterVariable(Float, ConfigUndoMergeTimeWindow, 0.3);
|
||||||
RegisterVariable(Float, ConfigJumpHistoryMergeTimeWindow, 0.3);
|
RegisterVariable(Float, ConfigJumpHistoryMergeTimeWindow, 0.3);
|
||||||
RegisterVariable(Int, ConfigJumpHistorySize, 512);
|
RegisterVariable(Int, ConfigJumpHistorySize, 4096);
|
||||||
RegisterVariable(String, ConfigInternetBrowser, "firefox");
|
RegisterVariable(String, ConfigInternetBrowser, "firefox");
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ void SetMouseCursor(SDL_SystemCursor id) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void SetMouseCursor(Event event) {
|
void SetMouseCursor(Event event) {
|
||||||
|
ProfileFunction();
|
||||||
Scratch scratch;
|
Scratch scratch;
|
||||||
Array<Window *> order = GetWindowZOrder(scratch);
|
Array<Window *> order = GetWindowZOrder(scratch);
|
||||||
Vec2I mouse = MouseVec2I();
|
Vec2I mouse = MouseVec2I();
|
||||||
@@ -448,7 +449,6 @@ void EvalCommand(String16 command) {
|
|||||||
EvalCommand(ToString(scratch, command));
|
EvalCommand(ToString(scratch, command));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GarbageCollect() {
|
void GarbageCollect() {
|
||||||
if (RunGCThisFrame == false) {
|
if (RunGCThisFrame == false) {
|
||||||
return;
|
return;
|
||||||
@@ -475,7 +475,11 @@ void GarbageCollect() {
|
|||||||
InvalidCodepath();
|
InvalidCodepath();
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer *buffer = GetBuffer(it->active_buffer);
|
Buffer *buffer = GetBuffer(it->active_buffer, NULL);
|
||||||
|
if (buffer == NULL || buffer->close) {
|
||||||
|
it->close = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!it->close) {
|
if (!it->close) {
|
||||||
if (!buffer->garbage) {
|
if (!buffer->garbage) {
|
||||||
continue;
|
continue;
|
||||||
@@ -487,7 +491,7 @@ void GarbageCollect() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RawAppendf(GCInfoBuffer, "View %d %S\n", (int)it->id.id, buffer->name);
|
RawAppendf(GCInfoBuffer, "View %d %S\n", (int)it->id.id, buffer ? buffer->name : String{"NULL"});
|
||||||
remove_item = true;
|
remove_item = true;
|
||||||
Dealloc(it);
|
Dealloc(it);
|
||||||
}
|
}
|
||||||
@@ -527,6 +531,11 @@ void GarbageCollect() {
|
|||||||
Dealloc(&it->goto_redo);
|
Dealloc(&it->goto_redo);
|
||||||
Dealloc(sys_allocator, it);
|
Dealloc(sys_allocator, it);
|
||||||
remove_item = true;
|
remove_item = true;
|
||||||
|
} else {
|
||||||
|
View *view = FindView(it->active_view, NULL);
|
||||||
|
if (!view) {
|
||||||
|
JumpToLastValidView(it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -673,8 +682,17 @@ void MainLoop() {
|
|||||||
Update(it);
|
Update(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool dont_wait_until_resolved = false;
|
||||||
|
For (ActiveCoroutines) {
|
||||||
|
if (it.dont_wait_until_resolved) {
|
||||||
|
dont_wait_until_resolved = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
WaitForEvents = ConfigWaitForEvents;
|
WaitForEvents = ConfigWaitForEvents;
|
||||||
if (IsDocumentSelectionValid() || IsScrollbarSelectionValid() || ActiveProcesses.len || ActiveCoroutines.len) {
|
if (IsDocumentSelectionValid() || IsScrollbarSelectionValid() || ActiveProcesses.len || dont_wait_until_resolved) {
|
||||||
WaitForEvents = false;
|
WaitForEvents = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -847,7 +865,8 @@ int main(int argc, char **argv)
|
|||||||
ReportConsolef("WorkDir = %S", WorkDir);
|
ReportConsolef("WorkDir = %S", WorkDir);
|
||||||
if (Testing) InitTests();
|
if (Testing) InitTests();
|
||||||
#if OS_WINDOWS
|
#if OS_WINDOWS
|
||||||
CoAdd(Windows_SetupVCVarsall);
|
CoData *co_data = CoAdd(Windows_SetupVCVarsall);
|
||||||
|
co_data->dont_wait_until_resolved = true;
|
||||||
#endif
|
#endif
|
||||||
#if OS_WASM
|
#if OS_WASM
|
||||||
emscripten_set_main_loop(MainLoop, 0, 1);
|
emscripten_set_main_loop(MainLoop, 0, 1);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ struct View {
|
|||||||
Caret main_caret_on_begin_frame;
|
Caret main_caret_on_begin_frame;
|
||||||
bool update_scroll;
|
bool update_scroll;
|
||||||
|
|
||||||
|
String hook_cmd;
|
||||||
Array<CommandData> hooks;
|
Array<CommandData> hooks;
|
||||||
String16 prev_search_line;
|
String16 prev_search_line;
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ Int ScreenSpaceToBufferPosErrorOutOfBounds(Window *window, View *view, Buffer *b
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
GotoCrumb GetCrumb(Array<GotoCrumb> *cr) {
|
GotoCrumb PopCrumb(Array<GotoCrumb> *cr) {
|
||||||
for (; cr->len;) {
|
for (; cr->len;) {
|
||||||
GotoCrumb c = Pop(cr);
|
GotoCrumb c = Pop(cr);
|
||||||
View *view = FindView(c.view_id, NULL);
|
View *view = FindView(c.view_id, NULL);
|
||||||
@@ -246,13 +246,33 @@ GotoCrumb GetCrumb(Array<GotoCrumb> *cr) {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void GotoBackward(Window *window) {
|
View *GetLastValidView(Window *window) {
|
||||||
|
For (IterateInReverse(&window->goto_redo)) {
|
||||||
|
if (it.view_id == window->active_view) continue;
|
||||||
|
View *view = FindView(it.view_id, NULL);
|
||||||
|
if (view) return view;
|
||||||
|
}
|
||||||
|
For (IterateInReverse(&window->goto_history)) {
|
||||||
|
if (it.view_id == window->active_view) continue;
|
||||||
|
View *view = FindView(it.view_id, NULL);
|
||||||
|
if (view) return view;
|
||||||
|
}
|
||||||
|
return Views[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
View *JumpToLastValidView(Window *window) {
|
||||||
|
View *view = GetLastValidView(window);
|
||||||
|
window->active_view = view->id;
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JumpBack(Window *window) {
|
||||||
if (window->jump_history == false) return;
|
if (window->jump_history == false) return;
|
||||||
if (window->goto_history.len <= 0) return;
|
if (window->goto_history.len <= 0) return;
|
||||||
BSet set = GetBSet(window);
|
BSet set = GetBSet(window);
|
||||||
Add(&window->goto_redo, {set.view->id, set.view->carets[0], GetTimeSeconds()});
|
Add(&window->goto_redo, {set.view->id, set.view->carets[0], GetTimeSeconds()});
|
||||||
|
|
||||||
GotoCrumb c = GetCrumb(&window->goto_history);
|
GotoCrumb c = PopCrumb(&window->goto_history);
|
||||||
window->active_view = c.view_id;
|
window->active_view = c.view_id;
|
||||||
View *view = GetView(c.view_id);
|
View *view = GetView(c.view_id);
|
||||||
view->carets[0] = c.caret;
|
view->carets[0] = c.caret;
|
||||||
@@ -261,18 +281,18 @@ void GotoBackward(Window *window) {
|
|||||||
if (window->goto_history.len) {
|
if (window->goto_history.len) {
|
||||||
GotoCrumb *next = GetLast(window->goto_history);
|
GotoCrumb *next = GetLast(window->goto_history);
|
||||||
if (c.view_id == next->view_id && c.time - next->time <= ConfigJumpHistoryMergeTimeWindow) {
|
if (c.view_id == next->view_id && c.time - next->time <= ConfigJumpHistoryMergeTimeWindow) {
|
||||||
GotoBackward(window);
|
JumpBack(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GotoForward(Window *window) {
|
void JumpForward(Window *window) {
|
||||||
if (window->jump_history == false) return;
|
if (window->jump_history == false) return;
|
||||||
if (window->goto_redo.len <= 0) return;
|
if (window->goto_redo.len <= 0) return;
|
||||||
BSet set = GetBSet(window);
|
BSet set = GetBSet(window);
|
||||||
Add(&window->goto_history, {set.view->id, set.view->carets[0], GetTimeSeconds()});
|
Add(&window->goto_history, {set.view->id, set.view->carets[0], GetTimeSeconds()});
|
||||||
|
|
||||||
GotoCrumb c = GetCrumb(&window->goto_redo);
|
GotoCrumb c = PopCrumb(&window->goto_redo);
|
||||||
window->active_view = c.view_id;
|
window->active_view = c.view_id;
|
||||||
View *view = GetView(c.view_id);
|
View *view = GetView(c.view_id);
|
||||||
view->carets[0] = c.caret;
|
view->carets[0] = c.caret;
|
||||||
@@ -281,7 +301,7 @@ void GotoForward(Window *window) {
|
|||||||
if (window->goto_redo.len) {
|
if (window->goto_redo.len) {
|
||||||
GotoCrumb *next = GetLast(window->goto_redo);
|
GotoCrumb *next = GetLast(window->goto_redo);
|
||||||
if (c.view_id == next->view_id && next->time - c.time <= ConfigJumpHistoryMergeTimeWindow) {
|
if (c.view_id == next->view_id && next->time - c.time <= ConfigJumpHistoryMergeTimeWindow) {
|
||||||
GotoForward(window);
|
JumpForward(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ void Command_ShowBufferList() {
|
|||||||
NextActiveWindowID = command_bar.window->id;
|
NextActiveWindowID = command_bar.window->id;
|
||||||
ResetBuffer(command_bar.buffer);
|
ResetBuffer(command_bar.buffer);
|
||||||
For (Buffers) {
|
For (Buffers) {
|
||||||
if (it->special || it->garbage || it->is_dir) {
|
if (it->special || it->garbage) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RawAppendf(command_bar.buffer, "\n%S", it->name);
|
RawAppendf(command_bar.buffer, "\n%S", it->name);
|
||||||
|
|||||||
Reference in New Issue
Block a user