Continuing the hook refactor, BeforeSaveBuffer
This commit is contained in:
@@ -1142,6 +1142,7 @@ API void InitBuffer(Allocator allocator, Buffer *buffer, BufferID id = {}, Strin
|
||||
API void DeinitBuffer(Buffer *buffer) {
|
||||
Allocator allocator = buffer->line_starts.allocator;
|
||||
Dealloc(allocator, buffer->data);
|
||||
Dealloc(&buffer->hooks);
|
||||
Dealloc(&buffer->line_starts);
|
||||
DeallocHistoryArray(&buffer->undo_stack);
|
||||
DeallocHistoryArray(&buffer->redo_stack);
|
||||
@@ -1548,7 +1549,18 @@ void ReopenBuffer(Buffer *buffer) {
|
||||
buffer->dirty = false;
|
||||
}
|
||||
|
||||
void BasicSaveBuffer(Buffer *buffer) {
|
||||
void SaveBuffer(Buffer *buffer) {
|
||||
ProfileFunction();
|
||||
|
||||
For (GlobalHooks) {
|
||||
if (it.kind == HookKind_BeforeBufferSave) {
|
||||
ProfileScopeEx(it.name);
|
||||
HookParam param = {};
|
||||
param.buffer = buffer;
|
||||
it.function(param);
|
||||
}
|
||||
}
|
||||
|
||||
Scratch scratch;
|
||||
String string = AllocCharString(scratch, buffer);
|
||||
bool success = WriteFile(buffer->name, string);
|
||||
@@ -1561,11 +1573,3 @@ void BasicSaveBuffer(Buffer *buffer) {
|
||||
ReportWarningf("Failed to save file with name: %S", buffer->name);
|
||||
}
|
||||
}
|
||||
|
||||
void SaveBuffer(Buffer *buffer) {
|
||||
if (TrimTrailingWhitespace) {
|
||||
TrimWhitespace(buffer);
|
||||
}
|
||||
|
||||
BasicSaveBuffer(buffer);
|
||||
}
|
||||
|
||||
@@ -291,6 +291,12 @@ void TrimWhitespace(Buffer *buffer, bool trim_lines_with_caret) {
|
||||
view->update_scroll = false;
|
||||
}
|
||||
|
||||
void HOOK_TrimTrailingWhitespace(HookParam param) {
|
||||
if (TrimTrailingWhitespace) {
|
||||
TrimWhitespace(param.buffer, false);
|
||||
}
|
||||
} RegisterHook(HOOK_TrimTrailingWhitespace, HookKind_BeforeBufferSave, "", "Cleans trailing whitespace before saving to file");
|
||||
|
||||
void ConvertLineEndingsToLF(Buffer *buffer, bool trim_lines_with_caret = false) {
|
||||
Scratch scratch;
|
||||
|
||||
@@ -486,7 +492,7 @@ void CMD_SaveAll(HookParam param) {
|
||||
For(Buffers) {
|
||||
// NOTE: file_mod_time is only set when buffer got read or written to disk already so should be saved
|
||||
if (it->file_mod_time && it->dirty) {
|
||||
BasicSaveBuffer(it);
|
||||
SaveBuffer(it);
|
||||
}
|
||||
}
|
||||
} RegisterCommand(CMD_SaveAll, "ctrl-shift-s");
|
||||
|
||||
@@ -511,6 +511,7 @@ void GarbageCollect() {
|
||||
|
||||
RawAppendf(GCInfoBuffer, "View %d %S\n", (int)it->id.id, buffer ? buffer->name : String{"NULL"});
|
||||
remove_item = true;
|
||||
Dealloc(&it->hooks);
|
||||
Dealloc(it);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,59 @@ struct HistoryEntry {
|
||||
double time;
|
||||
};
|
||||
|
||||
enum HookKind {
|
||||
HookKind_Invalid,
|
||||
|
||||
HookKind_AppInit,
|
||||
HookKind_AppUpdate,
|
||||
HookKind_AppQuit,
|
||||
|
||||
// Should we have commands like PostCommand, PreCommand? what would be the purpose?
|
||||
HookKind_Command,
|
||||
|
||||
// Currently we are only basically allowing control over non-layouted windows.
|
||||
// How can this be expanded?
|
||||
// - Changing the layout algorithm: this seems like a decent one
|
||||
// - What beside that?
|
||||
HookKind_LayoutWindow,
|
||||
HookKind_RenderWindow,
|
||||
|
||||
HookKind_BeforeBufferSave,
|
||||
// HookKind_BufferSave,
|
||||
// HookKind_AfterBufferSave,
|
||||
|
||||
// HookKind_ResolveOpen,
|
||||
|
||||
// HookKind_BeforeBufferOpen,
|
||||
// HookKind_BufferOpen,
|
||||
// HookKind_AfterBufferOpen,
|
||||
|
||||
};
|
||||
|
||||
// Global hooks, per (window, view, buffer) hooks
|
||||
|
||||
struct HookParam {
|
||||
union {
|
||||
Buffer *buffer;
|
||||
struct {
|
||||
Window *window;
|
||||
Rect2I *rect;
|
||||
int16_t wx;
|
||||
int16_t wy;
|
||||
} layout;
|
||||
};
|
||||
};
|
||||
|
||||
typedef void HookFunction(HookParam param);
|
||||
struct Hook {
|
||||
HookKind kind;
|
||||
String name;
|
||||
String docs;
|
||||
HookFunction *function;
|
||||
String binding;
|
||||
struct Trigger *trigger;
|
||||
};
|
||||
|
||||
struct Buffer {
|
||||
BufferID id;
|
||||
String name;
|
||||
@@ -44,6 +97,7 @@ struct Buffer {
|
||||
Array<HistoryEntry> undo_stack;
|
||||
Array<HistoryEntry> redo_stack;
|
||||
int edit_phase;
|
||||
Array<Hook> hooks;
|
||||
struct {
|
||||
unsigned no_history : 1;
|
||||
unsigned no_line_starts : 1;
|
||||
@@ -57,58 +111,6 @@ struct Buffer {
|
||||
};
|
||||
};
|
||||
|
||||
enum HookKind {
|
||||
HookKind_Invalid,
|
||||
|
||||
HookKind_AppInit,
|
||||
HookKind_AppUpdate,
|
||||
HookKind_AppQuit,
|
||||
|
||||
// Should we have commands like PostCommand, PreCommand? what would be the purpose?
|
||||
HookKind_Command,
|
||||
|
||||
|
||||
// Currently we are only basically allowing control over non-layouted windows.
|
||||
// How can this be expanded?
|
||||
// - Changing the layout algorithm: this seems like a decent one
|
||||
// - What beside that?
|
||||
HookKind_LayoutWindow,
|
||||
HookKind_RenderWindow
|
||||
|
||||
HookKind_BeforeBufferSave,
|
||||
HookKind_BufferSave,
|
||||
HookKind_AfterBufferSave,
|
||||
|
||||
HookKind_BeforeBufferOpen,
|
||||
HookKind_BufferOpen,
|
||||
HookKind_AfterBufferOpen,
|
||||
|
||||
HookKind_ViewUpdate,
|
||||
};
|
||||
|
||||
// Global hooks, per (window, view, buffer) hooks
|
||||
|
||||
struct HookParam {
|
||||
union {
|
||||
struct {
|
||||
Window *window;
|
||||
Rect2I *rect;
|
||||
int16_t wx;
|
||||
int16_t wy;
|
||||
} layout;
|
||||
};
|
||||
};
|
||||
|
||||
typedef void HookFunction(HookParam param);
|
||||
struct Hook {
|
||||
HookKind kind;
|
||||
String name;
|
||||
String docs;
|
||||
HookFunction *function;
|
||||
String binding;
|
||||
struct Trigger *trigger;
|
||||
};
|
||||
|
||||
struct View {
|
||||
ViewID id;
|
||||
BufferID active_buffer;
|
||||
|
||||
Reference in New Issue
Block a user