Rebase and use Path.os() introduced in https://github.com/sxyazi/yazi/pull/3541

This commit is contained in:
sxyazi 2026-01-09 19:59:37 +08:00
parent 1d0c9a0281
commit 646b008cdd
No known key found for this signature in database

View file

@ -14,10 +14,10 @@ function M:peek(job)
elseif job.skip > 0 and bound < job.skip + limit then elseif job.skip > 0 and bound < job.skip + limit then
return ya.emit("peek", { math.max(0, bound - limit), only_if = job.file.url, upper_bound = true }) return ya.emit("peek", { math.max(0, bound - limit), only_if = job.file.url, upper_bound = true })
elseif #files == 0 then elseif #files == 0 then
files = { { path = job.file.url.stem, size = 0, packed_size = 0, attr = "" } } files = { { path = Path.os(job.file.url.stem), size = 0, packed_size = 0, attr = "" } }
end end
M.prepare_tree(files) files = M.prepare_tree(files)
local left, right = {}, {} local left, right = {}, {}
for _, f in ipairs(files) do for _, f in ipairs(files) do
@ -158,7 +158,8 @@ function M.list_if_only_one(path)
if event == 0 then if event == 0 then
local attr, size, packed_size, path = next:sub(20):match("([^ ]+) +(%d+) +(%d+) +([^\r\n]+)") local attr, size, packed_size, path = next:sub(20):match("([^ ]+) +(%d+) +(%d+) +([^\r\n]+)")
if path then if path then
files[#files + 1] = { path = path, size = tonumber(size), packed_size = tonumber(packed_size), attr = attr } files[#files + 1] =
{ path = Path.os(path), size = tonumber(size), packed_size = tonumber(packed_size), attr = attr }
end end
elseif event ~= 1 then elseif event ~= 1 then
break break
@ -217,7 +218,7 @@ function M.is_encrypted(s) return s:find(" Wrong password", 1, true) end
function M.is_tar(path) return M.list_meta { "-p", tostring(path) } == "tar" end function M.is_tar(path) return M.list_meta { "-p", tostring(path) } == "tar" end
function M.should_decompress_tar(file) function M.should_decompress_tar(file)
return file.packed_size <= 1024 * 1024 * 1024 and file.path:lower():find(".+%.tar$") ~= nil return file.packed_size <= 1024 * 1024 * 1024 and (file.path.ext or ""):lower() == "tar"
end end
-- Parse the output of a "7z l -slt" command. -- Parse the output of a "7z l -slt" command.
@ -229,7 +230,7 @@ end
---@return integer bound ---@return integer bound
---@return Error? err ---@return Error? err
function M.parse_7z_slt(child, skip, limit) function M.parse_7z_slt(child, skip, limit)
local i, files, err = 0, { { path = "", size = 0, packed_size = 0, attr = "" } }, nil local i, files, err = 0, { { path = Path.os(""), size = 0, packed_size = 0, attr = "" } }, nil
local key, value, stderr = "", "", {} local key, value, stderr = "", "", {}
repeat repeat
local next, event = child:read_line() local next, event = child:read_line()
@ -245,8 +246,8 @@ function M.parse_7z_slt(child, skip, limit)
if next == "\n" or next == "\r\n" then if next == "\n" or next == "\r\n" then
i = i + 1 i = i + 1
if files[#files].path ~= "" then if files[#files].path ~= Path.os("") then
files[#files + 1] = { path = "", size = 0, packed_size = 0, attr = "" } files[#files + 1] = { path = Path.os(""), size = 0, packed_size = 0, attr = "" }
end end
goto continue goto continue
elseif i < skip then elseif i < skip then
@ -255,26 +256,21 @@ function M.parse_7z_slt(child, skip, limit)
key, value = next:match("^(%u[%a ]+) = (.-)[\r\n]+") key, value = next:match("^(%u[%a ]+) = (.-)[\r\n]+")
if key == "Path" then if key == "Path" then
files[#files].path = value files[#files].path = Path.os(value)
elseif key == "Size" then elseif key == "Size" then
files[#files].size = tonumber(value) or 0 files[#files].size = tonumber(value) or 0
elseif key == "Packed Size" then elseif key == "Packed Size" then
files[#files].packed_size = tonumber(value) or 0 files[#files].packed_size = tonumber(value) or 0
elseif key == "Attributes" then elseif key == "Attributes" then
files[#files].attr = value files[#files].attr = value
if value:sub(1, 1) == "D" then elseif key == "Folder" then
files[#files].is_dir = true files[#files].folder = value
end
elseif key == "Folder" and value == "+" then
-- Mark as directory if Folder = +
-- this is needed for some archive types, where Attributes may not have the D flag (ex: tarballs)
files[#files].is_dir = true
end end
::continue:: ::continue::
until i >= skip + limit until i >= skip + limit
if files[#files].path == "" then if files[#files].path == Path.os("") then
files[#files] = nil files[#files] = nil
end end
if #stderr ~= 0 then if #stderr ~= 0 then
@ -288,72 +284,62 @@ function M.prepare_tree(files)
return return
end end
local result = {} local parent = files[1].path.parent
local dir_stack, previous_path = {}, nil while parent do
-- Initialize dir_stack with the first file's
local first_file_url, components = Url(files[1].path).path, {}
while true do
first_file_url = first_file_url.parent
if first_file_url then
components[#components + 1] = first_file_url
else
break
end
end
for i, comp in ipairs(components) do
table.insert(files, 1, { table.insert(files, 1, {
path = tostring(comp), path = parent,
size = 0, size = 0,
attr = "", attr = "",
is_dir = true, is_dir = true,
display_name = comp.name, display_name = parent.name,
depth = #components - i,
}) })
parent = parent.parent
end end
local path, parent, dirs_to_add, dir_path = nil, nil, nil, nil local tree = {}
for _, f in ipairs(files) do local parents, prev_parent = {}, nil
path = Url(f.path).path for i, f in ipairs(files) do
if f.is_dir then
while #dir_stack > 0 and not path:starts_with(dir_stack[#dir_stack]) do f.depth = i - 1
dir_stack[#dir_stack] = nil else
f.is_dir = f.folder == "+" or (f.attr and f.attr:sub(1, 1) == "D")
end end
f.display_name = path.name while #parents > 0 and not f.path:starts_with(parents[#parents]) do
f.depth = #dir_stack parents[#parents] = nil
end
f.display_name = f.path.name
f.depth = #parents
if f.is_dir then if f.is_dir then
dir_stack[#dir_stack + 1] = path parents[#parents + 1] = f.path
elseif not previous_path or (path.parent ~= previous_path.parent) then elseif prev_parent ~= f.path.parent then
parent = path.parent local parent = f.path.parent
dirs_to_add = {} local dirs_to_add = {}
while parent and (not dir_stack[#dir_stack] or parent ~= dir_stack[#dir_stack]) do while parent and parent ~= parents[#parents] do
dirs_to_add[#dirs_to_add + 1] = parent dirs_to_add[#dirs_to_add + 1] = parent
parent = parent.parent parent = parent.parent
end end
for j = #dirs_to_add, 1, -1 do for j = #dirs_to_add, 1, -1 do
dir_path = dirs_to_add[j] tree[#tree + 1] = {
result[#result + 1] = { path = dirs_to_add[j],
path = tostring(dir_path),
size = 0, size = 0,
attr = "", attr = "",
is_dir = true, is_dir = true,
display_name = dir_path.name, display_name = dirs_to_add[j].name,
depth = #dir_stack, depth = #parents,
} }
dir_stack[#dir_stack + 1] = dir_path parents[#parents + 1] = dirs_to_add[j]
end end
f.depth = #dir_stack f.depth = #parents
end end
result[#result + 1] = f tree[#tree + 1] = f
previous_path = path prev_parent = f.path.parent
end end
for i = #result, 1, -1 do return tree
files[i] = result[i]
end
end end
return M return M