105 lines
3.0 KiB
Lua
105 lines
3.0 KiB
Lua
--[[
|
|
An addon for mpv-file-browser for searching the current directory
|
|
Available at: https://github.com/CogentRedTester/mpv-file-browser/tree/master/addons
|
|
|
|
Requires mpv-user-input: https://github.com/CogentRedTester/mpv-user-input
|
|
|
|
Keybinds:
|
|
Ctrl+f open search box
|
|
Ctrl+F open advanced search box (supports Lua patterns)
|
|
n cycle to next valid item
|
|
]]--
|
|
|
|
local msg = require "mp.msg"
|
|
local fb = require "file-browser"
|
|
local input_loaded, input = pcall(require, "mp.input")
|
|
local user_input_loaded, user_input = pcall(require, "user-input-module")
|
|
|
|
local find = {
|
|
api_version = "1.3.0"
|
|
}
|
|
local latest_coroutine = nil
|
|
local global_fb_state = getmetatable(fb.get_state()).__original
|
|
|
|
local function compare(name, query)
|
|
if name:find(query) then return true end
|
|
if name:lower():find(query) then return true end
|
|
if name:upper():find(query) then return true end
|
|
|
|
return false
|
|
end
|
|
|
|
local function main(key, state, co)
|
|
if not state.list then return false end
|
|
|
|
local text
|
|
if key.name == "find/find" then text = "Find: enter search string"
|
|
else text = "Find: enter advanced search string" end
|
|
|
|
if input_loaded then
|
|
input.get({
|
|
prompt = text .. "\n>",
|
|
id = "file-browser/find",
|
|
submit = fb.coroutine.callback(),
|
|
})
|
|
elseif user_input_loaded then
|
|
user_input.get_user_input( fb.coroutine.callback(), { text = text, id = "find", replace = true } )
|
|
end
|
|
|
|
local query, error = coroutine.yield()
|
|
if input_loaded then input.terminate() end
|
|
if not query then return msg.debug(error) end
|
|
|
|
-- allow the directory to be changed before this point
|
|
local list = fb.get_list()
|
|
local parse_id = global_fb_state.co
|
|
|
|
if key.name == "find/find" then
|
|
query = fb.pattern_escape(query)
|
|
end
|
|
|
|
local results = {}
|
|
|
|
for index, item in ipairs(list) do
|
|
if compare(item.label or item.name, query) then
|
|
table.insert(results, index)
|
|
end
|
|
end
|
|
|
|
if (#results < 1) then
|
|
msg.warn("No matching items for '"..query.."'")
|
|
return
|
|
end
|
|
|
|
--keep cycling through the search results if any are found
|
|
--putting this into a separate coroutine removes any passthrough ambiguity
|
|
--the final return statement should return to `step_find` not any other function
|
|
fb.coroutine.run(function()
|
|
latest_coroutine = coroutine.running()
|
|
while (true) do
|
|
for _, index in ipairs(results) do
|
|
fb.set_selected_index(index)
|
|
coroutine.yield(true)
|
|
|
|
if parse_id ~= global_fb_state.co then
|
|
latest_coroutine = nil
|
|
return false
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
|
|
local function step_find()
|
|
if not latest_coroutine then return false end
|
|
return fb.coroutine.resume_err(latest_coroutine)
|
|
end
|
|
|
|
find.keybinds = {
|
|
{"Ctrl+f", "find", main, {}},
|
|
{"Ctrl+F", "find_advanced", main, {}},
|
|
{"n", "next", step_find, {}},
|
|
}
|
|
|
|
return find
|