The Nixpkgs-endorsed way to write an executable Lua script is writers.buildLua; this accepts a libraries argument and gives the produced script a shebang to a Lua interpreter that has been wrapped to include the provided libraries in its search path.
This tip is for when you want to write a Lua script for an application that embeds Lua. In that case, wrapping the Lua interpreter is not possible. So how do you use packages from luaPackages in your script?
Here’s a solution I found. In this example, I wanted to add a script to Home Manager’s programs.mpv.scripts that would use luaPackages.ldbus. The Lua package system exposes two variables that it uses to search for packages: package.cpath and package.path. In the general case, both must be updated, and they can be updated from within the Lua script. I found two helper functions in luaPackages.luaLib for formatting the search strings. Here is what I use as the text of my script:
with pkgs.luaPackages; ''
package.cpath = '${luaLib.genLuaCPathAbsStr ldbus};' .. package.cpath
package.path = '${luaLib.genLuaPathAbsStr ldbus};' .. package.path
-- My use case: use ldbus to send a D-Bus message when mpv is in
-- fullscreen mode to a service I wrote that dims the lights in the
-- room.
local ldbus = require 'ldbus'
local conn = ldbus.bus.get 'session'
mp.observe_property('fullscreen', 'bool', function (prop, val)
if val then
cmd = 'Dim'
else
cmd = 'UnDim'
end
conn:send(ldbus.message.new_method_call('...', '...', '...', cmd))
end)
''
(Post better solutions if you know them! I’m only a dabbler in Lua.)