diff --git a/data/core/dirwatch.lua b/data/core/dirwatch.lua index 314a33c0..c13e91ea 100644 --- a/data/core/dirwatch.lua +++ b/data/core/dirwatch.lua @@ -31,10 +31,13 @@ end -- In windows, this is a no-op for anything underneath a top-level directory, -- but code should be called anyway, so we can ensure that we have a proper -- experience across all platforms. Should be an absolute path. +-- Can also be called on individual files, though this should be used sparingly, +-- so as not to run into system limits (like in the autoreload plugin). function dirwatch:watch(directory, bool) if bool == false then return self:unwatch(directory) end if not self.watched[directory] and not self.scanned[directory] then if PLATFORM == "Windows" then + if system.get_file_info(directory).type ~= "dir" then return self:scan(directory) end if not self.windows_watch_top or directory:find(self.windows_watch_top, 1, true) ~= 1 then -- Get the highest level of directory that is common to this directory, and the original. local target = directory diff --git a/data/plugins/autoreload.lua b/data/plugins/autoreload.lua index fba22a23..4e8f5513 100644 --- a/data/plugins/autoreload.lua +++ b/data/plugins/autoreload.lua @@ -10,7 +10,16 @@ config.plugins.autoreload = common.merge({ always_show_nagview = false }, config.plugins.autoreload) +local function get_project_doc(doc) + for i, v in ipairs(core.project_directories) do + if doc.abs_filename:find(v.abs_filename, 1, true) == 1 then return v end + end + return nil +end + +local watch = dirwatch.new() local times = setmetatable({}, { __mode = "k" }) +local visible = setmetatable({}, { __mode = "k" }) local function update_time(doc) local info = system.get_file_info(doc.filename) @@ -23,9 +32,9 @@ local function reload_doc(doc) core.log_quiet("Auto-reloaded doc \"%s\"", doc.filename) end -local function check_prompt_reload() - if core.active_view.doc and core.active_view.doc.deferred_reload then - local doc = core.active_view.doc +local function check_prompt_reload(doc) + if doc or (core.active_view.doc and core.active_view.doc.deferred_reload) then + doc = doc or core.active_view.doc core.nag_view:show("File Changed", doc.filename .. " has changed. Reload this file?", { { font = style.font, text = "Yes", default_yes = true }, { font = style.font, text = "No" , default_no = true } @@ -36,6 +45,24 @@ local function check_prompt_reload() end end +local function doc_becomes_visible(doc) + if doc and not visible[doc] and doc.abs_filename then + visible[doc] = true + check_prompt_reload(doc) + local dir = get_project_doc(doc) + (dir and dir.watch or watch):watch(doc.abs_filename) + end +end + +local function doc_becomes_invisible(doc) + if doc and visible[doc] then + visible[doc] = false + local dir = get_project_doc(doc) + (dir and dir.watch or watch):unwatch(doc.abs_filename) + end +end + +>>>>>>> Stashed changes local function check_if_modified(doc) local info = system.get_file_info(doc.filename or "") if info and times[doc] ~= info.modified then @@ -51,7 +78,7 @@ local on_check = dirwatch.check function dirwatch:check(change_callback, ...) on_check(self, function(dir) for _, doc in ipairs(core.docs) do - if dir == common.dirname(doc.abs_filename) then + if dir == common.dirname(doc.abs_filename) or dir == doc.abs_filename then check_if_modified(doc) end end @@ -60,30 +87,28 @@ function dirwatch:check(change_callback, ...) check_prompt_reload() end - -local set_active_view = core.set_active_view +local core_set_active_view = core.set_active_view function core.set_active_view(view) - set_active_view(view) - check_prompt_reload() - if view.doc and view.doc.abs_filename then - local should_poll = true - for i,v in ipairs(core.project_directories) do - if view.doc.abs_filename:find(v.name, 1, true) == 1 and not v.files_limit then - should_poll = false - end - end - if should_poll then - local doc = core.active_view.doc - core.add_thread(function() - while core.active_view.doc == doc do - check_if_modified(doc) - coroutine.yield(0.25) - end - end) - end - end + core_set_active_view(view) + doc_becomes_visible(view.doc) end +local node_set_active_view = Node.set_active_view +function Node:set_active_view(view) + doc_becomes_invisible(self.active_view.doc) + node_set_active_view(self, view) + doc_becomes_visible(self.active_view.doc) +end + +core.add_thread(function() + while true do + -- because we already hook this function above; we only + -- need to check the file. + watch:check(function() end) + coroutine.yield(0.05) + end +end) + -- patch `Doc.save|load` to store modified time local load = Doc.load local save = Doc.save