Fix several problem with directory update
When scanning a subdirectory on-demand ensure files aready present are not added twice. Files or directory can be already present due to dir monitoring create message. Fix check for ignore files when adding a file to respond to a dir monitor event to use each part of the file's path. Fix C function to compare files for treeview placement.
This commit is contained in:
parent
d3c7a43a60
commit
8e7d3c0f66
|
@ -194,6 +194,36 @@ function core.add_project_directory(path)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function file_search(files, info)
|
||||||
|
local filename, type = info.filename, info.type
|
||||||
|
local inf, sup = 1, #files
|
||||||
|
while sup - inf > 8 do
|
||||||
|
local curr = math.floor((inf + sup) / 2)
|
||||||
|
if system.path_compare(filename, type, files[curr].filename, files[curr].type) then
|
||||||
|
sup = curr - 1
|
||||||
|
else
|
||||||
|
inf = curr
|
||||||
|
end
|
||||||
|
end
|
||||||
|
repeat
|
||||||
|
if files[inf].filename == filename then
|
||||||
|
return inf, true
|
||||||
|
end
|
||||||
|
inf = inf + 1
|
||||||
|
until inf > sup or system.path_compare(filename, type, files[inf].filename, files[inf].type)
|
||||||
|
return inf, false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function project_scan_add_entry(dir, fileinfo)
|
||||||
|
local index, match = file_search(dir.files, fileinfo)
|
||||||
|
if not match then
|
||||||
|
table.insert(dir.files, index, fileinfo)
|
||||||
|
dir.is_dirty = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function core.scan_project_subdir(dirname, filename)
|
function core.scan_project_subdir(dirname, filename)
|
||||||
for _, dir in ipairs(core.project_directories) do
|
for _, dir in ipairs(core.project_directories) do
|
||||||
if dir.name == dirname then
|
if dir.name == dirname then
|
||||||
|
@ -202,8 +232,8 @@ function core.scan_project_subdir(dirname, filename)
|
||||||
if file.filename == filename then
|
if file.filename == filename then
|
||||||
if file.scanned then return end
|
if file.scanned then return end
|
||||||
local new_files = get_directory_files(dirname, PATHSEP .. filename, {})
|
local new_files = get_directory_files(dirname, PATHSEP .. filename, {})
|
||||||
for j, new_file in ipairs(new_files) do
|
for _, new_file in ipairs(new_files) do
|
||||||
table.insert(dir.files, i + j, new_file)
|
project_scan_add_entry(dir, new_file)
|
||||||
end
|
end
|
||||||
file.scanned = true
|
file.scanned = true
|
||||||
return true
|
return true
|
||||||
|
@ -289,27 +319,6 @@ function core.project_files_number()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function file_search(files, info)
|
|
||||||
local filename, type = info.filename, info.type
|
|
||||||
local inf, sup = 1, #files
|
|
||||||
while sup - inf > 8 do
|
|
||||||
local curr = math.floor((inf + sup) / 2)
|
|
||||||
if system.path_compare(filename, type, files[curr].filename, files[curr].type) then
|
|
||||||
sup = curr - 1
|
|
||||||
else
|
|
||||||
inf = curr
|
|
||||||
end
|
|
||||||
end
|
|
||||||
repeat
|
|
||||||
if files[inf].filename == filename then
|
|
||||||
return inf, true
|
|
||||||
end
|
|
||||||
inf = inf + 1
|
|
||||||
until inf > sup or system.path_compare(filename, type, files[inf].filename, files[inf].type)
|
|
||||||
return inf, false
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local function project_scan_remove_file(watch_id, filepath)
|
local function project_scan_remove_file(watch_id, filepath)
|
||||||
local project_dir_entry
|
local project_dir_entry
|
||||||
for i = 1, #core.project_directories do
|
for i = 1, #core.project_directories do
|
||||||
|
@ -340,14 +349,16 @@ local function project_scan_add_file(watch_id, filepath)
|
||||||
project_dir_entry = core.project_directories[i]
|
project_dir_entry = core.project_directories[i]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not project_dir_entry or common.match_pattern(filepath, config.ignore_files) then return end
|
if not project_dir_entry then return end
|
||||||
|
for fragment in string.gmatch(filepath, "([^/\\]+)") do
|
||||||
|
if common.match_pattern(fragment, config.ignore_files) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
local size_limit = config.file_size_limit * 10e5
|
local size_limit = config.file_size_limit * 10e5
|
||||||
local fileinfo = get_project_file_info(project_dir_entry.name, PATHSEP .. filepath, size_limit)
|
local fileinfo = get_project_file_info(project_dir_entry.name, PATHSEP .. filepath, size_limit)
|
||||||
local index, match = file_search(project_dir_entry.files, fileinfo)
|
if fileinfo then
|
||||||
if not match then
|
project_scan_add_entry(project_dir_entry, fileinfo)
|
||||||
table.insert(project_dir_entry.files, index, fileinfo)
|
|
||||||
project_dir_entry.is_dirty = true
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -101,9 +101,9 @@ end
|
||||||
|
|
||||||
|
|
||||||
function TreeView:check_cache()
|
function TreeView:check_cache()
|
||||||
-- invalidate cache's skip values if project_files has changed
|
|
||||||
for i = 1, #core.project_directories do
|
for i = 1, #core.project_directories do
|
||||||
local dir = core.project_directories[i]
|
local dir = core.project_directories[i]
|
||||||
|
-- invalidate cache's skip values if directory is declared dirty
|
||||||
if dir.is_dirty and self.cache[dir.name] then
|
if dir.is_dirty and self.cache[dir.name] then
|
||||||
self:invalidate_cache(dir.name)
|
self:invalidate_cache(dir.name)
|
||||||
end
|
end
|
||||||
|
@ -216,9 +216,7 @@ function TreeView:on_mouse_pressed(button, x, y, clicks)
|
||||||
else
|
else
|
||||||
if hovered_item.dir.files_limit and not hovered_item.expanded then
|
if hovered_item.dir.files_limit and not hovered_item.expanded then
|
||||||
local dirname = hovered_item.dir.name
|
local dirname = hovered_item.dir.name
|
||||||
if core.scan_project_subdir(dirname, hovered_item.filename) then
|
core.scan_project_subdir(dirname, hovered_item.filename)
|
||||||
self:invalidate_cache(dirname)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
hovered_item.expanded = not hovered_item.expanded
|
hovered_item.expanded = not hovered_item.expanded
|
||||||
end
|
end
|
||||||
|
|
|
@ -689,7 +689,21 @@ static int f_path_compare(lua_State *L) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* If types are the same compare the files' path alphabetically. */
|
/* If types are the same compare the files' path alphabetically. */
|
||||||
lua_pushboolean(L, strcmp(path1 + i, path2 + i) < 0);
|
int cfr = 0;
|
||||||
|
int len_min = (len1 < len2 ? len1 : len2);
|
||||||
|
for (int j = i; j <= len_min; j++) {
|
||||||
|
if (path1[j] == path2[j]) continue;
|
||||||
|
if (path1[j] == 0 || path2[j] == 0) {
|
||||||
|
cfr = (path1[j] == 0);
|
||||||
|
} else if (path1[j] == PATHSEP || path2[j] == PATHSEP) {
|
||||||
|
/* For comparison we treat PATHSEP as if it was the string terminator. */
|
||||||
|
cfr = (path1[j] == PATHSEP);
|
||||||
|
} else {
|
||||||
|
cfr = (path1[j] < path2[j]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lua_pushboolean(L, cfr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue