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 opts NavigationMenuOptions
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 {}
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 path_separator = path_separator(directory.path)
for _, dir in ipairs(directories) do
local serialized = serialize_path(utils.join_path(directory.path, dir))
if serialized then
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
@@ -214,7 +215,7 @@ function open_file_navigation_menu(directory_path, handle_select, opts)
end
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,
}

View File

@@ -22,7 +22,7 @@ end
---@param char string
---@return string
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
if str:byte(i) ~= char then
end_i = i

View File

@@ -145,33 +145,90 @@ function opacity_to_alpha(opacity)
return 255 - math.ceil(255 * opacity)
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
---@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)
if not path or is_protocol(path) then return path end
-- Ensure path is absolute
if not (path:match(state.os == 'windows' and '^%a+:' or '^/') or path:match('^\\\\')) then
path = utils.join_path(state.cwd, path)
end
path = ensure_absolute(path)
local is_unc = path:sub(1, 2) == '\\\\'
if state.os == 'windows' or is_unc then path = path:gsub('/', '\\') end
path = trim_trailing_separator(path)
-- Use proper slashes
if state.os == 'windows' then
path = trim_end(path, '\\')
-- Drive letters on windows need trailing backslash
if path:sub(#path) == ':' then
path = path .. '\\'
end
return path
else
return trim_end(path, '/')
end
--Deduplication of path separators
if is_unc then path = path:gsub('(.\\)\\+', '%1')
elseif state.os == 'windows' then path = path:gsub('\\\\+', '\\')
else path = path:gsub('//+', '/') end
return path
end
-- Check if path is a protocol, such as `http://...`.
---@param path string
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
---@param path string
@@ -197,9 +254,9 @@ end
function serialize_path(path)
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)
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, '.')
return {