diff --git a/data/core/dirwatch.lua b/data/core/dirwatch.lua index c13e91ea..093e541c 100644 --- a/data/core/dirwatch.lua +++ b/data/core/dirwatch.lua @@ -35,9 +35,11 @@ end -- 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 + local info = system.get_file_info(directory) + if not info then return 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 info.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 4e8f5513..03243851 100644 --- a/data/plugins/autoreload.lua +++ b/data/plugins/autoreload.lua @@ -3,6 +3,7 @@ local core = require "core" local config = require "core.config" local style = require "core.style" local Doc = require "core.doc" +local Node = require "core.node" local common = require "core.common" local dirwatch = require "core.dirwatch" @@ -10,31 +11,30 @@ 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 get_project_doc_watch(doc) + for i, v in ipairs(core.project_directories) do + if doc.abs_filename:find(v.name, 1, true) == 1 then return v.watch end + end + return watch +end + local function update_time(doc) - local info = system.get_file_info(doc.filename) - times[doc] = info.modified + times[doc] = system.get_file_info(doc.filename).modified end local function reload_doc(doc) doc:reload() update_time(doc) + core.redraw = true core.log_quiet("Auto-reloaded doc \"%s\"", doc.filename) end 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 + if doc and doc.deferred_reload then 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 } @@ -45,32 +45,11 @@ local function check_prompt_reload(doc) 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 - if not doc:is_dirty() and not config.plugins.autoreload.always_show_nagview then - reload_doc(doc) - else - doc.deferred_reload = true - end +local function doc_changes_visiblity(doc, visibility) + if doc and visible[doc] ~= visibility and doc.abs_filename then + visible[doc] = visibility + if visibility then check_prompt_reload(doc) end + get_project_doc_watch(doc):watch(doc.abs_filename, visibility) end end @@ -79,25 +58,32 @@ function dirwatch:check(change_callback, ...) on_check(self, function(dir) for _, doc in ipairs(core.docs) do if dir == common.dirname(doc.abs_filename) or dir == doc.abs_filename then - check_if_modified(doc) + local info = system.get_file_info(doc.filename or "") + if info and times[doc] ~= info.modified then + if not doc:is_dirty() and not config.plugins.autoreload.always_show_nagview then + reload_doc(doc) + else + doc.deferred_reload = true + if doc == core.active_view.doc then check_prompt_reload(doc) end + end + end end end change_callback(dir) end, ...) - check_prompt_reload() end local core_set_active_view = core.set_active_view function core.set_active_view(view) core_set_active_view(view) - doc_becomes_visible(view.doc) + doc_changes_visiblity(view.doc, true) end local node_set_active_view = Node.set_active_view function Node:set_active_view(view) - doc_becomes_invisible(self.active_view.doc) + if self.active_view then doc_changes_visiblity(self.active_view.doc, false) end node_set_active_view(self, view) - doc_becomes_visible(self.active_view.doc) + doc_changes_visiblity(self.active_view.doc, true) end core.add_thread(function() @@ -121,6 +107,8 @@ end Doc.save = function(self, ...) local res = save(self, ...) + -- if starting with an unsaved document with a filename. + if not times[self] then get_project_doc_watch(self):watch(self.abs_filename, true) end update_time(self) return res end diff --git a/src/api/dirmonitor/inotify.c b/src/api/dirmonitor/inotify.c index cb38c315..63e501a7 100644 --- a/src/api/dirmonitor/inotify.c +++ b/src/api/dirmonitor/inotify.c @@ -47,7 +47,7 @@ int translate_changes_dirmonitor(struct dirmonitor_internal* monitor, char* buff int add_dirmonitor(struct dirmonitor_internal* monitor, const char* path) { - return inotify_add_watch(monitor->fd, path, IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO); + return inotify_add_watch(monitor->fd, path, IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MODIFY | IN_MOVED_TO); }