script-messages.lua (4231B)
1 local mp = require 'mp' 2 local msg = require 'mp.msg' 3 local utils = require 'mp.utils' 4 5 local o = require 'modules.options' 6 local g = require 'modules.globals' 7 local fb_utils = require 'modules.utils' 8 local scanning = require 'modules.navigation.scanning' 9 10 ---@class script_messages 11 local script_messages = {} 12 13 ---Allows other scripts to request directory contents from file-browser. 14 ---@param directory string 15 ---@param response_str string 16 function script_messages.get_directory_contents(directory, response_str) 17 ---@async 18 fb_utils.coroutine.run(function() 19 if not directory then msg.error("did not receive a directory string"); return end 20 if not response_str then msg.error("did not receive a response string"); return end 21 22 directory = mp.command_native({"expand-path", directory}, "") --[[@as string]] 23 if directory ~= "" then directory = fb_utils.fix_path(directory, true) end 24 msg.verbose(("recieved %q from 'get-directory-contents' script message - returning result to %q"):format(directory, response_str)) 25 26 directory = fb_utils.resolve_directory_mapping(directory) 27 28 ---@class OptsWithVersion: Opts 29 ---@field API_VERSION string? 30 31 ---@type List|nil, OptsWithVersion|Opts|nil 32 local list, opts = scanning.scan_directory(directory, { source = "script-message" } ) 33 if opts then opts.API_VERSION = g.API_VERSION end 34 35 local list_str, err = fb_utils.format_json_safe(list) 36 if not list_str then msg.error(err) end 37 38 local opts_str, err2 = fb_utils.format_json_safe(opts) 39 if not opts_str then msg.error(err2) end 40 41 mp.commandv("script-message", response_str, list_str or "", opts_str or "") 42 end) 43 end 44 45 ---A helper script message for custom keybinds. 46 ---Substitutes any '=>' arguments for 'script-message'. 47 ---Makes chaining script-messages much easier. 48 ---@param ... string 49 function script_messages.chain(...) 50 ---@type string[] 51 local command = table.pack('script-message', ...) 52 for i, v in ipairs(command) do 53 if v == '=>' then command[i] = 'script-message' end 54 end 55 mp.commandv(table.unpack(command)) 56 end 57 58 ---A helper script message for custom keybinds. 59 ---Sends a command after the specified delay. 60 ---@param delay string 61 ---@param ... string 62 ---@return nil 63 function script_messages.delay_command(delay, ...) 64 local command = table.pack(...) 65 local success, err = pcall(mp.add_timeout, fb_utils.evaluate_string('return '..delay), function() mp.commandv(table.unpack(command)) end) 66 if not success then return msg.error(err) end 67 end 68 69 ---A helper script message for custom keybinds. 70 ---Sends a command only if the given expression returns true. 71 ---@param condition string 72 ---@param ... string 73 function script_messages.conditional_command(condition, ...) 74 local command = table.pack(...) 75 fb_utils.coroutine.run(function() 76 if fb_utils.evaluate_string('return '..condition) == true then mp.commandv(table.unpack(command)) end 77 end) 78 end 79 80 ---A helper script message for custom keybinds. 81 ---Extracts lua expressions from the command and evaluates them. 82 ---Expressions must be surrounded by !{}. Another ! before the { will escape the evaluation. 83 ---@param ... string 84 function script_messages.evaluate_expressions(...) 85 ---@type string[] 86 local args = table.pack(...) 87 fb_utils.coroutine.run(function() 88 for i, arg in ipairs(args) do 89 args[i] = arg:gsub('(!+)(%b{})', function(lead, expression) 90 if #lead % 2 == 0 then return string.rep('!', #lead/2)..expression end 91 92 ---@type any 93 local eval = fb_utils.evaluate_string('return '..expression:sub(2, -2)) 94 return type(eval) == "table" and utils.to_string(eval) or tostring(eval) 95 end) 96 end 97 98 mp.commandv(table.unpack(args)) 99 end) 100 end 101 102 ---A helper function for custom-keybinds. 103 ---Concatenates the command arguments with newlines and runs the 104 ---string as a statement of code. 105 ---@param ... string 106 function script_messages.run_statement(...) 107 local statement = table.concat(table.pack(...), '\n') 108 fb_utils.coroutine.run(fb_utils.evaluate_string, statement) 109 end 110 111 return script_messages