Reopen changed files

This commit is contained in:
Krzosa Karol
2024-08-14 07:35:12 +02:00
parent f125a38c50
commit 2b4a43ddc1
9 changed files with 80 additions and 22 deletions

View File

@@ -26,13 +26,14 @@ void Advance(FileIter *it);
FileIter IterateFiles(Allocator allocator, String path);
void InitOS(void (*error_proc)(const char *, ...));
String GetExePath(Allocator allocator);
String GetExeDir(Allocator allocator);
bool FileExists(String path);
bool IsDir(String path);
bool IsFile(String path);
String GetWorkingDir(Allocator arena);
bool IsAbsolute(String path);
String GetExePath(Allocator allocator);
String GetExeDir(Allocator allocator);
bool FileExists(String path);
bool IsDir(String path);
bool IsFile(String path);
String GetWorkingDir(Allocator arena);
bool IsAbsolute(String path);
int64_t GetFileModTime(String file);
struct Process {
bool is_valid;

View File

@@ -262,6 +262,21 @@ bool DeleteFile(String path) {
return result;
}
int64_t GetFileModTime(String file) {
Scratch scratch;
String16 string16 = ToString16(scratch, file);
WIN32_FIND_DATAW data;
HANDLE handle = FindFirstFileW(string16.data, &data);
if (handle != INVALID_HANDLE_VALUE) {
FindClose(handle);
FILETIME time = data.ftLastWriteTime;
int64_t result = (int64_t)time.dwHighDateTime << 32 | time.dwLowDateTime;
return result;
} else {
return -1;
}
}
struct Win32Process {
HANDLE handle;
HANDLE child_stdout_read;

View File

@@ -667,7 +667,8 @@ void SaveBuffer(View *view) {
bool success = WriteFile(buffer->name, string);
if (success) {
buffer->dirty = false;
buffer->file_mod_time = GetFileModTime(buffer->name);
buffer->dirty = false;
} else {
ReportWarningf("Failed to save file with name: %.*s", FmtString(buffer->name));
}

View File

@@ -116,6 +116,12 @@ int Lua_Open(lua_State *L) {
return 0;
}
int Lua_Reopen(lua_State *L) {
BSet main = GetActiveMainSet();
ReopenBuffer(main.buffer);
return 0;
}
int Lua_Print(lua_State *L) {
Scratch scratch;
String string = lua_tostring(L, 1);

View File

@@ -4,6 +4,7 @@ luaL_Reg LuaFunctions[] = {
{"C", Lua_C},
{"Kill", Lua_Kill},
{"Open", Lua_Open},
{"Reopen", Lua_Reopen},
{"Print", Lua_Print},
{"ListBuffers", Lua_ListBuffers},
{"GetBufferList", Lua_GetBufferList},

View File

@@ -309,15 +309,34 @@ Buffer *BufferOpenFile(String path) {
IKnowWhatImDoing_Appendf(buffer, "%.*s\n", FmtString(it.filename));
}
} else {
String string = ReadFile(scratch, path);
buffer = CreateBuffer(sys_allocator, path, string.len * 4 + 4096);
buffer->len = ConvertUTF8ToUTF16UnixLine(string, buffer->str, buffer->cap);
String string = ReadFile(scratch, path);
buffer = CreateBuffer(sys_allocator, path, string.len * 4 + 4096);
buffer->len = ConvertUTF8ToUTF16UnixLine(string, buffer->str, buffer->cap);
buffer->file_mod_time = GetFileModTime(path);
UpdateLines(buffer, {}, String16{(wchar_t *)buffer->data, buffer->len});
}
return buffer;
}
void ResetBuffer(Buffer *buffer) {
Assert(buffer->edit_phase == 0);
buffer->line_starts.len = 1;
DeallocHistoryEntries(&buffer->redo_stack);
DeallocHistoryEntries(&buffer->undo_stack);
}
void ReopenBuffer(Buffer *buffer) {
Scratch scratch;
String string = ReadFile(scratch, buffer->name);
if (string.len) {
ResetBuffer(buffer);
buffer->len = ConvertUTF8ToUTF16UnixLine(string, buffer->str, buffer->cap);
buffer->file_mod_time = GetFileModTime(buffer->name);
UpdateLines(buffer, {}, String16{(wchar_t *)buffer->data, buffer->len});
}
}
View *OpenBufferView(String name) {
Buffer *buffer = BufferOpenFile(name);
View *view = CreateView(buffer->id);
@@ -364,6 +383,15 @@ View *BufferIsReferenced(BufferID buffer_id) {
return NULL;
}
Window *BufferIsInWindow(BufferID buffer_id) {
For(Windows) {
Window *window = it.o;
View *view = GetView(window->active_view);
if (view->active_buffer == buffer_id) return window;
}
return NULL;
}
Window *BufferIsCrumb(BufferID buffer_id) {
For(Windows) {
Window *window = it.o;
@@ -378,7 +406,11 @@ void GarbageCollect() {
IterRemovePrepare(Views);
View *view = it.o;
Buffer *buffer = GetBuffer(view->active_buffer);
bool gc = buffer->gc || buffer->is_directory;
bool gc = buffer->gc;
if (buffer->is_directory) {
Window *ref = BufferIsCrumb(buffer->id);
if (!ref) gc = true;
}
Window *ref = ViewIsReferenced(view->id);
if (gc && !ref) {
@@ -394,10 +426,6 @@ void GarbageCollect() {
IterRemovePrepare(Buffers);
Buffer *buffer = it.o;
bool gc = buffer->gc;
if (buffer->is_directory) {
Window *ref = BufferIsCrumb(buffer->id);
if (!ref) gc = true;
}
View *ref = BufferIsReferenced(buffer->id);
if (gc && !ref) {
@@ -409,6 +437,11 @@ void GarbageCollect() {
// @todo: add buffer to free list
Command_Appendf(GCInfoView, "buffer %.*s", FmtString(buffer->name));
} else if (buffer->file_mod_time) {
int64_t new_file_mod_time = GetFileModTime(buffer->name);
if (buffer->file_mod_time != new_file_mod_time) {
buffer->changed_on_disk = true;
}
}
}
}
}

View File

@@ -25,6 +25,7 @@ struct Buffer {
BufferID id;
String name;
Int change_id;
Int file_mod_time;
union {
U16 *data;
@@ -42,6 +43,7 @@ struct Buffer {
int dirty : 1;
int is_directory : 1;
int gc : 1;
int changed_on_disk : 1;
};
};

View File

@@ -45,7 +45,8 @@ void ReplaceTitleBarData(Window *window) {
AdjustCarets(edits, &caret_copy);
}
String s = Format(scratch, "%.*s:%lld:%lld", FmtString(main.buffer->name), (long long)xy.line + 1ll, (long long)xy.col + 1ll);
char *reopen = main.buffer->changed_on_disk ? " #Reopen()" : "";
String s = Format(scratch, "%.*s:%lld:%lld%s", FmtString(main.buffer->name), (long long)xy.line + 1ll, (long long)xy.col + 1ll, reopen);
String16 string = ToString16(scratch, s);
String16 string_to_replace = GetString(title.buffer, replace_range);
if (string_to_replace != string) {

View File

@@ -1,7 +1,5 @@
- garbage collect the buffers, views - store them in free list on destroy
- adding items to directory should create files on save - it should ask the user (syntax: dir/ | file)
- refresh the directory - when opening up again?
- refresh the file content, periodically check file timestamp for changes and update if neccessary
- ask user if he really wants to quit even though he has an unsaved buffer - popup window
- add plumb rules for some web stuff
- test the code editor: try writing in it, try browsing in it, create test tooling
@@ -12,8 +10,8 @@
- group history entries so the you can rollback through multiple ones at once and not waste time on skipping whitespace trimming or deleting every character
- Check if file exists in ApplyRules otherwise return null
- Different buffers should be GCed differently
- Special buffers that store metadata
- Add the event buffer with serialized events
- Gotos, jumping between views should preserve cursors
- OnWindowCommand allow config user to overwrite the WindowCommand keybinding, introduce his own