200 lines
5.6 KiB
Lua
Executable file
200 lines
5.6 KiB
Lua
Executable file
-- This script provides an easy interface for setting/appending to
|
|
-- --glsl-shaders.
|
|
--
|
|
-- Ctrl+r is the default keybind, but if desired this can be changed in
|
|
-- input.conf, for example:
|
|
--
|
|
-- Ctrl+t script-binding pickshader
|
|
--
|
|
-- The interface is similar to ^R from Unix shells. Once it's open, simply type
|
|
-- a query to narrow down the results.
|
|
--
|
|
-- These keybinds can be used within the interface:
|
|
--
|
|
-- ESC or Ctrl+c will close the interface
|
|
--
|
|
-- ENTER will ADD the selected shader to --glsl-shaders
|
|
--
|
|
-- Ctrl+ENTER will SET --glsl-shaders to the selected shader
|
|
--
|
|
-- UP, DOWN, Ctrl+n, Ctrl+p will move the cursor up/down
|
|
--
|
|
-- This script assumes shaders are installed under ~~/shaders/ (~~ being the
|
|
-- directory where mpv.conf is). If they aren't located there, either relocate
|
|
-- them or make a symlink.
|
|
|
|
local utils = require 'mp.utils'
|
|
local options = require 'mp.options'
|
|
|
|
-- If you really don't want to use ~~/shaders for some reason this can be
|
|
-- changed in ~~/script-opts/pickshader.conf
|
|
local o = {
|
|
shader_dir = "~~/shaders"
|
|
}
|
|
options.read_options(o)
|
|
|
|
local function recursive_ls(dir)
|
|
local result = {}
|
|
local ls = utils.readdir(dir)
|
|
for i,child in pairs(ls) do
|
|
local info = utils.file_info(dir.."/"..child);
|
|
if info.is_dir then
|
|
for _,grandchild in pairs(recursive_ls(dir.."/"..child)) do
|
|
result[#result + 1] = grandchild
|
|
end
|
|
elseif string.match(child, "%.glsl$") or string.match(child, "%.hook$") then
|
|
result[#result + 1] = dir.."/"..child
|
|
end
|
|
end
|
|
return result
|
|
end
|
|
|
|
shaders = nil
|
|
local function init_shaders()
|
|
if shaders ~= nil then
|
|
return
|
|
end
|
|
local shader_dir = mp.command_native({"expand-path", o.shader_dir})
|
|
shaders = recursive_ls(shader_dir)
|
|
for i,shader in pairs(shaders) do -- basename
|
|
shaders[i] = shaders[i]:sub(shader_dir:len() + 2)
|
|
end
|
|
table.sort(shaders)
|
|
end
|
|
|
|
grepped_arr = {}
|
|
grepped_pattern = ""
|
|
cursor = 1
|
|
local function draw()
|
|
if current_pattern == "" then
|
|
grepped_arr = shaders
|
|
grepped_pattern = current_pattern
|
|
elseif grepped_pattern ~= current_pattern then
|
|
grepped_arr = {}
|
|
grepped_pattern = current_pattern
|
|
cursor = 1
|
|
for i,shader in pairs(shaders) do
|
|
-- XXX maybe split by space and interpret each part as a separate pattern
|
|
local e, match = pcall(string.match, shader:lower(), current_pattern:lower())
|
|
if match and e then
|
|
grepped_arr[#grepped_arr + 1] = shader
|
|
elseif not e then
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
local results_str = ""
|
|
for i,shader in pairs(grepped_arr) do
|
|
if i == cursor then
|
|
results_str = results_str .. "\n> " .. shader
|
|
elseif math.abs(i - cursor) < 3 then
|
|
results_str = results_str .. "\n" .. shader
|
|
end
|
|
end
|
|
results_str = results_str:sub(2) -- trim leading newline
|
|
|
|
-- lazy underlining, lua doesn't support case insensitive matching
|
|
if current_pattern ~= "" then
|
|
local e, underlined = pcall(string.gsub, results_str, current_pattern, "{\\u1}%0{\\u0}")
|
|
if e then results_str = underlined end
|
|
local e, underlined = pcall(string.gsub, results_str, current_pattern:upper(), "{\\u1}%0{\\u0}")
|
|
if e then results_str = underlined end
|
|
end
|
|
|
|
if results_str == "" then
|
|
results_str = "> " .. current_pattern
|
|
end
|
|
|
|
overlay.data = results_str
|
|
overlay:update()
|
|
end
|
|
|
|
local function incr_cursor()
|
|
cursor = math.min(cursor + 1, #grepped_arr)
|
|
draw()
|
|
end
|
|
|
|
local function decr_cursor()
|
|
cursor = math.max(cursor - 1, 1)
|
|
draw()
|
|
end
|
|
|
|
local function mode_off()
|
|
mode_on = false
|
|
grepped_arr = {}
|
|
cursor = 1
|
|
grepped_pattern = ""
|
|
current_pattern = ""
|
|
overlay.data = ""
|
|
overlay:remove()
|
|
overlay:update()
|
|
local binds = { "mode_off1", "mode_off2", "mode_off3", "incr1", "decr1", "incr2", "decr2", "backspace", "clear", "pick_add", "pick_set", "handle_input" }
|
|
for k,v in pairs(binds) do
|
|
mp.remove_key_binding(v)
|
|
end
|
|
end
|
|
|
|
local function backspace()
|
|
current_pattern = current_pattern:sub(1, -2)
|
|
draw()
|
|
end
|
|
|
|
local function clear()
|
|
current_pattern = ""
|
|
draw()
|
|
end
|
|
|
|
local function pick(op)
|
|
local shader = grepped_arr[cursor]
|
|
if op == nil then op = "add" end
|
|
|
|
mp.commandv("change-list", "glsl-shaders", op, o.shader_dir.."/"..shader)
|
|
mode_off()
|
|
mp.commandv("show-text", op.." "..shader)
|
|
end
|
|
|
|
current_pattern = ""
|
|
local function handle_input(input)
|
|
if input.event == "press"
|
|
or input.event == "down"
|
|
or input.event == "repeat" then
|
|
current_pattern = current_pattern .. input.key_text
|
|
draw()
|
|
end
|
|
end
|
|
|
|
mode_on = false
|
|
local function pickshader()
|
|
if not mode_on then
|
|
mode_on = true
|
|
overlay = mp.create_osd_overlay("ass-events")
|
|
init_shaders()
|
|
|
|
mp.add_forced_key_binding("ESC", "mode_off1", mode_off)
|
|
mp.add_forced_key_binding("Ctrl+[", "mode_off2", mode_off)
|
|
mp.add_forced_key_binding("Ctrl+c", "mode_off3", mode_off)
|
|
mp.add_forced_key_binding("Ctrl+n", "incr1", incr_cursor,
|
|
{ repeatable = true })
|
|
mp.add_forced_key_binding("Ctrl+p", "decr1", decr_cursor,
|
|
{ repeatable = true })
|
|
mp.add_forced_key_binding("DOWN", "incr2", incr_cursor,
|
|
{ repeatable = true })
|
|
mp.add_forced_key_binding("UP", "decr2", decr_cursor,
|
|
{ repeatable = true })
|
|
mp.add_forced_key_binding("BS", "backspace", backspace,
|
|
{ repeatable = true })
|
|
mp.add_forced_key_binding("Ctrl+u", "clear", clear)
|
|
mp.add_forced_key_binding("ENTER", "pick_add", pick)
|
|
mp.add_forced_key_binding("Ctrl+ENTER", "pick_set", function() pick("set") end)
|
|
mp.add_forced_key_binding("any_unicode", "handle_input", handle_input,
|
|
{ repeatable = true, complex = true })
|
|
draw()
|
|
else
|
|
incr_cursor()
|
|
end
|
|
end
|
|
|
|
mp.add_key_binding("Ctrl+r", "pickshader", pickshader,
|
|
{ repeatable = true })
|
|
|