feat: default_directory
option now supports {drives}
on windows
On unix, this will switch to `/`. closes #953
This commit is contained in:
@@ -194,7 +194,7 @@ audio_types=aac,ac3,aiff,ape,au,cue,dsf,dts,flac,m4a,mid,midi,mka,mp3,mp4a,oga,o
|
||||
image_types=apng,avif,bmp,gif,j2k,jp2,jfif,jpeg,jpg,jxl,mj2,png,svg,tga,tif,tiff,webp
|
||||
subtitle_types=aqt,ass,gsub,idx,jss,lrc,mks,pgs,pjs,psb,rt,sbv,slt,smi,sub,sup,srt,ssa,ssf,ttxt,txt,usf,vt,vtt
|
||||
playlist_types=m3u,m3u8,pls,url,cue
|
||||
# Default open-file menu directory
|
||||
# Default open-file menu directory. Use `{drives}` to open drives menu on windows (defaults to `/` on unix).
|
||||
default_directory=~/
|
||||
# List hidden files when reading directories. Due to environment limitations, this currently only hides
|
||||
# files starting with a dot. Doesn't hide hidden files on windows (we have no way to tell they're hidden).
|
||||
|
@@ -265,22 +265,26 @@ end
|
||||
---@param handle_activate fun(event: MenuEventActivate)
|
||||
---@param opts NavigationMenuOptions
|
||||
function open_file_navigation_menu(directory_path, handle_activate, opts)
|
||||
if directory_path == '{drives}' then
|
||||
if state.platform ~= 'windows' then directory_path = '/' end
|
||||
else
|
||||
directory_path = normalize_path(mp.command_native({'expand-path', directory_path}))
|
||||
end
|
||||
|
||||
opts = opts or {}
|
||||
local current_directory = serialize_path(normalize_path(directory_path))
|
||||
---@type string|nil
|
||||
local current_directory = nil
|
||||
---@type Menu
|
||||
local menu
|
||||
---@type string | nil
|
||||
local back_path
|
||||
|
||||
if not current_directory then
|
||||
msg.error('Couldn\'t serialize path "' .. directory_path .. '.')
|
||||
return
|
||||
end
|
||||
local separator = path_separator(current_directory.path)
|
||||
local separator = path_separator(directory_path)
|
||||
|
||||
---@param path string Can be path to a directory, or special string `'{drives}'` to get windows drives items.
|
||||
---@param selected_path? string Marks item with this path as active.
|
||||
---@return MenuStackValue, number
|
||||
---@return MenuStackValue[] menu_items
|
||||
---@return number selected_index
|
||||
---@return string|nil error
|
||||
local function serialize_items(path, selected_path)
|
||||
if path == '{drives}' then
|
||||
local process = mp.command_native({
|
||||
@@ -303,22 +307,23 @@ function open_file_navigation_menu(directory_path, handle_activate, opts)
|
||||
end
|
||||
end
|
||||
else
|
||||
msg.error(process.stderr)
|
||||
return {}, 1, 'Couldn\'t open drives. Error: ' .. utils.to_string(process.stderr)
|
||||
end
|
||||
|
||||
return items, selected_index
|
||||
end
|
||||
|
||||
current_directory = serialize_path(path)
|
||||
if not current_directory then
|
||||
msg.error('Couldn\'t serialize path "' .. path .. '.')
|
||||
return {}, 0
|
||||
local serialized = serialize_path(path)
|
||||
if not serialized then
|
||||
return {}, 0, 'Couldn\'t serialize path "' .. path .. '.'
|
||||
end
|
||||
local files, directories = read_directory(current_directory.path, {
|
||||
local files, directories, error = read_directory(serialized.path, {
|
||||
types = opts.allowed_types,
|
||||
hidden = options.show_hidden_files,
|
||||
})
|
||||
local is_root = not current_directory.dirname
|
||||
if error then
|
||||
return {}, 1, error
|
||||
end
|
||||
local is_root = not serialized.dirname
|
||||
|
||||
if not files or not directories then return {}, 0 end
|
||||
|
||||
@@ -331,10 +336,10 @@ function open_file_navigation_menu(directory_path, handle_activate, opts)
|
||||
|
||||
if is_root then
|
||||
if state.platform == 'windows' then
|
||||
items[#items + 1] = {title = '..', hint = t('Drives'), value = '{drives}', separator = true}
|
||||
items[#items + 1] = {title = '..', hint = t('Drives'), value = '{drives}', separator = true, is_to_parent = true}
|
||||
end
|
||||
else
|
||||
items[#items + 1] = {title = '..', hint = t('parent dir'), value = current_directory.dirname, separator = true}
|
||||
items[#items + 1] = {title = '..', hint = t('parent dir'), value = serialized.dirname, separator = true, is_to_parent = true}
|
||||
end
|
||||
|
||||
back_path = items[#items] and items[#items].value
|
||||
@@ -349,29 +354,46 @@ function open_file_navigation_menu(directory_path, handle_activate, opts)
|
||||
end
|
||||
|
||||
for index, item in ipairs(items) do
|
||||
if not item.value.is_to_parent and opts.active_path == item.value then
|
||||
if not item.is_to_parent then
|
||||
if opts.active_path == item.value then
|
||||
item.active = true
|
||||
if not selected_path then selected_index = index end
|
||||
end
|
||||
|
||||
if selected_path == item.value then selected_index = index end
|
||||
end
|
||||
end
|
||||
|
||||
return items, selected_index
|
||||
end
|
||||
|
||||
local items, selected_index = serialize_items(current_directory.path)
|
||||
local menu_data = {
|
||||
type = opts.type,
|
||||
title = opts.title or current_directory.basename .. separator,
|
||||
items = items,
|
||||
title = opts.title or '',
|
||||
items = {},
|
||||
on_close = opts.on_close and 'callback' or nil,
|
||||
selected_index = selected_index,
|
||||
}
|
||||
|
||||
---@param path string
|
||||
local function open_directory(path)
|
||||
local items, selected_index = serialize_items(path, current_directory.path)
|
||||
menu_data.title = opts.title or current_directory.basename .. separator
|
||||
local items, selected_index, error = serialize_items(path, current_directory)
|
||||
if error then
|
||||
msg.error(error)
|
||||
items = {{title = 'Something went wrong. See console for errors.', selectable = false, muted = true}}
|
||||
end
|
||||
|
||||
local title = opts.title
|
||||
if not title then
|
||||
if path == '{drives}' then
|
||||
title = 'Drives'
|
||||
else
|
||||
local serialized = serialize_path(path)
|
||||
title = serialized and serialized.basename .. separator or '??'
|
||||
end
|
||||
end
|
||||
|
||||
current_directory = path
|
||||
menu_data.title = title
|
||||
menu_data.items = items
|
||||
menu:search_cancel()
|
||||
menu:update(menu_data)
|
||||
@@ -418,6 +440,8 @@ function open_file_navigation_menu(directory_path, handle_activate, opts)
|
||||
end
|
||||
end)
|
||||
|
||||
open_directory(directory_path)
|
||||
|
||||
return menu
|
||||
end
|
||||
|
||||
@@ -650,11 +674,8 @@ function open_open_file_menu()
|
||||
local active_file
|
||||
|
||||
if state.path == nil or is_protocol(state.path) then
|
||||
local serialized = serialize_path(get_default_directory())
|
||||
if serialized then
|
||||
directory = serialized.path
|
||||
directory = options.default_directory
|
||||
active_file = nil
|
||||
end
|
||||
else
|
||||
local serialized = serialize_path(state.path)
|
||||
if serialized then
|
||||
@@ -723,7 +744,7 @@ function create_track_loader_menu_opener(opts)
|
||||
end
|
||||
end
|
||||
if not path then
|
||||
path = get_default_directory()
|
||||
path = options.default_directory
|
||||
end
|
||||
|
||||
local function handle_activate(event)
|
||||
|
@@ -436,11 +436,6 @@ function execute_command(command)
|
||||
return false
|
||||
end
|
||||
|
||||
---@return string
|
||||
function get_default_directory()
|
||||
return mp.command_native({'expand-path', options.default_directory})
|
||||
end
|
||||
|
||||
-- Serializes path into its semantic parts.
|
||||
---@param path string
|
||||
---@return nil|{path: string; is_root: boolean; dirname?: string; basename: string; filename: string; extension?: string;}
|
||||
@@ -465,19 +460,18 @@ end
|
||||
-- Reads items in directory and splits it into directories and files tables.
|
||||
---@param path string
|
||||
---@param opts? {types?: string[], hidden?: boolean}
|
||||
---@return string[]|nil files
|
||||
---@return string[]|nil directories
|
||||
---@return string[] files
|
||||
---@return string[] directories
|
||||
---@return string|nil error
|
||||
function read_directory(path, opts)
|
||||
opts = opts or {}
|
||||
local items, error = utils.readdir(path, 'all')
|
||||
local files, directories = {}, {}
|
||||
|
||||
if not items then
|
||||
msg.error('Reading files from "' .. path .. '" failed: ' .. error)
|
||||
return nil, nil
|
||||
return files, directories, 'Reading directory "' .. path .. '" failed. Error: ' .. utils.to_string(error)
|
||||
end
|
||||
|
||||
local files, directories = {}, {}
|
||||
|
||||
for _, item in ipairs(items) do
|
||||
if item ~= '.' and item ~= '..' and (opts.hidden or item:sub(1, 1) ~= '.') then
|
||||
local info = utils.file_info(join_path(path, item))
|
||||
@@ -505,8 +499,8 @@ function get_adjacent_files(file_path, opts)
|
||||
opts = opts or {}
|
||||
local current_meta = serialize_path(file_path)
|
||||
if not current_meta then return end
|
||||
local files = read_directory(current_meta.dirname, {hidden = opts.hidden})
|
||||
if not files then return end
|
||||
local files, _dirs, error = read_directory(current_meta.dirname, {hidden = opts.hidden})
|
||||
if error then msg.error(error) return end
|
||||
sort_strings(files)
|
||||
local current_file_index
|
||||
local paths = {}
|
||||
|
@@ -554,12 +554,16 @@ function load_file_index_in_current_directory(index)
|
||||
|
||||
local serialized = serialize_path(state.path)
|
||||
if serialized and serialized.dirname then
|
||||
local files = read_directory(serialized.dirname, {
|
||||
local files, _dirs, error = read_directory(serialized.dirname, {
|
||||
types = config.types.autoload,
|
||||
hidden = options.show_hidden_files,
|
||||
})
|
||||
|
||||
if not files then return end
|
||||
if error then
|
||||
msg.error(error)
|
||||
return
|
||||
end
|
||||
|
||||
sort_strings(files)
|
||||
if index < 0 then index = #files + index + 1 end
|
||||
|
||||
|
Reference in New Issue
Block a user