diff --git a/src/backup/todo.txt b/src/backup/todo.txt index c9fe551..115dac2 100644 --- a/src/backup/todo.txt +++ b/src/backup/todo.txt @@ -1,8 +1,9 @@ - What precise workflow do I need for me to be viable to use this? - From a user (novice) point of view, how does it look like? -- "DO YOU REALLY WANT TO QUIT?" popup -- open all in the folder and ctrl + p like in VSCode (without special buffers) +- Close all (ask to save) + - Close buffer instead of window (ask to save) +- Open all in the folder and ctrl + p like in VSCode (without special buffers) - Guide on the first page for new users with links to configs, tutorials - Window, View, Buffer + flags design (or is completely new kind based approach needed for Windows/Views?) diff --git a/src/text_editor/buffer.cpp b/src/text_editor/buffer.cpp index 27f5a80..cb4b6e6 100644 --- a/src/text_editor/buffer.cpp +++ b/src/text_editor/buffer.cpp @@ -1577,3 +1577,17 @@ void ReopenBuffer(Buffer *buffer) { buffer->changed_on_disk = false; buffer->dirty = false; } + +void SaveBuffer(Buffer *buffer) { + Scratch scratch; + String string = AllocCharString(scratch, buffer); + bool success = WriteFile(buffer->name, string); + + if (success) { + buffer->file_mod_time = GetFileModTime(buffer->name); + buffer->dirty = false; + buffer->garbage = false; + } else { + ReportWarningf("Failed to save file with name: %S", buffer->name); + } +} diff --git a/src/text_editor/buffer.h b/src/text_editor/buffer.h index f5f519b..cd7712d 100644 --- a/src/text_editor/buffer.h +++ b/src/text_editor/buffer.h @@ -40,6 +40,7 @@ struct Buffer { unsigned changed_on_disk : 1; unsigned garbage : 1; unsigned dont_warn_on_save : 1; + unsigned kill : 1; }; }; diff --git a/src/text_editor/commands.cpp b/src/text_editor/commands.cpp index a1df478..58e8c99 100644 --- a/src/text_editor/commands.cpp +++ b/src/text_editor/commands.cpp @@ -193,7 +193,10 @@ bool YesNoMessageBox(const char *title, const char *msg) { return result; } -int SaveMessageBox(const char *title, const char *msg) { +int 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" }, @@ -345,52 +348,6 @@ void ApplyClangFormat(Buffer *buffer) { ReplaceWithoutMovingCarets(buffer, GetRange(buffer), {temp_buffer->str, temp_buffer->len}); } -void SaveBuffer(Buffer *buffer) { - Scratch scratch; - String string = AllocCharString(scratch, buffer); - bool success = WriteFile(buffer->name, string); - - if (success) { - buffer->file_mod_time = GetFileModTime(buffer->name); - buffer->dirty = false; - buffer->garbage = false; - } else { - ReportWarningf("Failed to save file with name: %S", buffer->name); - } -} - -void KillSelectedLines(View *view) { - Scratch scratch; - Buffer *buffer = GetBuffer(view->active_buffer); - SaveCaretHistoryBeforeBeginEdit(buffer, view->carets); - - For (view->carets) { - Int eof = 0; - it.range.max = GetFullLineEnd(buffer, it.range.max, &eof); - it.range.min = GetFullLineStart(buffer, it.range.min); - it.range.min -= Clamp(eof, (Int)0, buffer->len); - } - Replace(view, u""); -} - -void EncloseLine(View *view) { - Buffer *buffer = GetBuffer(view->active_buffer); - For (view->carets) { - Int eof = 0; - it.range.max = GetFullLineEnd(buffer, it.range.max, &eof); - it.range.min = GetFullLineStart(buffer, it.range.min); - } -} - -void EncloseScope(View *view) { - Buffer *buffer = GetBuffer(view->active_buffer); - For (view->carets) { - it.range = EncloseScope(buffer, it.range.min - 1, it.range.max + 1, u'(', u')'); - it.range.min = Clamp(buffer, it.range.min + 1); - it.range.max = Clamp(buffer, it.range.max - 1); - } -} - void GotoNextInList(Window *window, Int line_offset = 1) { Assert(line_offset == 1 || line_offset == -1); View *active_view = GetView(window->active_view); @@ -710,10 +667,41 @@ void Command_KillProcess() { KillProcess(main.view); } RegisterCommand(Command_KillProcess, ""); -void Command_KillWindow() { +void Command_CloseWindow() { BSet main = GetBSet(LastActiveLayoutWindowID); main.window->kill = true; -} RegisterCommand(Command_KillWindow, "ctrl-w"); +} RegisterCommand(Command_CloseWindow, ""); + +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); + } + } + + main.window->active_view = FindInactiveView(); + main.view->kill = true; + + bool ref = false; + For (Views) { + if (it->id == main.view->id) { + continue; + } + if (it->active_buffer == main.buffer->id) { + ref = true; + break; + } + } + + if (!ref) { + main.buffer->kill = true; + } +} RegisterCommand(Command_Close, "ctrl-w"); void Command_GotoBackward() { BSet main = GetBSet(LastActiveLayoutWindowID); diff --git a/src/text_editor/text_editor.cpp b/src/text_editor/text_editor.cpp index a85a157..78c040a 100644 --- a/src/text_editor/text_editor.cpp +++ b/src/text_editor/text_editor.cpp @@ -417,12 +417,10 @@ void OnCommand(Event event) { continue; } if (it->dirty) { - String message = Format(scratch, "Do you really want to quit? Unsaved buffer: %S", it->name); - int save = SaveMessageBox("There are unsaved changes, do you really want to quit!", message.data); + int save = SaveMessageBox(it->name); if (save == 0) { break; - } - if (save == 2) { + } else if (save == 2) { SaveBuffer(it); } } @@ -471,14 +469,16 @@ void GarbageCollect() { IterRemove(Views) { IterRemovePrepare(Views); - Buffer *buffer = GetBuffer(it->active_buffer); - if (!buffer->garbage) { - continue; - } + if (it->kill == 0) { + Buffer *buffer = GetBuffer(it->active_buffer); + if (!buffer->garbage) { + continue; + } - bool ref = ViewIsReferenced(it->id); - if (ref) { - continue; + bool ref = ViewIsReferenced(it->id); + if (ref) { + continue; + } } remove_item = true; @@ -489,13 +489,21 @@ void GarbageCollect() { IterRemove(Buffers) { IterRemovePrepare(Buffers); - if (!it->garbage) { + + if (it->id.id == 0) { + it->kill = 0; continue; } - bool ref = BufferIsReferenced(it->id); - if (ref) { - continue; + if (it->kill == 0) { + if (!it->garbage) { + continue; + } + + bool ref = BufferIsReferenced(it->id); + if (ref) { + continue; + } } remove_item = true; diff --git a/src/text_editor/view.cpp b/src/text_editor/view.cpp index 7cfb6d7..1130e82 100644 --- a/src/text_editor/view.cpp +++ b/src/text_editor/view.cpp @@ -59,6 +59,15 @@ API bool ViewIsCrumb(ViewID view_id) { return false; } +bool ViewIsActive(ViewID id) { + For (Windows) { + if (it->active_view == id) { + return true; + } + } + return false; +} + API bool ViewIsReferenced(ViewID view) { if (view == NullViewID) { return true; @@ -68,12 +77,14 @@ API bool ViewIsReferenced(ViewID view) { return true; } - For(Windows) { - if (it->active_view == view) { - return true; - } + return ViewIsActive(view); +} + +ViewID FindInactiveView(ViewID default_view = NullViewID) { + For (Views) { + if (!ViewIsActive(it->id)) return it->id; } - return false; + return default_view; } String16 FetchLoadWord(View *view) { @@ -566,3 +577,35 @@ void DuplicateLine(View *view, int direction) { caret->range.max = XYToPos(buffer, xymax); } } + +void KillSelectedLines(View *view) { + Scratch scratch; + Buffer *buffer = GetBuffer(view->active_buffer); + SaveCaretHistoryBeforeBeginEdit(buffer, view->carets); + + For (view->carets) { + Int eof = 0; + it.range.max = GetFullLineEnd(buffer, it.range.max, &eof); + it.range.min = GetFullLineStart(buffer, it.range.min); + it.range.min -= Clamp(eof, (Int)0, buffer->len); + } + Replace(view, u""); +} + +void EncloseLine(View *view) { + Buffer *buffer = GetBuffer(view->active_buffer); + For (view->carets) { + Int eof = 0; + it.range.max = GetFullLineEnd(buffer, it.range.max, &eof); + it.range.min = GetFullLineStart(buffer, it.range.min); + } +} + +void EncloseScope(View *view) { + Buffer *buffer = GetBuffer(view->active_buffer); + For (view->carets) { + it.range = EncloseScope(buffer, it.range.min - 1, it.range.max + 1, u'(', u')'); + it.range.min = Clamp(buffer, it.range.min + 1); + it.range.max = Clamp(buffer, it.range.max - 1); + } +} diff --git a/src/text_editor/view.h b/src/text_editor/view.h index 7bc1503..1ce10ad 100644 --- a/src/text_editor/view.h +++ b/src/text_editor/view.h @@ -12,6 +12,10 @@ struct View { bool update_scroll; String16 prev_search_line; + struct { + unsigned kill : 1; + + }; }; struct GotoCrumb { @@ -28,4 +32,4 @@ API View *FindView(String name, View *default_view = NULL); API View *GetView(ViewID id); API View *OpenBufferView(String name); API bool ViewIsCrumb(ViewID view_id); -API bool ViewIsReferenced(ViewID view); \ No newline at end of file +API bool ViewIsReferenced(ViewID view);