init
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
local mp = require 'mp'
|
||||
local msg = require 'mp.msg'
|
||||
local utils = require 'mp.utils'
|
||||
|
||||
local o = require 'modules.options'
|
||||
local g = require 'modules.globals'
|
||||
local fb_utils = require 'modules.utils'
|
||||
local ass = require 'modules.ass'
|
||||
local directory_movement = require 'modules.navigation.directory-movement'
|
||||
local scanning = require 'modules.navigation.scanning'
|
||||
local controls = require 'modules.controls'
|
||||
|
||||
---@class FbAPI: fb_utils
|
||||
local fb = setmetatable({}, { __index = setmetatable({}, { __index = fb_utils }) })
|
||||
package.loaded["file-browser"] = setmetatable({}, { __index = fb })
|
||||
|
||||
--these functions we'll provide as-is
|
||||
fb.redraw = ass.update_ass
|
||||
fb.browse_directory = controls.browse_directory
|
||||
|
||||
---Clears the directory cache.
|
||||
---@return thread
|
||||
function fb.rescan()
|
||||
return scanning.rescan()
|
||||
end
|
||||
|
||||
---@async
|
||||
---@return thread
|
||||
function fb.rescan_await()
|
||||
local co = scanning.rescan(nil, fb_utils.coroutine.callback())
|
||||
coroutine.yield()
|
||||
return co
|
||||
end
|
||||
|
||||
---@param directories? string[]
|
||||
function fb.clear_cache(directories)
|
||||
if directories then
|
||||
mp.commandv('script-message-to', mp.get_script_name(), 'cache/clear', utils.format_json(directories))
|
||||
else
|
||||
mp.commandv('script-message-to', mp.get_script_name(), 'cache/clear')
|
||||
end
|
||||
end
|
||||
|
||||
---A wrapper around scan_directory for addon API.
|
||||
---@async
|
||||
---@param directory string
|
||||
---@param parse_state ParseStateTemplate
|
||||
---@return Item[]|nil
|
||||
---@return Opts
|
||||
function fb.parse_directory(directory, parse_state)
|
||||
if not parse_state then parse_state = { source = "addon" }
|
||||
elseif not parse_state.source then parse_state.source = "addon" end
|
||||
return scanning.scan_directory(directory, parse_state)
|
||||
end
|
||||
|
||||
---Register file extensions which can be opened by the browser.
|
||||
---@param ext string
|
||||
function fb.register_parseable_extension(ext)
|
||||
g.parseable_extensions[string.lower(ext)] = true
|
||||
end
|
||||
|
||||
---Deregister file extensions which can be opened by the browser.
|
||||
---@param ext string
|
||||
function fb.remove_parseable_extension(ext)
|
||||
g.parseable_extensions[string.lower(ext)] = nil
|
||||
end
|
||||
|
||||
---Add a compatible extension to show through the filter, only applies if run during the setup() method.
|
||||
---@param ext string
|
||||
function fb.add_default_extension(ext)
|
||||
table.insert(g.compatible_file_extensions, ext)
|
||||
end
|
||||
|
||||
---Add item to root at position pos.
|
||||
---@param item Item
|
||||
---@param pos? number
|
||||
function fb.insert_root_item(item, pos)
|
||||
msg.debug("adding item to root", item.label or item.name, pos)
|
||||
item.ass = item.ass or fb.ass_escape(item.label or item.name)
|
||||
item.type = "dir"
|
||||
table.insert(g.root, pos or (#g.root + 1), item)
|
||||
end
|
||||
|
||||
---Add a new mapping to the given directory.
|
||||
---@param directory string
|
||||
---@param mapping string
|
||||
---@param pattern? boolean
|
||||
---@return string
|
||||
function fb.register_directory_mapping(directory, mapping, pattern)
|
||||
if not pattern then mapping = '^'..fb_utils.pattern_escape(mapping) end
|
||||
g.directory_mappings[mapping] = directory
|
||||
msg.verbose('registering directory alias', mapping, directory)
|
||||
|
||||
directory_movement.set_current_file(g.current_file.original_path)
|
||||
return mapping
|
||||
end
|
||||
|
||||
---Remove all directory mappings that map to the given directory.
|
||||
---@param directory string
|
||||
---@return string[]
|
||||
function fb.remove_all_mappings(directory)
|
||||
local removed = {}
|
||||
for mapping, target in pairs(g.directory_mappings) do
|
||||
if target == directory then
|
||||
g.directory_mappings[mapping] = nil
|
||||
table.insert(removed, mapping)
|
||||
end
|
||||
end
|
||||
return removed
|
||||
end
|
||||
|
||||
---A newer API for adding items to the root.
|
||||
---Only adds the item if the same item does not already exist in the root.
|
||||
---@param item Item|string
|
||||
---@param priority? number Specifies the insertion location, a lower priority
|
||||
--- is placed higher in the list and the default is 100.
|
||||
---@return boolean
|
||||
function fb.register_root_item(item, priority)
|
||||
msg.verbose('registering root item:', utils.to_string(item))
|
||||
if type(item) == 'string' then
|
||||
item = {name = item, type = 'dir'}
|
||||
end
|
||||
|
||||
-- if the item is already in the list then do nothing
|
||||
if fb.list.some(g.root, function(r)
|
||||
return fb.get_full_path(r, '') == fb.get_full_path(item, '')
|
||||
end) then return false end
|
||||
|
||||
---@type table<Item,number>
|
||||
local priorities = {}
|
||||
|
||||
priorities[item] = priority
|
||||
for i, v in ipairs(g.root) do
|
||||
if (priorities[v] or 100) > (priority or 100) then
|
||||
fb.insert_root_item(item, i)
|
||||
return true
|
||||
end
|
||||
end
|
||||
fb.insert_root_item(item)
|
||||
return true
|
||||
end
|
||||
|
||||
--providing getter and setter functions so that addons can't modify things directly
|
||||
|
||||
|
||||
---@param key string
|
||||
---@return boolean|string|number
|
||||
function fb.get_opt(key) return o[key] end
|
||||
|
||||
function fb.get_script_opts() return fb.copy_table(o) end
|
||||
function fb.get_platform() return g.PLATFORM end
|
||||
function fb.get_extensions() return fb.copy_table(g.extensions) end
|
||||
function fb.get_sub_extensions() return fb.copy_table(g.sub_extensions) end
|
||||
function fb.get_audio_extensions() return fb.copy_table(g.audio_extensions) end
|
||||
function fb.get_parseable_extensions() return fb.copy_table(g.parseable_extensions) end
|
||||
function fb.get_state() return fb.copy_table(g.state) end
|
||||
function fb.get_parsers() return fb.copy_table(g.parsers) end
|
||||
function fb.get_root() return fb.copy_table(g.root) end
|
||||
function fb.get_directory() return g.state.directory end
|
||||
function fb.get_list() return fb.copy_table(g.state.list) end
|
||||
function fb.get_current_file() return fb.copy_table(g.current_file) end
|
||||
function fb.get_current_parser() return g.state.parser:get_id() end
|
||||
function fb.get_current_parser_keyname() return g.state.parser.keybind_name or g.state.parser.name end
|
||||
function fb.get_selected_index() return g.state.selected end
|
||||
function fb.get_selected_item() return fb.copy_table(g.state.list[g.state.selected]) end
|
||||
function fb.get_open_status() return not g.state.hidden end
|
||||
function fb.get_parse_state(co) return g.parse_states[co or coroutine.running() or ""] end
|
||||
function fb.get_history() return fb.copy_table(g.history.list) end
|
||||
function fb.get_history_index() return g.history.position end
|
||||
|
||||
---@deprecated
|
||||
---@return string|nil
|
||||
function fb.get_dvd_device()
|
||||
local dvd_device = mp.get_property('dvd-device')
|
||||
if not dvd_device or dvd_device == '' then return nil end
|
||||
return fb_utils.fix_path(dvd_device, true)
|
||||
end
|
||||
|
||||
---@param str string
|
||||
function fb.set_empty_text(str)
|
||||
g.state.empty_text = str
|
||||
fb.redraw()
|
||||
end
|
||||
|
||||
---@param index number
|
||||
---@return number|false
|
||||
function fb.set_selected_index(index)
|
||||
if type(index) ~= "number" then return false end
|
||||
if index < 1 then index = 1 end
|
||||
if index > #g.state.list then index = #g.state.list end
|
||||
g.state.selected = index
|
||||
fb.redraw()
|
||||
return index
|
||||
end
|
||||
|
||||
fb.set_history_index = directory_movement.goto_history
|
||||
|
||||
return fb
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
local msg = require 'mp.msg'
|
||||
|
||||
local g = require 'modules.globals'
|
||||
|
||||
---@class ParseStateAPI
|
||||
local parse_state_API = {}
|
||||
|
||||
---A wrapper around coroutine.yield that aborts the coroutine if
|
||||
--the parse request was cancelled by the user.
|
||||
--the coroutine is
|
||||
---@async
|
||||
---@param self ParseState
|
||||
---@param ... any
|
||||
---@return unknown ...
|
||||
function parse_state_API:yield(...)
|
||||
local co = coroutine.running()
|
||||
local is_browser = co == g.state.co
|
||||
|
||||
local result = table.pack(coroutine.yield(...))
|
||||
if is_browser and co ~= g.state.co then
|
||||
msg.verbose("browser no longer waiting for list - aborting parse for", self.directory)
|
||||
error(g.ABORT_ERROR)
|
||||
end
|
||||
return table.unpack(result, 1, result.n)
|
||||
end
|
||||
|
||||
---Checks if the current coroutine is the one handling the browser's request.
|
||||
---@return boolean
|
||||
function parse_state_API:is_coroutine_current()
|
||||
return coroutine.running() == g.state.co
|
||||
end
|
||||
|
||||
return parse_state_API
|
||||
@@ -0,0 +1,40 @@
|
||||
local msg = require 'mp.msg'
|
||||
|
||||
local g = require 'modules.globals'
|
||||
local scanning = require 'modules.navigation.scanning'
|
||||
local fb = require 'modules.apis.fb'
|
||||
|
||||
---@class ParserAPI: FbAPI
|
||||
local parser_api = setmetatable({}, { __index = fb })
|
||||
|
||||
---Returns the index of the parser.
|
||||
---@return number
|
||||
function parser_api:get_index() return g.parsers[self].index end
|
||||
|
||||
---Returns the ID of the parser
|
||||
---@return string
|
||||
function parser_api:get_id() return g.parsers[self].id end
|
||||
|
||||
---A newer API for adding items to the root.
|
||||
---Only adds the item if the same item does not already exist in the root.
|
||||
---Wrapper around `fb.register_root_item`.
|
||||
---@param item Item|string
|
||||
---@param priority? number The priority for the added item. Uses the parsers priority by default.
|
||||
---@return boolean
|
||||
function parser_api:register_root_item(item, priority)
|
||||
return fb.register_root_item(item, priority or g.parsers[self:get_id()].priority)
|
||||
end
|
||||
|
||||
---Runs choose_and_parse starting from the next parser.
|
||||
---@async
|
||||
---@param directory string
|
||||
---@return Item[]?
|
||||
---@return Opts?
|
||||
function parser_api:defer(directory)
|
||||
msg.trace("deferring to other parsers...")
|
||||
local list, opts = scanning.choose_and_parse(directory, self:get_index() + 1)
|
||||
fb.get_parse_state().already_deferred = true
|
||||
return list, opts
|
||||
end
|
||||
|
||||
return parser_api
|
||||
Reference in New Issue
Block a user