diff --git a/src/text_editor/buffer.cpp b/src/text_editor/buffer.cpp index 19563f6..325f10f 100644 --- a/src/text_editor/buffer.cpp +++ b/src/text_editor/buffer.cpp @@ -1402,7 +1402,7 @@ bool IsNull(Buffer *buffer) { void Close(BufferID id) { Buffer *buffer = GetBuffer(id, NULL); if (buffer) { - if (buffer->id.id == 0) { + if (buffer->id.id == 0 || buffer->special) { return; } diff --git a/src/text_editor/commands.cpp b/src/text_editor/commands.cpp index f4aefd2..fb9482e 100644 --- a/src/text_editor/commands.cpp +++ b/src/text_editor/commands.cpp @@ -158,51 +158,6 @@ void Appendf(View *view, const char *fmt, ...) { Append(view, string, true); } -bool YesNoMessageBox(const char *title, const char *msg) { - SDL_MessageBoxButtonData buttons[] = { - { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 1, "No" }, - { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, "Yes" }, - }; - SDL_MessageBoxData data = {}; - data.flags = SDL_MESSAGEBOX_WARNING; - data.title = title; - data.message = msg; - data.numbuttons = 2; - data.buttons = buttons; - int resp; - bool status = SDL_ShowMessageBox(&data, &resp); - Assert(status); - bool result = resp == 0; - return result; -} - -enum SaveResult { - SAVE_CANCEL, - SAVE_NO, - SAVE_YES, -}; - -SaveResult SaveMessageBox(String filename) { - Scratch scratch; - const char *title = "There are unsaved changes, do you really want to quit?"; - const char *msg = Format(scratch, "Do you really want to quit? Unsaved buffer: %S", filename).data; - SDL_MessageBoxButtonData buttons[] = { - { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, SAVE_YES, "Save" }, - { 0, SAVE_NO, "Don't save" }, - { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, SAVE_CANCEL, "Cancel" }, - }; - SDL_MessageBoxData data = {}; - data.flags = SDL_MESSAGEBOX_WARNING; - data.title = title; - data.message = msg; - data.numbuttons = 3; - data.buttons = buttons; - int resp; - bool status = SDL_ShowMessageBox(&data, &resp); - Assert(status); - return (SaveResult)resp; -} - void ReportErrorf(const char *fmt, ...) { Scratch scratch; STRING_FORMAT(scratch, fmt, string); @@ -681,8 +636,8 @@ void Command_ToggleFullscreen() { SDL_GetWindowSize(SDLWindow, &FullScreenSizeX, &FullScreenSizeY); SDL_GetWindowPosition(SDLWindow, &FullScreenPositionX, &FullScreenPositionY); - SDL_DisplayID display = SDL_GetDisplayForWindow(SDLWindow); - const SDL_DisplayMode *dm = SDL_GetCurrentDisplayMode(display); + SDL_DisplayID display = SDL_GetDisplayForWindow(SDLWindow); + const SDL_DisplayMode *dm = SDL_GetCurrentDisplayMode(display); SDL_SetWindowSize(SDLWindow, dm->w, dm->h); SDL_SetWindowPosition(SDLWindow, 0, 0); } @@ -747,42 +702,7 @@ void Command_CloseWindow() { Close(LastActiveLayoutWindowID); } RegisterCommand(Command_CloseWindow, ""); -SaveResult TrySavingBuffer(Buffer *buffer) { - if (buffer->special || buffer->garbage) { - return SAVE_NO; - } - if (buffer->dirty) { - SaveResult save = SaveMessageBox(buffer->name); - if (save == SAVE_CANCEL) { - return SAVE_CANCEL; - } else if (save == SAVE_YES) { - SaveBuffer(buffer); - return SAVE_YES; - } else { - return SAVE_NO; - } - } - return SAVE_YES; -} - -SaveResult TrySavingAllBuffers() { - For (Buffers) { - if (it->garbage || it->special || it->dont_try_to_save_in_bulk_ops) { - continue; - } - if (it->dirty) { - SaveResult save = SaveMessageBox(it->name); - if (save == SAVE_CANCEL) { - return SAVE_CANCEL; - } else if (save == SAVE_YES) { - SaveBuffer(it); - } - } - } - return SAVE_YES; -} - -String UIYesNoCancel(mco_coro *co, BSet main, String question) { +String Coro_YesNoCancel(mco_coro *co, BSet main, String question) { JumpGarbageBuffer(&main); NextActiveWindowID = main.window->id; @@ -843,7 +763,7 @@ void Coro_Close(mco_coro *co) { Scratch scratch; String question = Format(scratch, "Do you want to save [%S] before closing?", main.buffer->name); - String result = UIYesNoCancel(co, main, question); + String result = Coro_YesNoCancel(co, main, question); if (result == "Yes") { SaveBuffer(main.buffer); Close(main.buffer->id); @@ -858,27 +778,57 @@ void Command_Close() { CoAdd(Coro_Close); } RegisterCommand(Command_Close, "ctrl-w"); -void Command_Quit() { - if (TrySavingAllBuffers() != SAVE_CANCEL) { +// Considerations with coroutines: +// 1. Does scratch memory leak across Yield boundary? Or interacts badly with Yield stuff in any way? +// 2. Are pointers and globals correct over time? Or might they get deleted etc. +String Coro_CloseAllEx(mco_coro *co) { + Scratch scratch; + BSet main = GetBSet(LastActiveLayoutWindowID); + Array buffers = {scratch}; + For (Buffers) Add(&buffers, it->id); + ForItem (id, buffers) { + Buffer *it = GetBuffer(id); + if (it->special || !it->dirty) { + continue; + } + if (it->garbage || it->dont_try_to_save_in_bulk_ops) { + continue; + } + + String question = Format(scratch, "Do you want to save [%S] before closing?", it->name); + String result = Coro_YesNoCancel(co, main, question); + it = GetBuffer(id, NULL); + if (it && result == "Yes") { + SaveBuffer(it); + } else if (result == "No") { + } else if (result == "Cancel") { + return "Cancel"; + } ElseInvalidCodepath(); + } + + For(Buffers) { + Close(it->id); + } + return "Yes"; +} + +void Coro_Quit(mco_coro *co) { + String res = Coro_CloseAllEx(co); + if (res != "Cancel") { AppIsRunning = false; } +} + +void Command_Quit() { + CoAdd(Coro_Quit); } RegisterCommand(Command_Quit, ""); +void Coro_CloseAll(mco_coro *co) { + Coro_CloseAllEx(co); +} + void Command_CloseAll() { - if (TrySavingAllBuffers() != SAVE_CANCEL) { - For (Views) { - if (it->special) { - continue; - } - Close(it->id); - } - For (Buffers) { - if (it->special) { - continue; - } - Close(it->id); - } - } + CoAdd(Coro_CloseAll); } RegisterCommand(Command_CloseAll, ""); void Command_JumpBack() {