summaryrefslogtreecommitdiff
path: root/mpv/scripts/file-browser/modules/addons/find.lua
diff options
context:
space:
mode:
authorryukamish <[email protected]>2026-04-11 16:06:45 +0530
committerryukamish <[email protected]>2026-04-11 16:06:45 +0530
commit607891801fbf2051a0c9062d15a445dd238c1e1b (patch)
tree33b8cfba2355b498addea05e385b06d46cced30f /mpv/scripts/file-browser/modules/addons/find.lua
parent6fbde2906e3bb2d4d1df23f6374d8a6a0aef870f (diff)
add: mako and mpv configs
Diffstat (limited to 'mpv/scripts/file-browser/modules/addons/find.lua')
-rw-r--r--mpv/scripts/file-browser/modules/addons/find.lua124
1 files changed, 124 insertions, 0 deletions
diff --git a/mpv/scripts/file-browser/modules/addons/find.lua b/mpv/scripts/file-browser/modules/addons/find.lua
new file mode 100644
index 0000000..0b64d92
--- /dev/null
+++ b/mpv/scripts/file-browser/modules/addons/find.lua
@@ -0,0 +1,124 @@
+--[[
+ This file is an internal file-browser addon.
+ It should not be imported like a normal module.
+
+ Allows searching the current directory.
+]]--
+
+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")
+
+---@type ParserConfig
+local find = {
+ api_version = "1.3.0"
+}
+
+---@type thread|nil
+local latest_coroutine = nil
+
+---@type State
+local global_fb_state = getmetatable(fb.get_state()).__original
+
+---@param name string
+---@param query string
+---@return boolean
+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
+
+---@async
+---@param key Keybind
+---@param state State
+---@param co thread
+---@return boolean?
+local function main(key, state, co)
+ if not state.list then return false end
+
+ ---@type string
+ 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
+ ---@async
+ fb.coroutine.run(function()
+ latest_coroutine = coroutine.running()
+ ---@type number
+ local rindex = 1
+ while (true) do
+
+ if rindex == 0 then rindex = #results
+ elseif rindex == #results + 1 then rindex = 1 end
+
+ fb.set_selected_index(results[rindex])
+ local direction = coroutine.yield(true) --[[@as number]]
+ rindex = rindex + direction
+
+ if parse_id ~= global_fb_state.co then
+ latest_coroutine = nil
+ return
+ end
+ end
+ end)
+end
+
+local function step_find(key)
+ if not latest_coroutine then return false end
+ ---@type number
+ local direction = 0
+ if key.name == "find/next" then direction = 1
+ elseif key.name == "find/prev" then direction = -1 end
+ return fb.coroutine.resume_err(latest_coroutine, direction)
+end
+
+find.keybinds = {
+ {"Ctrl+f", "find", main, {}},
+ {"Ctrl+F", "find_advanced", main, {}},
+ {"n", "next", step_find, {}},
+ {"N", "prev", step_find, {}},
+}
+
+return find