From db24dbc3a0d215711cfce4e3c2fb7cbb75299c05 Mon Sep 17 00:00:00 2001 From: Francesco Abbate Date: Sun, 25 Jul 2021 15:16:01 +0200 Subject: [PATCH] Fix a new things about project rescan Add a flag core.redraw to force redraw when rescan is done. Inhibit recursion when files_limit is reached. Still doesn't work correctly for files limited directories. --- data/core/init.lua | 76 +++++++++++++++-------------- data/plugins/treeview.lua | 3 +- resources/notes-dmon-integration.md | 9 +++- 3 files changed, 48 insertions(+), 40 deletions(-) diff --git a/data/core/init.lua b/data/core/init.lua index 874e5ccb..ef2f1372 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -224,27 +224,6 @@ local function project_scan_add_entry(dir, fileinfo) end -function core.scan_project_subdir(dirname, filename) - for _, dir in ipairs(core.project_directories) do - if dir.name == dirname then - for i, file in ipairs(dir.files) do - local file = dir.files[i] - if file.filename == filename then - if file.scanned then return end - local new_files = get_directory_files(dirname, PATHSEP .. filename, {}) - for _, new_file in ipairs(new_files) do - -- FIXME: add index bounds to limit the scope of the search. - project_scan_add_entry(dir, new_file) - end - file.scanned = true - return true - end - end - end - end -end - - local function files_info_equal(a, b) return a.filename == b.filename and a.type == b.type end @@ -280,24 +259,30 @@ local function files_list_replace(as, i1, n, bs) end end +local function project_subdir_bounds(dir, filename) + local index, n = 0, #dir.files + for i, file in ipairs(dir.files) do + local file = dir.files[i] + if file.filename == filename then + index, n = i, #dir.files - i + for j = 1, #dir.files - i do + if not common.path_belongs_to(dir.files[i + j].filename, filename) then + n = j - 1 + break + end + end + return index, n, file + end + end +end + local function rescan_project_subdir(dir, filename_rooted) - local new_files = get_directory_files(dir.name, filename_rooted, {}, true, coroutine.yield) + local recursive = not dir.files_limit + local new_files = get_directory_files(dir.name, filename_rooted, {}, recursive, coroutine.yield) local index, n = 0, #dir.files if filename_rooted ~= "" then local filename = strip_leading_path(filename_rooted) - for i, file in ipairs(dir.files) do - local file = dir.files[i] - if file.filename == filename then - index, n = i, #dir.files - i - for j = 1, #dir.files - i do - if not common.path_belongs_to(dir.files[i + j].filename, filename) then - n = j - 1 - break - end - end - break - end - end + index, n = project_subdir_bounds(dir, filename) end if not files_list_match(dir.files, index, n, new_files) then @@ -307,6 +292,17 @@ local function rescan_project_subdir(dir, filename_rooted) end end + +function core.scan_project_subdir(dir, filename) + local index, n, file = project_subdir_bounds(dir, filename) + if index then + local new_files = get_directory_files(dir.name, PATHSEP .. filename, {}) + files_list_replace(dir.files, index, n, new_files) + file.scanned = true + return true + end +end + -- Find files and directories recursively reading from the filesystem. -- Filter files and yields file's directory and info table. This latter -- is filled to be like required by project directories "files" list. @@ -1060,10 +1056,13 @@ function core.dir_rescan_add_job(dir, filepath) local dirpath_rooted = dirpath and PATHSEP .. dirpath or "" local abs_dirpath = dir.name .. dirpath_rooted if dirpath then - local _, dir_match = file_search(dir.files, {filename = dirpath, type = "dir"}) - if not dir_match then return end + -- check if the directory is in the project files list, if not exit + local dir_index, dir_match = file_search(dir.files, {filename = dirpath, type = "dir"}) + if not dir_match or (dir.files_limit and not dir.files[dir_index].scanned) then return end end local new_time = system.get_time() + 1 + + -- evaluate new rescan request versus existing rescan local remove_list = {} for _, rescan in pairs(scheduled_rescan) do if abs_dirpath == rescan.abs_path or common.path_belongs_to(abs_dirpath, rescan.abs_path) then @@ -1071,12 +1070,14 @@ function core.dir_rescan_add_job(dir, filepath) rescan.time_limit = new_time return elseif common.path_belongs_to(rescan.abs_path, abs_dirpath) then + -- abs_dirpath already cover this rescan: add to the list of rescan to be removed table.insert(remove_list, rescan.abs_path) end end for _, key_path in ipairs(remove_list) do scheduled_rescan[key_path] = nil end + scheduled_rescan[abs_dirpath] = {dir = dir, path = dirpath_rooted, abs_path = abs_dirpath, time_limit = new_time} core.add_thread(function() while true do @@ -1085,6 +1086,7 @@ function core.dir_rescan_add_job(dir, filepath) if system.get_time() > rescan.time_limit then local has_changes = rescan_project_subdir(rescan.dir, rescan.path) if has_changes then + core.redraw = true -- we run without an event, from a thread rescan.time_limit = new_time else scheduled_rescan[rescan.abs_path] = nil diff --git a/data/plugins/treeview.lua b/data/plugins/treeview.lua index a45c7ff6..5b12af31 100644 --- a/data/plugins/treeview.lua +++ b/data/plugins/treeview.lua @@ -218,8 +218,7 @@ function TreeView:on_mouse_pressed(button, x, y, clicks) create_directory_in(hovered_item) else if hovered_item.dir.files_limit and not hovered_item.expanded then - local dirname = hovered_item.dir.name - core.scan_project_subdir(dirname, hovered_item.filename) + core.scan_project_subdir(hovered_item.dir, hovered_item.filename) end hovered_item.expanded = not hovered_item.expanded end diff --git a/resources/notes-dmon-integration.md b/resources/notes-dmon-integration.md index 6dfc997e..5179df40 100644 --- a/resources/notes-dmon-integration.md +++ b/resources/notes-dmon-integration.md @@ -14,7 +14,7 @@ `core.scan_project_subdir`: (before was named `core.scan_project_folder`) scan a single folder, without recursion. Used when too many files. -New local function `scan_project_folder`: +Local function `scan_project_folder`: Populate the project folder top directory. Done only once when the directory is added to the project. @@ -24,6 +24,13 @@ New local function `scan_project_folder`: `core.set_project_dir`: Set the initial project directory. +`core.dir_rescan_add_job`: + Add a job to rescan after an elapsed time a project's subdirectory to fix for any + changes. + +Local function `rescan_project_subdir`: + Rescan a project's subdirectory, compare to the current version and patch the list if + a difference is found. `core.project_scan_thread`: