nixcfg
nixcfg copied to clipboard
A better way to do multiline scripts in Sway
I've been studying your config and applying the bits I like to mine, but in doing so have found a better way to handle scripts in the sway config you have. I wanted to do some advanced scripting, so was getting quite annoyed with all of the \
s for newlines. So instead, we can use pkgs.writeShellScript
to write a script which is then used as a substitution, which avoids all of that.
For example:
You do
https://github.com/cole-mickens/nixcfg/blob/aef46f04089021adf3364c91402c761479cefb38/mixins/sway.nix#L56-L62
I do
{
idlecmd = pkgs.writeShellScript "swayidle.sh" ''
${pkgs.swayidle}/bin/swayidle -w
before-sleep "${swaylockcmd}"
lock "${swaylockcmd}"
timeout 500 "${swaylockcmd}"
timeout 1000 "${pkgs.systemd}/bin/systemctl suspend"
'';
}
pkgs.writeShellScript
will return a path to the nix store where the script is, Sway will run the shell script rather than having to interpret \
.
While I grant that my swaylock setup might be broken, afaict that's not right either? From first glance, what you wrote is a shell script that executed 5 lines, only one of which is (partially) valid.
only one of which is (partially) valid.
Hah, you're right, you still need the multiline \
s. I still think this method of writing a shell script and calling it is less error prone though.
❯ sway
No status data could be sent: $NOTIFY_SOCKET was not set
tail: cannot open '/run/user/1000/sway-ipc.1000.160833.sock.wob' for reading: No such file or directory
tail: no files remaining
Failed to acquire service name: File exists
Is a notification daemon already running?
1627915052.999441 ERROR main.c:788: STDIN unexpectedly closed, revents = 16
No command specified! Nothing to do, will exit
/nix/store/ia71kkvb4gs4r5hhi13y7nx239zq9pm2-swayidle.sh: line 3: before-sleep: command not found
/nix/store/ia71kkvb4gs4r5hhi13y7nx239zq9pm2-swayidle.sh: line 4: lock: command not found
timeout: failed to run command ‘/nix/store/1iddbq0z64y9y6b3ms01grakw9zzcdb9-swaylock-1.5/bin/swaylock -c '#000000'’: No such file or directory
timeout: failed to run command ‘/nix/store/yh9hjlgknf4ff8di0lw0hgm6clx38p47-systemd-247.6/bin/systemctl suspend’: No such file or directory
Another flashfocus instance is running.
An example of where this method is obviously better would be how I manage my "dropdown" terminal, which is a terminal that pops up in the center of the screen when I hit f12. Each time I hit f12 this script is fired off, doing this without writing a shell script would be really hard due to how you'd have to write it in terms of escape chars, etc.
https://github.com/MatthewCroughan/nixcfg/blob/9436a367dec2d17df7d7c1cee84cad8825b422b9/mixins/sway.nix#L24-L37
let
dropdownTerminalCmd = pkgs.writeShellScript "launchkitty.sh" ''
open=$(ps aux | grep -i "kitty --class=dropdown" | grep -v grep)
if [[ $open -eq 0 ]]
then
${pkgs.kitty}/bin/kitty --class=dropdown --detach
until swaymsg scratchpad show
do
echo "Waiting for Kitty to appear..."
done
else
echo "Kitty is already open"
swaymsg "[app_id=dropdown] scratchpad show"
fi
'';
in
{
...
}
I have a pretty complete swayidle module here (that needs to be merged in HM): https://github.com/berbiche/dotfiles/blob/40a6f3666c11abcb5ae34a09099c190b36148b7f/modules/home-manager/swayidle.nix
This is what it looks like configured:
{
services.swayidle = {
enable = true;
idlehint = "5 minutes";
timeout = [
{
timeout = "5 minutes";
command = "${swaylock} -f";
}
{
timeout = "10 minutes";
command = "${swaymsg} 'output * dpms off'";
resume = "${swaymsg} 'output * dpms on'";
}
];
before-sleep = [
"${playerctl} ${withPlayerctld} pause"
"${dunstctl} set-paused true"
"${swaylock} -f"
];
lock = [
"${dunstctl} set-paused true"
];
unlock = [
"${dunstctl} set-paused false"
];
};
}
This is pretty old, and I do use the better multiline strings now :).