diff --git a/devshell.toml b/devshell.toml index 8012e7d3..dfa61285 100644 --- a/devshell.toml +++ b/devshell.toml @@ -60,3 +60,11 @@ help = "golang linter" name = "golangci-lint" package = "golangci-lint" category = "linters" + +[[commands]] +name = "hello-loop" +command = "while true; do hello; sleep 1; done" + +[[services]] +name = "hello-printer" +command = "hello-loop" diff --git a/mkDevShell/default.nix b/mkDevShell/default.nix index 235bce03..f68922b4 100644 --- a/mkDevShell/default.nix +++ b/mkDevShell/default.nix @@ -39,6 +39,7 @@ let inherit (config) bash commands + services env motd name @@ -57,9 +58,41 @@ let (writeShellScriptBin name (toString command)) ]; in - (builtins.concatMap op commands) ++ packages; + (builtins.concatMap op commands) ++ packages ++ [ serviceViewer ]; }; + sessionName = "${name}-sessions"; + serviceRunner = let + makeService = service: '' + echo "Starting service ${service.name}" + ${pkgs.tmux}/bin/tmux new-window -n '${service.name}' -t '${sessionName}' '${service.command}' + ''; + in pkgs.writeShellScript "service-runner" '' + # In case user is running multiple terminals with the same devshell + ${pkgs.tmux}/bin/tmux list-sessions | grep '^${sessionName}: ' && exit 0 + + ${pkgs.tmux}/bin/tmux new-session -d -s '${sessionName}' + ${lib.strings.concatStringsSep + "\n" + (map + makeService + services + ) + } + ''; + serviceViewer = writeShellScriptBin "service-viewer" '' + serviceName="$1" + case "$serviceName" in + ${lib.strings.concatStrings (map (service: "${service.name})\n;;\n") services)} + *) + echo "Invalid service name. Choose one of ${lib.strings.concatStringsSep "\n" (map (service: service.name) services)}" + exit 1 + ;; + esac + + ${pkgs.tmux}/bin/tmux select-window -t '${sessionName}':"$serviceName" \; a -t '${sessionName}' + ''; + # write a bash profile to load bashrc = writeText "${name}-bashrc" '' # Set all the passed environment variables @@ -73,6 +106,13 @@ let # Expose the path to nixpkgs export NIXPKGS_PATH=${toString pkgs.path} + function stopServices { + echo "Cleaning up services" + ${pkgs.tmux}/bin/tmux kill-session -t '${sessionName}' + } + trap stopServices EXIT + ${serviceRunner} + # Load installed profiles for file in "$DEVSHELL_DIR/etc/profile.d/"*.sh; do # If that folder doesn't exist, bash loves to return the whole glob diff --git a/mkDevShell/options.nix b/mkDevShell/options.nix index 0e74f095..a991dc7e 100644 --- a/mkDevShell/options.nix +++ b/mkDevShell/options.nix @@ -112,6 +112,15 @@ let ''; }; }; + + serviceOptions = { + name = mkOption { + type = types.str; + }; + command = mkOption { + type = types.str; + }; + }; in { options = { @@ -160,6 +169,11 @@ in ''; }; + services = mkOption { + type = types.listOf (types.submodule { options = serviceOptions; }); + default = [ ]; + }; + bash = mkOption { type = types.submodule { options = {