nixfiles/home-manager/modules/ezpcusr.nix

705 lines
23 KiB
Nix
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

inputs: {
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.ezpcusr;
lockCommand = pkgs.writeScript "lock.sh" ''
${pkgs.swaylock-effects}/bin/swaylock -f --clock --indicator --screenshots --effect-scale 0.8 --effect-blur 8x3 --effect-vignette 0.2:0.5 --fade-in 0.5 --text-color ${config.ezcolors.base16.base08} --inside-color ${config.ezcolors.base16.base00} --ring-color ${config.ezcolors.base16.base01} --datestr "%Y-%m-%e" --timestr "%I:%M %p"
'';
selshot = pkgs.writeScript "selshot.sh" ''
#!${pkgs.zsh}/bin/zsh
${pkgs.grim}/bin/grim -g "$(${pkgs.slurp}/bin/slurp)" $1
'';
selvid = pkgs.writeScript "selvid.sh" ''
#!${pkgs.zsh}/bin/zsh
${pkgs.wf-recorder}/bin/wf-recorder -g "$(${pkgs.slurp}/bin/slurp)" -f $1
'';
getscrloc = pkgs.writeScript "getscrloc.sh" ''
#!${pkgs.zsh}/bin/zsh
mkdir -p "${cfg.screenshotsPath}"
echo "${cfg.screenshotsPath}/$(date +%F_%T).''${1:-png}"
'';
scrsaveclip = pkgs.writeScript "scr-save-clip.sh" ''
#!${pkgs.zsh}/bin/zsh
LOC=$(${getscrloc})
${selshot} $LOC
${pkgs.wl-clipboard}/bin/wl-copy -t image/png < $LOC
'';
scrsaveup =
if cfg.uploadScript != null
then
pkgs.writeScript "scr-save-up.sh" ''
#!${pkgs.zsh}/bin/zsh
LOC=$(${getscrloc})
${selshot} $LOC
${cfg.uploadScript} $LOC | xargs echo -n | ${pkgs.wl-clipboard}/bin/wl-copy
notify-send "Screenshot Uploaded!"
''
else null;
scrvidsaveclip = pkgs.writeScript "scr-vid-save-clip.sh" ''
#!${pkgs.zsh}/bin/zsh
LOC=$(${getscrloc} mp4)
${selvid} $LOC
${pkgs.wl-clipboard}/bin/wl-copy -t video/mp4 < $LOC
'';
scrvidsaveup =
if cfg.uploadScript != null
then
pkgs.writeScript "scr-vid-save-up.sh" ''
#!${pkgs.zsh}/bin/zsh
LOC=$(${getscrloc} mp4)
${selvid} $LOC
${cfg.uploadScript} $LOC | ${pkgs.findutils}/bin/xargs echo -n | ${pkgs.wl-clipboard}/bin/wl-copy
notify-send "Screen Recording Uploaded!"
''
else null;
scrvidstop = pkgs.writeScript "scr-vid-stop.sh" ''
#!${pkgs.zsh}/bin/zsh
${pkgs.procps}/bin/pkill -2 wf-recorder
'';
ezDrv = pkgs.runCommand "ez-commands" {} (
''
mkdir -p $out/bin
ln -s ${selshot} $out/bin/selshot
ln -s ${selvid} $out/bin/selvid
ln -s ${getscrloc} $out/bin/getscrloc
ln -s ${scrsaveclip} $out/bin/scrsaveclip
ln -s ${scrvidsaveclip} $out/bin/scrvidsaveclip
ln -s ${scrvidstop} $out/bin/scrvidstop
''
+ (
if cfg.uploadScript != null
then ''
ln -s ${cfg.uploadScript} $out/bin/upload_file
ln -s ${scrsaveup} $out/bin/scrsaveup
ln -s ${scrvidsaveup} $out/bin/scrvidsaveup
''
else ""
)
);
in {
options.ezpcusr = {
enable = mkEnableOption "Enable simple PC user config";
uploadScript = mkOption {
type = types.nullOr types.package;
default = null;
description = "A path to a script that takes a path to a file and returns a URL";
};
screenshotsPath = mkOption {
description = "Path to save screenshots in";
default = "$HOME/Media/Screenshots";
type = types.str;
};
screensaver = mkOption {
description = "ezpcusr screensaver";
default = {};
type = types.submodule {
options = {
lockTime = mkOption {
type = types.int;
default = 300;
description = "Time until your screen locks";
};
offTime = mkOption {
type = types.int;
default = 600;
description = "Time until your screen turns off";
};
};
};
};
favIcons = mkOption {
description = "Your favourite icons pack";
default = {};
type = types.submodule {
options = {
name = mkOption {
type = types.str;
default = "Papirus-Dark";
description = "Name of your icon pack";
};
package = mkOption {
type = types.package;
default = pkgs.papirus-icon-theme;
description = "Package for your icon pack";
};
};
};
};
bluetooth = mkOption {
type = types.bool;
default = false;
description = "If this PC has bluetooth support";
};
battery = mkOption {
type = types.bool;
default = false;
description = "If this PC has a battery";
};
location = mkOption {
description = "Your location (used for weather)";
example = "US-12345";
default = "";
type = types.str;
};
};
config = lib.mkIf cfg.enable {
services.swayidle = {
enable = lib.mkDefault true;
events = [
{
event = "before-sleep";
command = "${lockCommand}";
}
{
event = "lock";
command = "${lockCommand}";
}
];
timeouts = [
{
timeout = cfg.screensaver.lockTime;
command = "${lockCommand}";
}
{
timeout = cfg.screensaver.offTime;
command = "${pkgs.sway}/bin/swaymsg 'output * dpms off'";
resumeCommand = "${pkgs.sway}/bin/swaymsg 'output * dpms on'";
}
];
};
wayland.windowManager.sway = {
enable = lib.mkDefault true;
systemdIntegration = lib.mkDefault true;
wrapperFeatures.gtk = lib.mkDefault true;
extraConfig = ''
exec keyctl link @u @s
workspace 1
'';
config = {
terminal = lib.mkDefault "${pkgs.kermit-terminal}/bin/kermit";
modifier = lib.mkDefault "Mod4";
keybindings = let
modifier = config.wayland.windowManager.sway.config.modifier;
alphabet = ["Ctrl" "Alt" "Ctrl+Alt"];
genKeyAttrs = move:
lib.listToAttrs (
map
(
n: {
name = "${modifier}${
if move
then "+Shift"
else ""
}+${builtins.elemAt alphabet ((n - 11) / 10)}+${toString (lib.mod n 10)}";
value = "${
if move
then "move container to "
else ""
}workspace number ${toString n}";
}
)
(lib.lists.range 11 (10 * (builtins.length alphabet) + 10))
);
in
lib.mkOptionDefault (
let
volumeUp = "exec ${pkgs.pulseaudio}/bin/pactl set-sink-volume @DEFAULT_SINK@ +5%";
volumeDown = "exec ${pkgs.pulseaudio}/bin/pactl set-sink-volume @DEFAULT_SINK@ -5%";
in
{
"${modifier}+q" = "kill";
"Print" = "exec ${scrsaveclip}";
"Shift+Print" =
if cfg.uploadScript != null
then "exec ${scrsaveup}"
else "nop";
"Ctrl+Print" = "exec ${scrvidsaveclip}";
"Ctrl+Alt+Print" = "exec ${scrvidstop}";
"${modifier}+minus" = volumeDown;
"${modifier}+equal" = volumeUp;
"XF86AudioRaiseVolume" = volumeUp;
"XF86AudioLowerVolume" = volumeDown;
"XF86AudioMute" = "exec ${pkgs.pulseaudio}/bin/pactl set-sink-mute @DEFAULT_SINK@ toggle";
"XF86AudioMicMute" = "exec ${pkgs.pulseaudio}/bin/pactl set-source-mute @DEFAULT_SOURCE@ toggle";
"XF86MonBrightnessDown" = "exec ${pkgs.light}/bin/light -U 10";
"XF86MonBrightnessUp" = "exec ${pkgs.light}/bin/light -A 10";
"${modifier}+semicolon" = "exec ${pkgs.light}/bin/light -U 10";
"${modifier}+apostrophe" = "exec ${pkgs.light}/bin/light -A 10";
# Previous/next but change the shuffle/random state before action (and change back afterwards)
"${modifier}+Shift+bracketright" = "exec ${pkgs.playerctl}/bin/playerctl shuffle Toggle && ${pkgs.playerctl}/bin/playerctl next && ${pkgs.playerctl}/bin/playerctl shuffle Toggle";
"${modifier}+Shift+bracketleft" = "exec ${pkgs.playerctl}/bin/playerctl shuffle Toggle && ${pkgs.playerctl}/bin/playerctl previous && ${pkgs.playerctl}/bin/playerctl shuffle Toggle";
"Shift+XF86AudioNext" = "exec ${pkgs.playerctl}/bin/playerctl shuffle Toggle && ${pkgs.playerctl}/bin/playerctl next && ${pkgs.playerctl}/bin/playerctl shuffle Toggle";
# Previous/next
"${modifier}+bracketright" = "exec ${pkgs.playerctl}/bin/playerctl next";
"${modifier}+bracketleft" = "exec ${pkgs.playerctl}/bin/playerctl previous";
"XF86AudioNext" = "exec ${pkgs.playerctl}/bin/playerctl next";
"XF86AudioPrev" = "exec ${pkgs.playerctl}/bin/playerctl prev";
# Seek forward/back
"${modifier}+Ctrl+bracketright" = "exec ${pkgs.playerctl}/bin/playerctl position 5+";
"${modifier}+Ctrl+bracketleft" = "exec ${pkgs.playerctl}/bin/playerctl position 5-";
"Ctrl+XF86AudioNext" = "exec ${pkgs.playerctl}/bin/playerctl position 5+";
"Ctrl+XF86AudioPrev" = "exec ${pkgs.playerctl}/bin/playerctl position 5-";
# Toggle play/pause
"XF86AudioPlay" = "exec ${pkgs.playerctl}/bin/playerctl play-pause";
"XF86AudioPause" = "exec ${pkgs.playerctl}/bin/playerctl play-pause";
"${modifier}+backslash" = "exec ${pkgs.playerctl}/bin/playerctl play-pause";
"${modifier}+Ctrl+Shift+m" = let
ripMusicAdvanced = pkgs.writeShellScript "rip-music-advanced.sh" ''
CURRENT=$(${pkgs.mpc_cli}/bin/mpc -f '%file%' current)
URLIFIED=$(${pkgs.gnused}/bin/sed 's/youtube:video:/https:\/\/youtube.com\/watch?v=/'<<<$CURRENT)
PARAMS=$(${config.programs.rofi.package}/bin/rofi -dmenu)
echo y | ${inputs.mudl.defaultPackage.${pkgs.system}}/bin/mudl "$URLIFIED" "$PARAMS"
'';
in "exec ${ripMusicAdvanced}";
"${modifier}+Ctrl+m" = let
ripMusic = pkgs.writeShellScript "rip-music.sh" ''
CURRENT=$(${pkgs.mpc_cli}/bin/mpc -f '%file%' current)
URLIFIED=$(${pkgs.gnused}/bin/sed 's/youtube:video:/https:\/\/youtube.com\/watch?v=/'<<<$CURRENT)
DL_OUT=$(echo y | ${inputs.mudl.defaultPackage.${pkgs.system}}/bin/mudl "$URLIFIED")
if echo "$DL_OUT" | ${pkgs.gnugrep}/bin/grep -qE 'Album: $'; then
${pkgs.libnotify}/bin/notify-send mudl 'Album name required'
ALBUM=$(${config.programs.rofi.package}/bin/rofi -dmenu)
echo y | ${inputs.mudl.defaultPackage.${pkgs.system}}/bin/mudl "$URLIFIED" "$ALBUM"
fi
'';
in "exec ${ripMusic}";
"${modifier}+m" = let
musicRofi = pkgs.writeShellScript "music-rofi" ''
SONGN=$(${pkgs.mpc_cli}/bin/mpc -f "%position% - %artist% - %album% - %title%" playlist | ${config.programs.rofi.package}/bin/rofi -dmenu -i | ${pkgs.coreutils}/bin/cut -d " " -f 1)
[ ! -z "$SONGN" ] && ${pkgs.mpc_cli}/bin/mpc play "$SONGN"
'';
in "exec ${musicRofi}";
"${modifier}+k" = "exec ${pkgs.mpc_cli}/bin/mpc clear";
"${config.wayland.windowManager.sway.config.modifier}+Shift+k" = lib.mkForce "exec ${pkgs.mpc_cli}/bin/mpc ls \"Local media/Tracks\" | ${pkgs.mpc_cli}/bin/mpc add";
"${config.wayland.windowManager.sway.config.modifier}+Shift+m" = let
mopidySearch = pkgs.writeShellScript "mopidy-search.sh" ''
QUERY=$(${config.programs.rofi.package}/bin/rofi -dmenu)
[ -z "$QUERY" ] && exit
RESULTS=$(${pkgs.mpc_cli}/bin/mpc search -f '%file% / %artist% - %title%' any "$QUERY")
USERLIST=$(echo "$RESULTS" | ${pkgs.gawk}/bin/awk -F' / ' '{print $2}')
CHOSEN=$(echo "$USERLIST" | ${config.programs.rofi.package}/bin/rofi -dmenu -i)
[ -z "$CHOSEN" ] && exit
NTH=$(echo "$USERLIST" | ${pkgs.gnugrep}/bin/grep -n "^$CHOSEN$" | cut -d':' -f1)
LINE=$(echo "$RESULTS" | ${pkgs.coreutils}/bin/tail "-n+$NTH" | ${pkgs.coreutils}/bin/head -1)
NAME=$(echo "$LINE" | ${pkgs.gawk}/bin/awk -F' / ' '{print $1}')
${pkgs.mpc_cli}/bin/mpc add "$NAME"
PLAYLIST=$(${pkgs.mpc_cli}/bin/mpc -f "%position% / %file%" playlist)
PLAYLIST_ENTRY=$(echo "$PLAYLIST" | ${pkgs.gnugrep}/bin/grep -E "^.* / $NAME$" | head -1)
PLAYLIST_ENTRY_POSITION=$(echo "$PLAYLIST_ENTRY" | ${pkgs.gawk}/bin/awk -F' / ' '{print $1}')
${pkgs.mpc_cli}/bin/mpc play "$PLAYLIST_ENTRY_POSITION"
'';
in "exec ${mopidySearch}";
"${modifier}+p" = "exec bash ${inputs.bwmenu}/bwmenu";
"${modifier}+e" = "exec bash ${inputs.bemoji}/bemoji -t";
"${modifier}+0" = "workspace 10";
"${modifier}+Shift+0" = "move container to workspace 10";
"Ctrl+Alt+l" = "exec ${lockCommand}";
}
// genKeyAttrs true
// genKeyAttrs false
);
menu = "${config.programs.rofi.package}/bin/rofi -show drun -show-icons -run-command '${pkgs.sway}/bin/swaymsg exec -- {cmd}'";
bars = [];
gaps = {
smartGaps = lib.mkDefault true;
smartBorders = lib.mkDefault "on";
inner = lib.mkDefault 10;
outer = lib.mkDefault 0;
};
};
};
programs.firefox.enable = true;
programs.waybar = {
enable = lib.mkDefault true;
systemd = {
enable = lib.mkDefault true;
target = lib.mkDefault "sway-session.target";
};
settings.mainbar = let
weatherCommand = f: "${pkgs.curl}/bin/curl 'wttr.in/${cfg.location}?format=${f}' || echo 'ERR'";
weatherIf = "(${pkgs.curl}/bin/curl 'wttr.in/${cfg.location}?format=%t' || echo 'ERR') | grep -c 'ERR|Unknown'";
in {
position = lib.mkDefault "left";
height = lib.mkDefault null;
modules-left = ["sway/workspaces" "custom/weather-spacer" "custom/weather-temp" "custom/weather-precip" "custom/weather-wind"];
modules-center = ["clock#1" "clock#2" "custom/spacer" "custom/media" "custom/spacer" "clock#3" "custom/spacer" "clock#4"];
modules-right = ["pulseaudio" "custom/spacer" "memory" "custom/spacer" "cpu"] ++ lib.optionals cfg.battery ["custom/spacer" "battery"] ++ ["custom/spacer" "tray"];
"custom/spacer" = {
format = lib.mkDefault "";
rotate = lib.mkDefault 90;
tooltip = lib.mkDefault false;
};
"custom/weather-spacer" = {
exec-if = weatherIf;
format = lib.mkDefault "";
rotate = lib.mkDefault 90;
tooltip = lib.mkDefault false;
};
"custom/weather-temp" = {
exec = lib.mkDefault (weatherCommand "%t+%c");
exec-if = weatherIf;
on-click = lib.mkDefault "${pkgs.xdg-utils}/bin/xdg-open 'https://weather.com/weather/today/l/85625'";
on-click-right = lib.mkDefault "${pkgs.xdg-utils}/bin/xdg-open 'https://wttr.in/${cfg.location}'";
interval = lib.mkDefault 900;
};
"custom/weather-precip" = {
exec = lib.mkDefault (weatherCommand "🌧+%p");
exec-if = weatherIf;
on-click = lib.mkDefault "${pkgs.xdg-utils}/bin/xdg-open 'https://www.lightningmaps.org/'";
on-click-right = "lib.mkDefault ${pkgs.xdg-utils}/bin/xdg-open 'https://wttr.in/${cfg.location}'";
interval = lib.mkDefault 900;
};
"custom/weather-wind" = {
exec = lib.mkDefault (weatherCommand "🌬+%w");
exec-if = weatherIf;
on-click = lib.mkDefault "${pkgs.xdg-utils}/bin/xdg-open 'https://www.ventusky.com/";
on-click-right = lib.mkDefault "${pkgs.xdg-utils}/bin/xdg-open 'https://wttr.in/${cfg.location}'";
interval = lib.mkDefault 900;
};
"custom/media" = {
rotate = lib.mkDefault 90;
max-length = lib.mkDefault 60;
on-click = lib.mkDefault "${pkgs.playerctl}/bin/playerctl play-pause";
exec = lib.mkDefault "${pkgs.playerctl}/bin/playerctl metadata --format '{{ emoji(status) }} {{ artist }} - {{ title }}' --follow";
};
"sway/workspaces" = {
disable-scroll = lib.mkDefault true;
};
"clock#1" = {
tooltip = lib.mkDefault false;
format = lib.mkDefault "{:%a}";
};
"clock#2" = {
tooltip = lib.mkDefault false;
format = lib.mkDefault "{:%m-%d}";
};
"clock#3" = {
tooltip = lib.mkDefault false;
format = lib.mkDefault "{:%I:%M %p}";
};
"clock#4" = {
tooltip = lib.mkDefault false;
timezone = lib.mkDefault "Etc/UTC";
format = lib.mkDefault "{:%H:%M} UTC";
};
pulseaudio = {
format = lib.mkDefault "{icon} {volume}%";
format-bluetooth = lib.mkDefault "{icon} {volume}%";
format-muted = lib.mkDefault "MUTE";
format-icons = {
headphone = lib.mkDefault "";
default = lib.mkDefault "";
};
on-click = lib.mkDefault "${pkgs.pulseaudio}/bin/pactl set-source-mute @DEFAULT_SOURCE@ toggle";
on-click-right = lib.mkDefault "${pkgs.pavucontrol}/bin/pavucontrol";
};
memory = {
interval = lib.mkDefault 20;
format = lib.mkDefault " {}%";
};
cpu = {
interval = lib.mkDefault 20;
format = lib.mkDefault " {usage}%";
};
battery = {
states = {
good = lib.mkDefault 90;
warning = lib.mkDefault 25;
critical = lib.mkDefault 10;
};
format = lib.mkDefault "{icon} {capacity}%";
format-icons = ["" "" "" "" "" "" "" "" "" ""];
};
tray = {
icon-size = lib.mkDefault 18;
spacing = lib.mkDefault 5;
};
};
style = ''
window#waybar {
background: #${config.ezcolors.base16.base01};
color: #${config.ezcolors.base16.base06};
}
#custom-spacer {
font-size: 20px;
color: #${config.ezcolors.base16.base00};
font-weight: bold;
}
#workspaces,
#clock.1,
#clock.2,
#clock.3,
#clock.4,
#pulseaudio,
#memory,
#cpu,
#battery,
#disk,
#tray,
#mode,
#custom-weather-temp,
#custom-weather-precip,
#custom-weather-wind,
#custom-media {
color: #${config.ezcolors.base16.base06};
font-size: ${toString (config.ezfonts.font.size + 1)}px;
background: #${config.ezcolors.base16.base00};
padding: 5px 0;
}
#workspaces { padding: 0 }
#clock.1 { padding: 5px 0 0 0; }
#clock.2 { padding: 0 0 5px 0; }
#custom-weather-temp { padding: 5px 0 0 0; }
#custom-weather-precip { padding: 5px 0; }
#custom-weather-wind { padding: 0 0 5px 0; }
#custom-media.playing {
color: #${config.ezcolors.base16.base0A};
}
#workspaces button.focused {
color: #${config.ezcolors.base16.base0A};
}
#workspaces button:hover {
background: #${config.ezcolors.base16.base02};
}
#pulseaudio {
color: #${config.ezcolors.base16.base0B};
}
#memory {
color: #${config.ezcolors.base16.base0C};
}
#cpu {
color: #${config.ezcolors.base16.base0D};
}
#battery {
color: #${config.ezcolors.base16.base0E};
}
* {
font-family: "${config.ezfonts.font.name}";
border-radius: 0;
border-width: 0;
border-style: none;
margin: 0;
padding: 0;
}
'';
};
programs.mako = {
enable = lib.mkDefault true;
maxVisible = lib.mkDefault 6;
extraConfig = lib.generators.toKeyValue {} {
on-button-middle = "dismiss-all";
};
};
systemd.user.services.mako = {
Service = {
ExecStart = "${pkgs.mako}/bin/mako";
};
Install = {
After = ["sway-session.target"];
WantedBy = ["sway-session.target"];
};
};
ezcolors.enable = lib.mkDefault true;
ezfonts.enable = lib.mkDefault true;
services.blueman-applet.enable = lib.mkDefault cfg.bluetooth;
services.mpris-proxy.enable = lib.mkDefault true;
services.mopidy = {
enable = lib.mkDefault true;
extensionPackages = with pkgs; [
mopidy-youtube
mopidy-local
mopidy-mpd
];
settings = {
youtube = {
enabled = lib.mkDefault true;
allow_cache = lib.mkDefault true;
};
file = {
media_dirs = lib.mkDefault "${config.home.homeDirectory}/Music";
};
local = {
enabled = lib.mkDefault true;
media_dir = lib.mkDefault "${config.home.homeDirectory}/Music";
};
mpd = {
enabled = lib.mkDefault true;
# hostname = lib.mkDefault "::";
# command_blacklist = lib.mkDefault "";
};
};
};
services.playerctld.enable = lib.mkDefault true;
gtk = {
enable = lib.mkDefault true;
iconTheme = {
package = lib.mkDefault cfg.favIcons.package;
name = lib.mkDefault cfg.favIcons.name;
};
};
qt = {
enable = lib.mkDefault true;
platformTheme = lib.mkDefault "gtk";
};
programs.kermit = {
enable = lib.mkDefault true;
settings = {
opacity = lib.mkDefault "0.90";
key = lib.mkDefault "shift";
};
};
xdg.enable = true;
xdg.userDirs.enable = true;
xdg.configFile."mimeapps.list".force = true;
xdg.mimeApps = let
applications = {
"inode/directory" = "pcmanfm-qt.desktop";
"text/html" = "librewolf.desktop";
"x-scheme-handler/http" = "librewolf.desktop";
"x-scheme-handler/https" = "librewolf.desktop";
"x-scheme-handler/about" = "librewolf.desktop";
"application/zip" = "ark.desktop";
"application/rar" = "ark.desktop";
"application/7z" = "ark.desktop";
"application/*tar" = "ark.desktop";
};
in {
enable = true;
associations.added = applications;
defaultApplications = applications;
};
programs.mpv.enable = lib.mkDefault true;
fonts.fontconfig.enable = lib.mkDefault true;
home.packages = with pkgs; [
wl-clipboard
wtype
ydotool
keyutils
# ezpcusr stuff
ezDrv
inputs.mudl.defaultPackage.${pkgs.system}
# programs
pavucontrol
ark
pcmanfm-qt
# CLI tools
yt-dlp
maim
slop
# CLI tools that integrate with ezpcusr things
mpc_cli
playerctl
xorg.xhost
];
programs.rofi = {
enable = lib.mkDefault true;
package = pkgs.rofi-wayland;
terminal = lib.mkDefault "${pkgs.kermit-terminal}/bin/kermit";
};
};
}