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
|
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
|
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
|
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=~/
|
default_directory=~/
|
||||||
# List hidden files when reading directories. Due to environment limitations, this currently only hides
|
# 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).
|
# 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 handle_activate fun(event: MenuEventActivate)
|
||||||
---@param opts NavigationMenuOptions
|
---@param opts NavigationMenuOptions
|
||||||
function open_file_navigation_menu(directory_path, handle_activate, opts)
|
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 {}
|
opts = opts or {}
|
||||||
local current_directory = serialize_path(normalize_path(directory_path))
|
---@type string|nil
|
||||||
|
local current_directory = nil
|
||||||
---@type Menu
|
---@type Menu
|
||||||
local menu
|
local menu
|
||||||
---@type string | nil
|
---@type string | nil
|
||||||
local back_path
|
local back_path
|
||||||
|
local separator = path_separator(directory_path)
|
||||||
if not current_directory then
|
|
||||||
msg.error('Couldn\'t serialize path "' .. directory_path .. '.')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local separator = path_separator(current_directory.path)
|
|
||||||
|
|
||||||
---@param path string Can be path to a directory, or special string `'{drives}'` to get windows drives items.
|
---@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.
|
---@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)
|
local function serialize_items(path, selected_path)
|
||||||
if path == '{drives}' then
|
if path == '{drives}' then
|
||||||
local process = mp.command_native({
|
local process = mp.command_native({
|
||||||
@@ -303,22 +307,23 @@ function open_file_navigation_menu(directory_path, handle_activate, opts)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
msg.error(process.stderr)
|
return {}, 1, 'Couldn\'t open drives. Error: ' .. utils.to_string(process.stderr)
|
||||||
end
|
end
|
||||||
|
|
||||||
return items, selected_index
|
return items, selected_index
|
||||||
end
|
end
|
||||||
|
|
||||||
current_directory = serialize_path(path)
|
local serialized = serialize_path(path)
|
||||||
if not current_directory then
|
if not serialized then
|
||||||
msg.error('Couldn\'t serialize path "' .. path .. '.')
|
return {}, 0, 'Couldn\'t serialize path "' .. path .. '.'
|
||||||
return {}, 0
|
|
||||||
end
|
end
|
||||||
local files, directories = read_directory(current_directory.path, {
|
local files, directories, error = read_directory(serialized.path, {
|
||||||
types = opts.allowed_types,
|
types = opts.allowed_types,
|
||||||
hidden = options.show_hidden_files,
|
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
|
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 is_root then
|
||||||
if state.platform == 'windows' 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
|
end
|
||||||
else
|
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
|
end
|
||||||
|
|
||||||
back_path = items[#items] and items[#items].value
|
back_path = items[#items] and items[#items].value
|
||||||
@@ -349,29 +354,46 @@ function open_file_navigation_menu(directory_path, handle_activate, opts)
|
|||||||
end
|
end
|
||||||
|
|
||||||
for index, item in ipairs(items) do
|
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
|
||||||
item.active = true
|
if opts.active_path == item.value then
|
||||||
if not selected_path then selected_index = index end
|
item.active = true
|
||||||
end
|
if not selected_path then selected_index = index end
|
||||||
|
end
|
||||||
|
|
||||||
if selected_path == item.value then selected_index = index end
|
if selected_path == item.value then selected_index = index end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return items, selected_index
|
return items, selected_index
|
||||||
end
|
end
|
||||||
|
|
||||||
local items, selected_index = serialize_items(current_directory.path)
|
|
||||||
local menu_data = {
|
local menu_data = {
|
||||||
type = opts.type,
|
type = opts.type,
|
||||||
title = opts.title or current_directory.basename .. separator,
|
title = opts.title or '',
|
||||||
items = items,
|
items = {},
|
||||||
on_close = opts.on_close and 'callback' or nil,
|
on_close = opts.on_close and 'callback' or nil,
|
||||||
selected_index = selected_index,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
---@param path string
|
||||||
local function open_directory(path)
|
local function open_directory(path)
|
||||||
local items, selected_index = serialize_items(path, current_directory.path)
|
local items, selected_index, error = serialize_items(path, current_directory)
|
||||||
menu_data.title = opts.title or current_directory.basename .. separator
|
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_data.items = items
|
||||||
menu:search_cancel()
|
menu:search_cancel()
|
||||||
menu:update(menu_data)
|
menu:update(menu_data)
|
||||||
@@ -418,6 +440,8 @@ function open_file_navigation_menu(directory_path, handle_activate, opts)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
open_directory(directory_path)
|
||||||
|
|
||||||
return menu
|
return menu
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -650,11 +674,8 @@ function open_open_file_menu()
|
|||||||
local active_file
|
local active_file
|
||||||
|
|
||||||
if state.path == nil or is_protocol(state.path) then
|
if state.path == nil or is_protocol(state.path) then
|
||||||
local serialized = serialize_path(get_default_directory())
|
directory = options.default_directory
|
||||||
if serialized then
|
active_file = nil
|
||||||
directory = serialized.path
|
|
||||||
active_file = nil
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
local serialized = serialize_path(state.path)
|
local serialized = serialize_path(state.path)
|
||||||
if serialized then
|
if serialized then
|
||||||
@@ -723,7 +744,7 @@ function create_track_loader_menu_opener(opts)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not path then
|
if not path then
|
||||||
path = get_default_directory()
|
path = options.default_directory
|
||||||
end
|
end
|
||||||
|
|
||||||
local function handle_activate(event)
|
local function handle_activate(event)
|
||||||
|
@@ -436,11 +436,6 @@ function execute_command(command)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
---@return string
|
|
||||||
function get_default_directory()
|
|
||||||
return mp.command_native({'expand-path', options.default_directory})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Serializes path into its semantic parts.
|
-- Serializes path into its semantic parts.
|
||||||
---@param path string
|
---@param path string
|
||||||
---@return nil|{path: string; is_root: boolean; dirname?: string; basename: string; filename: string; extension?: 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.
|
-- Reads items in directory and splits it into directories and files tables.
|
||||||
---@param path string
|
---@param path string
|
||||||
---@param opts? {types?: string[], hidden?: boolean}
|
---@param opts? {types?: string[], hidden?: boolean}
|
||||||
---@return string[]|nil files
|
---@return string[] files
|
||||||
---@return string[]|nil directories
|
---@return string[] directories
|
||||||
|
---@return string|nil error
|
||||||
function read_directory(path, opts)
|
function read_directory(path, opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
local items, error = utils.readdir(path, 'all')
|
local items, error = utils.readdir(path, 'all')
|
||||||
|
local files, directories = {}, {}
|
||||||
|
|
||||||
if not items then
|
if not items then
|
||||||
msg.error('Reading files from "' .. path .. '" failed: ' .. error)
|
return files, directories, 'Reading directory "' .. path .. '" failed. Error: ' .. utils.to_string(error)
|
||||||
return nil, nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local files, directories = {}, {}
|
|
||||||
|
|
||||||
for _, item in ipairs(items) do
|
for _, item in ipairs(items) do
|
||||||
if item ~= '.' and item ~= '..' and (opts.hidden or item:sub(1, 1) ~= '.') then
|
if item ~= '.' and item ~= '..' and (opts.hidden or item:sub(1, 1) ~= '.') then
|
||||||
local info = utils.file_info(join_path(path, item))
|
local info = utils.file_info(join_path(path, item))
|
||||||
@@ -505,8 +499,8 @@ function get_adjacent_files(file_path, opts)
|
|||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
local current_meta = serialize_path(file_path)
|
local current_meta = serialize_path(file_path)
|
||||||
if not current_meta then return end
|
if not current_meta then return end
|
||||||
local files = read_directory(current_meta.dirname, {hidden = opts.hidden})
|
local files, _dirs, error = read_directory(current_meta.dirname, {hidden = opts.hidden})
|
||||||
if not files then return end
|
if error then msg.error(error) return end
|
||||||
sort_strings(files)
|
sort_strings(files)
|
||||||
local current_file_index
|
local current_file_index
|
||||||
local paths = {}
|
local paths = {}
|
||||||
|
@@ -554,12 +554,16 @@ function load_file_index_in_current_directory(index)
|
|||||||
|
|
||||||
local serialized = serialize_path(state.path)
|
local serialized = serialize_path(state.path)
|
||||||
if serialized and serialized.dirname then
|
if serialized and serialized.dirname then
|
||||||
local files = read_directory(serialized.dirname, {
|
local files, _dirs, error = read_directory(serialized.dirname, {
|
||||||
types = config.types.autoload,
|
types = config.types.autoload,
|
||||||
hidden = options.show_hidden_files,
|
hidden = options.show_hidden_files,
|
||||||
})
|
})
|
||||||
|
|
||||||
if not files then return end
|
if error then
|
||||||
|
msg.error(error)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
sort_strings(files)
|
sort_strings(files)
|
||||||
if index < 0 then index = #files + index + 1 end
|
if index < 0 then index = #files + index + 1 end
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user