Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix dirmonitor sorting issues #1599

Merged
merged 3 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions data/core/common.lua
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ function common.path_suggest(text, root)
if root and root:sub(-1) ~= PATHSEP then
root = root .. PATHSEP
end
local path, name = text:match("^(.-)([^/\\]*)$")
local path, name = text:match("^(.-)([^"..PATHSEP.."]*)$")
local clean_dotslash = false
-- ignore root if path is absolute
local is_absolute = common.is_absolute_path(text)
Expand Down Expand Up @@ -279,7 +279,7 @@ end
---@param text string The input path.
---@return string[]
function common.dir_path_suggest(text)
local path, name = text:match("^(.-)([^/\\]*)$")
local path, name = text:match("^(.-)([^"..PATHSEP.."]*)$")
local files = system.list_dir(path == "" and "." or path) or {}
local res = {}
for _, file in ipairs(files) do
Expand All @@ -298,7 +298,7 @@ end
---@param dir_list string[] A list of paths to filter.
---@return string[]
function common.dir_list_suggest(text, dir_list)
local path, name = text:match("^(.-)([^/\\]*)$")
local path, name = text:match("^(.-)([^"..PATHSEP.."]*)$")
local res = {}
for _, dir_path in ipairs(dir_list) do
if dir_path:lower():find(text:lower(), nil, true) == 1 then
Expand Down Expand Up @@ -452,7 +452,7 @@ end
function common.basename(path)
-- a path should never end by / or \ except if it is '/' (unix root) or
-- 'X:\' (windows drive)
return path:match("[^\\/]+$") or path
return path:match("[^"..PATHSEP.."]+$") or path
end


Expand All @@ -461,7 +461,7 @@ end
---@param path string
---@return string|nil
function common.dirname(path)
return path:match("(.+)[\\/][^\\/]+$")
return path:match("(.+)["..PATHSEP.."][^"..PATHSEP.."]+$")
end


Expand Down Expand Up @@ -504,10 +504,10 @@ end

