diff options
| author | pablu <me@pablu.de> | 2026-09-17 17:05:03 +0200 |
|---|---|---|
| committer | pablu <me@pablu.de> | 2026-09-17 17:05:03 +0200 |
| commit | f8312a59c775c740d9af173fafa65ab7e731e03e (patch) | |
| tree | a54a9274376f20bbb35f07bccfeab8aef542fa0e /dot_config/hypr/scripts/executable_tmux-smart-nav | |
| parent | 0716da5eef605977b804f34f265979cf39be844b (diff) | |
update codex config to not contain local project dirs, update .tmux.conf only for gentoo, make tmux work with hyprland
Diffstat (limited to 'dot_config/hypr/scripts/executable_tmux-smart-nav')
| -rw-r--r-- | dot_config/hypr/scripts/executable_tmux-smart-nav | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/dot_config/hypr/scripts/executable_tmux-smart-nav b/dot_config/hypr/scripts/executable_tmux-smart-nav new file mode 100644 index 0000000..4275462 --- /dev/null +++ b/dot_config/hypr/scripts/executable_tmux-smart-nav @@ -0,0 +1,105 @@ +#!/usr/bin/env bash + +set -u + +direction="${1:-}" +terminal_pid="${2:-}" + +case "$direction" in + left) + tmux_key="C-h" + ;; + right) + tmux_key="C-l" + ;; + up) + tmux_key="C-k" + ;; + down) + tmux_key="C-j" + ;; + *) + printf 'usage: %s <left|right|up|down> <terminal-pid>\n' "$0" >&2 + exit 2 + ;; +esac + +if [[ ! "$terminal_pid" =~ ^[0-9]+$ ]] || ! command -v tmux >/dev/null 2>&1; then + printf 'hyprland\n' + exit +fi + +# A tmux client is a descendant of the terminal process that owns it. This +# avoids acting on a client in another Ghostty window. +is_descendant_of() { + local pid="$1" + local parent + + while [[ "$pid" =~ ^[0-9]+$ && "$pid" -gt 1 ]]; do + if [[ "$pid" == "$terminal_pid" ]]; then + return 0 + fi + + parent="$(ps -o ppid= -p "$pid" 2>/dev/null | tr -d '[:space:]')" + [[ -n "$parent" && "$parent" != "$pid" ]] || return 1 + pid="$parent" + done + + return 1 +} + +client_tty="" +while read -r client_pid tty; do + if is_descendant_of "$client_pid"; then + client_tty="$tty" + break + fi +done < <(tmux list-clients -F '#{client_pid} #{client_tty}' 2>/dev/null) + +if [[ -z "$client_tty" ]]; then + printf 'hyprland\n' + exit +fi + +pane_id="$(tmux display-message -p -c "$client_tty" '#{pane_id}' 2>/dev/null)" +pane_command="$(tmux display-message -p -c "$client_tty" '#{pane_current_command}' 2>/dev/null)" + +# Ghostty has one title for the whole tmux window, so it cannot identify the +# focused pane's process. Ask Neovim through a pane-specific socket only when +# tmux says this exact pane is running it. +case "${pane_command,,}" in + nvim|vim) + safe_pane_id="${pane_id//[^a-zA-Z0-9_.-]/_}" + socket_path="${XDG_RUNTIME_DIR:-/tmp}/nvim-hypr-nav-pane-${safe_pane_id}.sock" + response="$( + printf 'nav:%s\n' "$direction" | + socat -T 0.25 -,ignoreeof "UNIX-CONNECT:$socket_path" 2>/dev/null || true + )" + + if [[ "$response" == *success* ]]; then + printf 'handled\n' + exit + fi + ;; +esac + +# Send the directional key through the matching client so tmux resolves it +# against that client's own active pane. Its existing C-h/j/k/l bindings also +# retain the configured Neovim handoff. +at_edge="$(tmux display-message -p -c "$client_tty" "#{pane_at_${direction}}" 2>/dev/null)" + +if [[ -z "$pane_id" || "$at_edge" == "1" ]]; then + printf 'hyprland\n' + exit +fi + +if tmux send-keys -c "$client_tty" -K "$tmux_key" >/dev/null 2>&1; then + selected_pane_id="$(tmux display-message -p -c "$client_tty" '#{pane_id}' 2>/dev/null)" + + if [[ "$selected_pane_id" != "$pane_id" ]]; then + printf 'handled\n' + exit + fi +fi + +printf 'hyprland\n' |
