diff --git a/flake.lock b/flake.lock index c0cc575..04de495 100644 --- a/flake.lock +++ b/flake.lock @@ -111,11 +111,11 @@ ] }, "locked": { - "lastModified": 1783134515, - "narHash": "sha256-qMoZazubXlXUD9k/syJ/aiWC4X4g73mwVmZ7Z4+rdpM=", + "lastModified": 1783963347, + "narHash": "sha256-r376E2XpakiXwModDHIxlvB6qLq4iFVEq730vxOO4JY=", "owner": "nix-community", "repo": "home-manager", - "rev": "b885baad531fa3d3beae2ba9a0712d22974d8016", + "rev": "a45a7c451455a51ae740ec3bce4024b312809c29", "type": "github" }, "original": { @@ -163,11 +163,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1782959384, - "narHash": "sha256-xnJJk+ct+D2+wdRxj1wk36w5zV9RVESwRqcklPdt3fM=", + "lastModified": 1783776592, + "narHash": "sha256-UgCQzxeWI75XM8G+hPrPh+MKzEPjG3SpAj7dtqSbksA=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "65179426c83bb3f6bc14898b42ea1c6f01d374b0", + "rev": "e7a3ca8092b61ff85b6a45bf863ea2b2d6a661b3", "type": "github" }, "original": { diff --git a/home/zsh/files/waypipe.zsh b/home/zsh/files/waypipe.zsh index 8a0af82..bc4a342 100644 --- a/home/zsh/files/waypipe.zsh +++ b/home/zsh/files/waypipe.zsh @@ -1,20 +1,47 @@ -if [ "$SSH_SESSION_ID" != "" ]; then - mkdir -p /tmp/ssh_sessions - echo $$ > /tmp/ssh_sessions/"$SSH_SESSION_ID" -fi - -if [ "$REMOTE_PATH" != "" ]; then - if [ -d "$REMOTE_PATH" ]; then - cd "$REMOTE_PATH" - fi -elif [ "$PREVIOUS_SESSION_ID" != "" ]; then - cd "$(readlink -e /proc/$(cat /tmp/ssh_sessions/$PREVIOUS_SESSION_ID)/cwd)" +if [ "$PREVIOUS_SESSION_ID" != "" ]; then + # Spawned as a new window/terminal for an existing remote session (by the + # niri/hyprland keybind). Inherit that session's working directory: find a + # live shell whose SSH_SESSION_ID (carried in its environment) matches and + # cd to its cwd. Then drop the hint so child shells don't keep jumping back. + _best_pid=0 + _prev_cwd="" + for _environ in /proc/[0-9]*/environ; do + _pid=${_environ%/environ} + _pid=${_pid#/proc/} + # cat (not a < redirect) so unreadable/ptrace-protected environ files + # fail quietly into the pipe instead of raising a shell error. + if cat "$_environ" 2>/dev/null | tr '\0' '\n' | grep -Fxq "SSH_SESSION_ID=$PREVIOUS_SESSION_ID"; then + [ "$(cat /proc/$_pid/comm 2>/dev/null)" = zsh ] || continue + _c=$(readlink -e /proc/$_pid/cwd 2>/dev/null) || continue + if [ -n "$_c" ] && [ "$_pid" -gt "$_best_pid" ]; then + _best_pid=$_pid + _prev_cwd=$_c + fi + fi + done + [ -n "$_prev_cwd" ] && cd "$_prev_cwd" + unset _best_pid _prev_cwd _environ _pid _c PREVIOUS_SESSION_ID fi function run_waypipe() { - SSH_SESSION_ID=$RANDOM - REMOTE_PATH=$(echo $(pwd) | sed "s|/home/[a-z]*|\$HOME|g") - SSH_SESSION_ID=$SSH_SESSION_ID waypipe -n ssh -t $1 env REMOTE_PATH=\"$REMOTE_PATH\" SSH_SESSION_ID=$SSH_SESSION_ID "zsh --login" + if [ -z "$1" ]; then + echo "usage: run_waypipe " >&2 + return 1 + fi + local SSH_SESSION_ID=$RANDOM REMOTE_PATH + # Map the current path relative to $HOME so it resolves to the remote user's + # home even when the username differs (the remote shell expands $HOME). + if [[ "$PWD" == "$HOME" || "$PWD" == "$HOME"/* ]]; then + REMOTE_PATH="\$HOME${PWD#$HOME}" + else + REMOTE_PATH="$PWD" + fi + # cd into the mirrored path before the interactive shell starts, so the cwd + # is never carried in an inherited env var (which would leak to every child + # shell and override the cwd of new zellij panes). SSH_SESSION_ID stays in + # the environment on purpose: it is the token the WM keybind above uses to + # locate this session's shells later. + waypipe -n ssh -t "$1" "cd \"$REMOTE_PATH\" 2>/dev/null; exec env SSH_SESSION_ID=$SSH_SESSION_ID zsh --login" } alias s='run_waypipe'