local function split_on_slash(s, sep_pattern)
local t = {}
if s:match("^[/\\]") then
if s:match("^["..PATHSEP.."]") then
t[#t + 1] = ""
end
for fragment in string.gmatch(s, "([^/\\]+)") do
for fragment in string.gmatch(s, "([^"..PATHSEP.."]+)") do
t[#t + 1] = fragment
end
return t
Expand Down Expand Up @@ -640,7 +640,7 @@ function common.mkdirp(path)
while path and path ~= "" do
local success_mkdir = system.mkdir(path)
if success_mkdir then break end
local updir, basedir = path:match("(.*)[/\\](.+)$")
local updir, basedir = path:match("(.*)["..PATHSEP.."](.+)$")
table.insert(subdirs, 1, basedir or path)
path = updir
end
Expand Down
48 changes: 23 additions & 25 deletions data/core/dirwatch.lua
Original file line number Diff line number Diff line change
Expand Up @@ -186,49 +186,47 @@ end
-- "root" will by an absolute path without trailing '/'
-- "path" will be a path starting without '/' and without trailing '/'
-- or the empty string.
-- It will identifies a sub-path within "root.
-- It identifies a sub-path within "root".
-- The current path location will therefore always be: root .. path.
-- When recursing "root" will always be the same, only "path" will change.
-- When recursing, "root" will always be the same, only "path" will change.
-- Returns a list of file "items". In each item the "filename" will be the
-- complete file path relative to "root" *without* the trailing '/', and without the starting '/'.
function dirwatch.get_directory_files(dir, root, path, t, entries_count, recurse_pred)
function dirwatch.get_directory_files(dir, root, path, entries_count, recurse_pred)
local t = {}
local t0 = system.get_time()
local t_elapsed = system.get_time() - t0
local dirs, files = {}, {}
local ignore_compiled = compile_ignore_files()


local all = system.list_dir(root .. PATHSEP .. path)
if not all then return nil end

for _, file in ipairs(all or {}) do
local entries = { }
for _, file in ipairs(all) do
local info = get_project_file_info(root, (path ~= "" and (path .. PATHSEP) or "") .. file, ignore_compiled)
if info then
table.insert(info.type == "dir" and dirs or files, info)
entries_count = entries_count + 1
table.insert(entries, info)
end
end
table.sort(entries, compare_file)

local recurse_complete = true
table.sort(dirs, compare_file)
for _, f in ipairs(dirs) do
table.insert(t, f)
if recurse_pred(dir, f.filename, entries_count, t_elapsed) then
local _, complete, n = dirwatch.get_directory_files(dir, root, f.filename, t, entries_count, recurse_pred)
recurse_complete = recurse_complete and complete
if n ~= nil then
entries_count = n
for _, info in ipairs(entries) do
table.insert(t, info)
entries_count = entries_count + 1
if info.type == "dir" then
if recurse_pred(dir, info.filename, entries_count, system.get_time() - t0) then
local t_rec, complete, n = dirwatch.get_directory_files(dir, root, info.filename, entries_count, recurse_pred)
recurse_complete = recurse_complete and complete
if n ~= nil then
entries_count = n
for _, info_rec in ipairs(t_rec) do
table.insert(t, info_rec)
end
end
else
recurse_complete = false
end
else
recurse_complete = false
end
end

table.sort(files, compare_file)
for _, f in ipairs(files) do
table.insert(t, f)
end

return t, recurse_complete, entries_count
end

Expand Down
10 changes: 4 additions & 6 deletions data/core/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ local function strip_leading_path(filename)
end

local function strip_trailing_slash(filename)
if filename:match("[^:][/\\]$") then
if filename:match("[^:]["..PATHSEP.."]$") then
return filename:sub(1, -2)
end
return filename
Expand All @@ -120,9 +120,7 @@ local function show_max_files_warning(dir)
"Too many files in project directory: stopped reading at "..
config.max_project_files.." files. For more information see "..
"usage.md at https://github.com/lite-xl/lite-xl."
if core.status_view then
core.status_view:show_message("!", style.accent, message)
end
core.warn(message)
end


Expand Down Expand Up @@ -184,7 +182,7 @@ local function refresh_directory(topdir, target)
directory_start_idx = directory_start_idx + 1
end

local files = dirwatch.get_directory_files(topdir, topdir.name, (target or ""), {}, 0, function() return false end)
local files = dirwatch.get_directory_files(topdir, topdir.name, (target or ""), 0, function() return false end)
local change = false

-- If this file doesn't exist, we should be calling this on our parent directory, assume we'll do that.
Expand Down Expand Up @@ -265,7 +263,7 @@ function core.add_project_directory(path)

local fstype = PLATFORM == "Linux" and system.get_fs_type(topdir.name) or "unknown"
topdir.force_scans = (fstype == "nfs" or fstype == "fuse")
local t, complete, entries_count = dirwatch.get_directory_files(topdir, topdir.name, "", {}, 0, timed_max_files_pred)
local t, complete, entries_count = dirwatch.get_directory_files(topdir, topdir.name, "", 0, timed_max_files_pred)
topdir.files = t
if not complete then
topdir.slow_filesystem = not complete and (entries_count <= config.max_project_files)
Expand Down
2 changes: 1 addition & 1 deletion data/plugins/treeview.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ local tooltip_alpha_rate = 1

local function get_depth(filename)
local n = 1
for sep in filename:gmatch("[\\/]") do
for _ in filename:gmatch(PATHSEP) do
n = n + 1
end
return n
Expand Down
3 changes: 1 addition & 2 deletions src/api/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,7 @@ static int f_load_native_plugin(lua_State *L) {
#endif

/* Special purpose filepath compare function. Corresponds to the
order used in the TreeView view of the project's files. Returns true iff
order used in the TreeView view of the project's files. Returns true if
path1 < path2 in the TreeView order. */
static int f_path_compare(lua_State *L) {
size_t len1, len2;
Expand All @@ -1070,7 +1070,6 @@ static int f_path_compare(lua_State *L) {
size_t offset = 0, i, j;
for (i = 0; i < len1 && i < len2; i++) {
if (path1[i] != path2[i]) break;
if (isdigit(path1[i])) break;
if (path1[i] == PATHSEP) {
offset = i + 1;
}
Expand Down