nirish

config files for niri window manager
Log | Files | Refs | README | LICENSE

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