# Helpers for writing Hyprland's Lua config through home-manager, which # renders each `settings.` entry as an hl.(...) call. Calls with # several arguments take an `_args` list, and Lua expressions (dispatchers) # must be wrapped with mkLuaInline or they'd be emitted as strings. { lib }: rec { lua = lib.generators.mkLuaInline; # A Lua string literal (JSON's escaping is valid Lua for printable text). str = builtins.toJSON; _bind = keys: dispatcher: { _args = [ keys (lua dispatcher) ]; }; bindWith = opts: keys: dispatcher: { _args = [ keys (lua dispatcher) opts ]; }; bind = keys: dispatcher: desc: bindWith {description = desc;} keys dispatcher; bindm = keys: dispatcher: desc: bindWith {description = desc; mouse = true;} keys dispatcher; exec = cmd: "hl.dsp.exec_cmd(${str cmd})"; mulexec = cmds: "function() ${lib.concatMapStringsSep " " (cmd: "hl.dsp.exec_cmd(${str cmd})") cmds} end"; pass = window: "hl.dsp.pass({ window = ${str window}})"; submap = name: "hl.dsp.submap(${str name})"; sendShortcut = shortcut: window: "hl.dsp.send_shortcut({ mods = '', key = ${str shortcut}, window = ${str window}})"; moveWorkspace = ws: follow: "hl.dsp.window.move({ workspace = ${if builtins.isInt ws then toString ws else str ws}; follow = ${str follow} })"; moveDirection = dir: "hl.dsp.window.move({ direction = ${str dir} })"; focusWorkspace = ws: "hl.dsp.focus({ workspace = ${if builtins.isInt ws then toString ws else str ws} })"; focusDirection = dir: "hl.dsp.focus({ direction = ${str dir} })"; makeSubmap = name: binds: let bindContent = builtins.concatStringsSep "\n " (map (bind: ''hl.bind("${builtins.elemAt bind 0}", ${builtins.elemAt bind 1}, { description = "${if builtins.length bind >= 3 then builtins.elemAt bind 2 else ""}" })'' ) binds); in { _args = [ name (lua "function()\n ${bindContent}\nend") ]; }; }