diff --git a/Userland/DevTools/HackStudio/HackStudioWidget.cpp b/Userland/DevTools/HackStudio/HackStudioWidget.cpp index 0fafe27a98..c79b7979fc 100644 --- a/Userland/DevTools/HackStudio/HackStudioWidget.cpp +++ b/Userland/DevTools/HackStudio/HackStudioWidget.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -69,6 +70,7 @@ #include #include #include +#include #include #include #include @@ -231,6 +233,20 @@ bool HackStudioWidget::open_file(const String& full_filename) new_project_file = m_project->get_file(filename); m_open_files.set(filename, *new_project_file); m_open_files_vector.append(filename); + auto watcher_or_error = Core::FileWatcher::watch(filename); + if (!watcher_or_error.is_error()) { + auto& watcher = watcher_or_error.value(); + watcher->on_change = [this, filename]() { + struct stat st; + if (lstat(filename.characters(), &st) < 0) { + if (errno == ENOENT) { + handle_external_file_deletion(filename); + } + } + }; + m_file_watchers.set(filename, watcher_or_error.release_value()); + } + m_open_files_view->model()->update(); } @@ -1074,6 +1090,36 @@ void HackStudioWidget::initialize_menubar(GUI::Menubar& menubar) create_help_menubar(menubar); } +void HackStudioWidget::handle_external_file_deletion(const String& filepath) +{ + m_open_files.remove(filepath); + m_open_files_vector.remove_all_matching( + [&filepath](const String& element) { return element == filepath; }); + + for (auto& editor_wrapper : m_all_editor_wrappers) { + Editor& editor = editor_wrapper.editor(); + String editor_file_path = editor.code_document().file_path(); + String relative_editor_file_path = LexicalPath::relative_path(editor_file_path, project().root_path()); + + if (relative_editor_file_path == filepath) { + if (m_open_files_vector.is_empty()) { + editor.set_document(CodeDocument::create()); + editor_wrapper.filename_label().set_text(String { "Undefined" }); + m_currently_open_file = ""; + } else { + auto& first_path = m_open_files_vector[0]; + auto& document = m_open_files.get(first_path).value()->code_document(); + editor.set_document(document); + editor_wrapper.filename_label().set_text(first_path); + m_currently_open_file = first_path; + } + } + } + + m_file_watchers.remove(filepath); + m_open_files_view->model()->update(); +} + HackStudioWidget::~HackStudioWidget() { if (!m_debugger_thread.is_null()) { diff --git a/Userland/DevTools/HackStudio/HackStudioWidget.h b/Userland/DevTools/HackStudio/HackStudioWidget.h index 9cf5e8b6d6..312d138bf3 100644 --- a/Userland/DevTools/HackStudio/HackStudioWidget.h +++ b/Userland/DevTools/HackStudio/HackStudioWidget.h @@ -93,6 +93,8 @@ private: void reveal_action_tab(GUI::Widget&); void initialize_debugger(); + void handle_external_file_deletion(const String& filepath); + void create_open_files_view(GUI::Widget& parent); void create_form_editor(GUI::Widget& parent); void create_toolbar(GUI::Widget& parent); @@ -118,7 +120,8 @@ private: String m_currently_open_file; HashMap> m_open_files; - Vector m_open_files_vector; // NOTE: This contains the keys from m_open_files + HashMap> m_file_watchers; + Vector m_open_files_vector; // NOTE: This contains the keys from m_open_files and m_file_watchers OwnPtr m_project;