Command_Close

This commit is contained in:
krzosa
2025-12-22 11:01:10 +01:00
parent 32efabac6a
commit 3ba7eeb1f2
7 changed files with 131 additions and 72 deletions

View File

@@ -1,8 +1,9 @@
- What precise workflow do I need for me to be viable to use this? - 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? - From a user (novice) point of view, how does it look like?
- "DO YOU REALLY WANT TO QUIT?" popup - Close all (ask to save)
- open all in the folder and ctrl + p like in VSCode (without special buffers) - 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 - 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?) - Window, View, Buffer + flags design (or is completely new kind based approach needed for Windows/Views?)

View File

@@ -1577,3 +1577,17 @@ void ReopenBuffer(Buffer *buffer) {
buffer->changed_on_disk = false; buffer->changed_on_disk = false;
buffer->dirty = 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);
}
}

View File

@@ -40,6 +40,7 @@ struct Buffer {
unsigned changed_on_disk : 1; unsigned changed_on_disk : 1;
unsigned garbage : 1; unsigned garbage : 1;
unsigned dont_warn_on_save : 1; unsigned dont_warn_on_save : 1;
unsigned kill : 1;
}; };
}; };

View File

@@ -193,7 +193,10 @@ bool YesNoMessageBox(const char *title, const char *msg) {
return result; 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_MessageBoxButtonData buttons[] = {
{ SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 2, "Save" }, { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 2, "Save" },
{ 0, 1, "Don't save" }, { 0, 1, "Don't save" },
@@ -345,52 +348,6 @@ void ApplyClangFormat(Buffer *buffer) {
ReplaceWithoutMovingCarets(buffer, GetRange(buffer), {temp_buffer->str, temp_buffer->len}); 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) { void GotoNextInList(Window *window, Int line_offset = 1) {
Assert(line_offset == 1 || line_offset == -1); Assert(line_offset == 1 || line_offset == -1);
View *active_view = GetView(window->active_view); View *active_view = GetView(window->active_view);
@@ -710,10 +667,41 @@ void Command_KillProcess() {
KillProcess(main.view); KillProcess(main.view);
} RegisterCommand(Command_KillProcess, ""); } RegisterCommand(Command_KillProcess, "");
void Command_KillWindow() { void Command_CloseWindow() {
BSet main = GetBSet(LastActiveLayoutWindowID); BSet main = GetBSet(LastActiveLayoutWindowID);
main.window->kill = true; 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() { void Command_GotoBackward() {
BSet main = GetBSet(LastActiveLayoutWindowID); BSet main = GetBSet(LastActiveLayoutWindowID);

View File

@@ -417,12 +417,10 @@ void OnCommand(Event event) {
continue; continue;
} }
if (it->dirty) { if (it->dirty) {
String message = Format(scratch, "Do you really want to quit? Unsaved buffer: %S", it->name); int save = SaveMessageBox(it->name);
int save = SaveMessageBox("There are unsaved changes, do you really want to quit!", message.data);
if (save == 0) { if (save == 0) {
break; break;
} } else if (save == 2) {
if (save == 2) {
SaveBuffer(it); SaveBuffer(it);
} }
} }
@@ -471,6 +469,7 @@ void GarbageCollect() {
IterRemove(Views) { IterRemove(Views) {
IterRemovePrepare(Views); IterRemovePrepare(Views);
if (it->kill == 0) {
Buffer *buffer = GetBuffer(it->active_buffer); Buffer *buffer = GetBuffer(it->active_buffer);
if (!buffer->garbage) { if (!buffer->garbage) {
continue; continue;
@@ -480,6 +479,7 @@ void GarbageCollect() {
if (ref) { if (ref) {
continue; continue;
} }
}
remove_item = true; remove_item = true;
Dealloc(&it->carets); Dealloc(&it->carets);
@@ -489,6 +489,13 @@ void GarbageCollect() {
IterRemove(Buffers) { IterRemove(Buffers) {
IterRemovePrepare(Buffers); IterRemovePrepare(Buffers);
if (it->id.id == 0) {
it->kill = 0;
continue;
}
if (it->kill == 0) {
if (!it->garbage) { if (!it->garbage) {
continue; continue;
} }
@@ -497,6 +504,7 @@ void GarbageCollect() {
if (ref) { if (ref) {
continue; continue;
} }
}
remove_item = true; remove_item = true;
DeallocBuffer(it); DeallocBuffer(it);

View File

@@ -59,6 +59,15 @@ API bool ViewIsCrumb(ViewID view_id) {
return false; return false;
} }
bool ViewIsActive(ViewID id) {
For (Windows) {
if (it->active_view == id) {
return true;
}
}
return false;
}
API bool ViewIsReferenced(ViewID view) { API bool ViewIsReferenced(ViewID view) {
if (view == NullViewID) { if (view == NullViewID) {
return true; return true;
@@ -68,12 +77,14 @@ API bool ViewIsReferenced(ViewID view) {
return true; return true;
} }
For(Windows) { return ViewIsActive(view);
if (it->active_view == view) {
return true;
} }
ViewID FindInactiveView(ViewID default_view = NullViewID) {
For (Views) {
if (!ViewIsActive(it->id)) return it->id;
} }
return false; return default_view;
} }
String16 FetchLoadWord(View *view) { String16 FetchLoadWord(View *view) {
@@ -566,3 +577,35 @@ void DuplicateLine(View *view, int direction) {
caret->range.max = XYToPos(buffer, xymax); 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);
}
}

View File

@@ -12,6 +12,10 @@ struct View {
bool update_scroll; bool update_scroll;
String16 prev_search_line; String16 prev_search_line;
struct {
unsigned kill : 1;
};
}; };
struct GotoCrumb { struct GotoCrumb {