fix: menu title when browsing files (#349)

This commit is contained in:
christoph-heinrich
2022-10-28 21:54:57 +02:00
committed by GitHub
parent 00d249a351
commit 59ac8af48f
3 changed files with 81 additions and 23 deletions

View File

@@ -149,7 +149,7 @@ end
---@param handle_select fun(path: string): nil ---@param handle_select fun(path: string): nil
---@param opts NavigationMenuOptions ---@param opts NavigationMenuOptions
function open_file_navigation_menu(directory_path, handle_select, opts) function open_file_navigation_menu(directory_path, handle_select, opts)
directory = serialize_path(directory_path) directory = serialize_path(normalize_path(directory_path))
opts = opts or {} opts = opts or {}
if not directory then if not directory then
@@ -184,11 +184,12 @@ function open_file_navigation_menu(directory_path, handle_select, opts)
local items_start_index = #items + 1 local items_start_index = #items + 1
local path_separator = path_separator(directory.path)
for _, dir in ipairs(directories) do for _, dir in ipairs(directories) do
local serialized = serialize_path(utils.join_path(directory.path, dir)) local serialized = serialize_path(utils.join_path(directory.path, dir))
if serialized then if serialized then
serialized.is_directory = true serialized.is_directory = true
items[#items + 1] = {title = serialized.basename, value = serialized, hint = '/'} items[#items + 1] = {title = serialized.basename, value = serialized, hint = path_separator}
end end
end end
@@ -214,7 +215,7 @@ function open_file_navigation_menu(directory_path, handle_select, opts)
end end
local menu_data = { local menu_data = {
type = opts.type, title = opts.title or directory.basename .. '/', items = items, type = opts.type, title = opts.title or directory.basename .. path_separator, items = items,
on_open = opts.on_open, on_close = opts.on_close, on_open = opts.on_open, on_close = opts.on_close,
} }

View File

@@ -22,7 +22,7 @@ end
---@param char string ---@param char string
---@return string ---@return string
function trim_end(str, char) function trim_end(str, char)
local char, end_i = char:byte(), nil local char, end_i = char:byte(), 0
for i = #str, 1, -1 do for i = #str, 1, -1 do
if str:byte(i) ~= char then if str:byte(i) ~= char then
end_i = i end_i = i

View File

@@ -145,33 +145,90 @@ function opacity_to_alpha(opacity)
return 255 - math.ceil(255 * opacity) return 255 - math.ceil(255 * opacity)
end end
-- Ensures path is absolute and remove trailing slashes/backslashes. do
local os_separator = state.os == 'windows' and '\\' or '/'
-- Get appropriate path separator for the given path.
---@param path string
---@return string
function path_separator(path)
return path:sub(1, 2) == '\\\\' and '\\' or os_separator
end
-- Joins paths with the OS aware path separator or UNC separator.
---@param p1 string
---@param p2 string
---@return string
function utils.join_path(p1, p2)
return p1 .. path_separator(p1) .. p2
end
end
-- Check if path is absolute.
---@param path string ---@param path string
---@return boolean
function is_absolute(path)
if path:sub(1, 2) == '\\\\' then return true
elseif state.os == 'windows' then return path:find('^%a+:') ~= nil
else return path:sub(1, 1) == '/' end
end
-- Ensure path is absolute.
---@param path string
---@return string
function ensure_absolute(path)
if is_absolute(path) then return path end
return utils.join_path(state.cwd, path)
end
-- Remove trailing slashes/backslashes.
---@param path string
---@return string
function trim_trailing_separator(path)
path = trim_end(path, path_separator(path))
if state.os == 'windows' then
-- Drive letters on windows need trailing backslash
if path:sub(#path) == ':' then return path .. '\\' end
return path
else
if path == '' then return '/' end
return path
end
end
-- Ensures path is absolute, remove trailing slashes/backslashes.
-- Lightweight version of normalize_path for performance critical parts.
---@param path string
---@return string
function normalize_path_lite(path)
if not path or is_protocol(path) then return path end
path = ensure_absolute(path)
return trim_trailing_separator(path)
end
-- Ensures path is absolute, remove trailing slashes/backslashes, normalization of path separators and deduplication.
---@param path string
---@return string
function normalize_path(path) function normalize_path(path)
if not path or is_protocol(path) then return path end if not path or is_protocol(path) then return path end
-- Ensure path is absolute path = ensure_absolute(path)
if not (path:match(state.os == 'windows' and '^%a+:' or '^/') or path:match('^\\\\')) then local is_unc = path:sub(1, 2) == '\\\\'
path = utils.join_path(state.cwd, path) if state.os == 'windows' or is_unc then path = path:gsub('/', '\\') end
end path = trim_trailing_separator(path)
-- Use proper slashes --Deduplication of path separators
if state.os == 'windows' then if is_unc then path = path:gsub('(.\\)\\+', '%1')
path = trim_end(path, '\\') elseif state.os == 'windows' then path = path:gsub('\\\\+', '\\')
-- Drive letters on windows need trailing backslash else path = path:gsub('//+', '/') end
if path:sub(#path) == ':' then
path = path .. '\\' return path
end
return path
else
return trim_end(path, '/')
end
end end
-- Check if path is a protocol, such as `http://...`. -- Check if path is a protocol, such as `http://...`.
---@param path string ---@param path string
function is_protocol(path) function is_protocol(path)
return type(path) == 'string' and (path:match('^%a[%a%d-_]+://') ~= nil or path:match('^%a[%a%d-_]+:\\?') ~= nil) return type(path) == 'string' and (path:find('^%a[%a%d-_]+://') ~= nil or path:find('^%a[%a%d-_]+:\\?') ~= nil)
end end
---@param path string ---@param path string
@@ -197,9 +254,9 @@ end
function serialize_path(path) function serialize_path(path)
if not path or is_protocol(path) then return end if not path or is_protocol(path) then return end
local normal_path = normalize_path(path) local normal_path = normalize_path_lite(path)
local dirname, basename = utils.split_path(normal_path) local dirname, basename = utils.split_path(normal_path)
if basename == '' then dirname = nil end if basename == '' then basename, dirname = dirname:sub(1, #dirname - 1), nil end
local dot_i = string_last_index_of(basename, '.') local dot_i = string_last_index_of(basename, '.')
return { return {