diff --git a/src/text_editor/buffer.cpp b/src/text_editor/buffer.cpp index cb4b6e6..5752cc2 100644 --- a/src/text_editor/buffer.cpp +++ b/src/text_editor/buffer.cpp @@ -1460,21 +1460,22 @@ String GetUniqueBufferName(String working_dir, String prepend_name, String exten void InitBuffers() { Allocator sys_allocator = GetSystemAllocator(); Scratch scratch; - Buffer *null_buffer = CreateBuffer(sys_allocator, GetUniqueBufferName(GetWorkingDir(scratch), "console")); - null_buffer->dont_warn_on_save = true; + Buffer *null_buffer = CreateBuffer(sys_allocator, GetUniqueBufferName(GetWorkingDir(scratch), "console")); + null_buffer->special = true; View *null_view = CreateView(null_buffer->id); + null_view->special = true; Assert(null_buffer->id == NullBufferID && null_view->id == NullViewID); TraceBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(WorkDir, "trace")); - TraceBuffer->dont_warn_on_save = true; + TraceBuffer->special = true; TraceView = CreateView(TraceBuffer->id); GCInfoBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(WorkDir, "gc")); - GCInfoBuffer->dont_warn_on_save = true; + GCInfoBuffer->special = true; GCInfoBuffer->no_history = true; EventBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(WorkDir, "events")); - EventBuffer->dont_warn_on_save = true; EventBuffer->no_history = true; + EventBuffer->special = true; ScratchBuffer = BufferOpenFile(GetUniqueBufferName(WorkDir, "scratch")); - ScratchBuffer->dont_warn_on_save = true; + ScratchBuffer->special = true; } Int ConvertUTF8ToUTF16UnixLine(String string, char16_t *buffer, Int buffer_cap) { diff --git a/src/text_editor/buffer.h b/src/text_editor/buffer.h index cd7712d..b62de58 100644 --- a/src/text_editor/buffer.h +++ b/src/text_editor/buffer.h @@ -39,8 +39,9 @@ struct Buffer { unsigned dirty : 1; unsigned changed_on_disk : 1; unsigned garbage : 1; - unsigned dont_warn_on_save : 1; + unsigned dont_try_to_save_in_bulk_ops : 1; unsigned kill : 1; + unsigned special : 1; }; }; diff --git a/src/text_editor/commands.cpp b/src/text_editor/commands.cpp index 58e8c99..0cb5d65 100644 --- a/src/text_editor/commands.cpp +++ b/src/text_editor/commands.cpp @@ -193,14 +193,20 @@ bool YesNoMessageBox(const char *title, const char *msg) { return result; } -int SaveMessageBox(String filename) { +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, 2, "Save" }, - { 0, 1, "Don't save" }, - { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 0, "Cancel" }, + { 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; @@ -211,7 +217,7 @@ int SaveMessageBox(String filename) { int resp; bool status = SDL_ShowMessageBox(&data, &resp); Assert(status); - return resp; + return (SaveResult)resp; } void ReportErrorf(const char *fmt, ...) { @@ -447,7 +453,7 @@ void ListFilesRecursive(Buffer *buffer, String dir) { View *ExecHidden(String buffer_name, String cmd, String working_dir) { View *view = OpenBufferView(buffer_name); Buffer *buffer = GetBuffer(view->active_buffer); - buffer->dont_warn_on_save = true; + buffer->dont_try_to_save_in_bulk_ops = true; Exec(view->id, true, cmd, working_dir); return view; } @@ -672,16 +678,42 @@ void Command_CloseWindow() { main.window->kill = true; } RegisterCommand(Command_CloseWindow, ""); +SaveResult TrySavingBuffer(Buffer *buffer) { + 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; +} + void Command_Close() { BSet main = GetBSet(LastActiveLayoutWindowID); - - if (main.buffer->dirty) { - int save = SaveMessageBox(main.buffer->name); - if (save == 0) { - return; - } else if (save == 2) { - SaveBuffer(main.buffer); - } + if (TrySavingBuffer(main.buffer) == SAVE_CANCEL) { + return; } main.window->active_view = FindInactiveView(); @@ -703,6 +735,29 @@ void Command_Close() { } } RegisterCommand(Command_Close, "ctrl-w"); +void Command_Quit() { + if (TrySavingAllBuffers() != SAVE_CANCEL) { + AppIsRunning = false; + } +} RegisterCommand(Command_Quit, ""); + +void Command_CloseAll() { + if (TrySavingAllBuffers() != SAVE_CANCEL) { + For (Views) { + if (it->special) { + continue; + } + it->kill = true; + } + For (Buffers) { + if (it->special) { + continue; + } + it->kill = true; + } + } +} RegisterCommand(Command_CloseAll, ""); + void Command_GotoBackward() { BSet main = GetBSet(LastActiveLayoutWindowID); GotoBackward(main.window); @@ -1020,6 +1075,10 @@ void Command_FocusWindow3() { } } RegisterCommand(Command_FocusWindow3, "ctrl-3"); +void Command_NewWindow() { + CreateWind(); +} RegisterCommand(Command_NewWindow, "ctrl-backslash"); + void Command_ClearCarets() { BSet active = GetBSet(ActiveWindowID); active.view->carets.len = 1; diff --git a/src/text_editor/text_editor.cpp b/src/text_editor/text_editor.cpp index 78c040a..a4ebed6 100644 --- a/src/text_editor/text_editor.cpp +++ b/src/text_editor/text_editor.cpp @@ -410,25 +410,7 @@ void OnCommand(Event event) { } if (event.kind == EVENT_QUIT) { - Scratch scratch; - bool do_quit = true; - For (Buffers) { - if (it->garbage || it->dont_warn_on_save) { - continue; - } - if (it->dirty) { - int save = SaveMessageBox(it->name); - if (save == 0) { - break; - } else if (save == 2) { - SaveBuffer(it); - } - } - } - - if (do_quit) { - AppIsRunning = false; - } + Command_Quit(); } } @@ -469,8 +451,8 @@ void GarbageCollect() { IterRemove(Views) { IterRemovePrepare(Views); + Buffer *buffer = GetBuffer(it->active_buffer); if (it->kill == 0) { - Buffer *buffer = GetBuffer(it->active_buffer); if (!buffer->garbage) { continue; } @@ -481,6 +463,7 @@ void GarbageCollect() { } } + RawAppendf(GCInfoBuffer, "View %d %S\n", (int)it->id.id, buffer->name); remove_item = true; Dealloc(&it->carets); Dealloc(sys_allocator, it); @@ -506,6 +489,7 @@ void GarbageCollect() { } } + RawAppendf(GCInfoBuffer, "Buff %d %S\n", (int)it->id.id, it->name); remove_item = true; DeallocBuffer(it); } @@ -513,6 +497,7 @@ void GarbageCollect() { IterRemove(Windows) { IterRemovePrepare(Windows); if (it->kill) { + RawAppendf(GCInfoBuffer, "Wind %d %S\n", (int)it->id.id); Dealloc(&it->goto_history); Dealloc(&it->goto_redo); Dealloc(sys_allocator, it); diff --git a/src/text_editor/view.h b/src/text_editor/view.h index 1ce10ad..ef3352f 100644 --- a/src/text_editor/view.h +++ b/src/text_editor/view.h @@ -14,7 +14,7 @@ struct View { String16 prev_search_line; struct { unsigned kill : 1; - + unsigned special : 1; }; }; diff --git a/src/text_editor/window_command.cpp b/src/text_editor/window_command.cpp index 4ebb77e..dde4d21 100644 --- a/src/text_editor/window_command.cpp +++ b/src/text_editor/window_command.cpp @@ -2,8 +2,9 @@ void CommandWindowInit() { Window *window = CreateWind(); CommandBarWindowID = window->id; Buffer *buffer = CreateBuffer(SysAllocator, "command_bar"); - buffer->dont_warn_on_save = true; + buffer->special = true; View *view = CreateView(buffer->id); + view->special = true; window->active_view = view->id; window->draw_line_numbers = false; window->draw_scrollbar = false; diff --git a/src/text_editor/window_debug.cpp b/src/text_editor/window_debug.cpp index 8d7b4ea..bdb213a 100644 --- a/src/text_editor/window_debug.cpp +++ b/src/text_editor/window_debug.cpp @@ -9,11 +9,12 @@ void DebugWindowInit() { Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(WorkDir, "debug")); DebugBufferID = buffer->id; - buffer->dont_warn_on_save = true; buffer->no_history = true; + buffer->special = true; - View *view = CreateView(buffer->id); - DebugViewID = view->id; + View *view = CreateView(buffer->id); + view->special = true; + DebugViewID = view->id; window->active_view = view->id; window->visible = false; } diff --git a/src/text_editor/window_search.cpp b/src/text_editor/window_search.cpp index a0e1a89..5208073 100644 --- a/src/text_editor/window_search.cpp +++ b/src/text_editor/window_search.cpp @@ -2,9 +2,10 @@ void SearchWindowInit() { Window *window = CreateWind(); SearchBarWindowID = window->id; Buffer *buffer = CreateBuffer(SysAllocator, "search_bar"); - buffer->dont_warn_on_save = true; + buffer->special = true; SearchBufferID = buffer->id; View *view = CreateView(buffer->id); + view->special = true; SearchViewID = view->id; window->active_view = view->id; window->draw_line_numbers = false; diff --git a/src/text_editor/window_status.cpp b/src/text_editor/window_status.cpp index a7d72d1..a207bed 100644 --- a/src/text_editor/window_status.cpp +++ b/src/text_editor/window_status.cpp @@ -2,8 +2,9 @@ void StatusWindowInit() { Window *window = CreateWind(); StatusBarWindowID = window->id; Buffer *buffer = CreateBuffer(SysAllocator, "status_bar"); - buffer->dont_warn_on_save = true; + buffer->special = true; View *view = CreateView(buffer->id); + view->special = true; window->active_view = view->id; window->font = &SecondaryFont; window->draw_line_numbers = false;