aboutsummaryrefslogtreecommitdiff
path: root/dot_config/hypr/scripts/executable_herdr-smart-nav
diff options
context:
space:
mode:
authorpablu <me@pablu.de>2026-09-17 17:05:03 +0200
committerpablu <me@pablu.de>2026-09-17 17:05:03 +0200
commitf8312a59c775c740d9af173fafa65ab7e731e03e (patch)
treea54a9274376f20bbb35f07bccfeab8aef542fa0e /dot_config/hypr/scripts/executable_herdr-smart-nav
parent0716da5eef605977b804f34f265979cf39be844b (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_herdr-smart-nav')
-rw-r--r--dot_config/hypr/scripts/executable_herdr-smart-nav143
1 files changed, 143 insertions, 0 deletions
diff --git a/dot_config/hypr/scripts/executable_herdr-smart-nav b/dot_config/hypr/scripts/executable_herdr-smart-nav
new file mode 100644
index 0000000..36d27aa
--- /dev/null
+++ b/dot_config/hypr/scripts/executable_herdr-smart-nav
@@ -0,0 +1,143 @@
+#!/usr/bin/env bash
+
+set -u
+
+direction="${1:-}"
+terminal_pid="${2:-}"
+
+case "$direction" in
+ left|right|up|down)
+ ;;
+ *)
+ printf 'usage: %s <left|right|up|down> <terminal-pid>\n' "$0" >&2
+ exit 2
+ ;;
+esac
+
+# Window titles can change with the workspace. Find a foreground Herdr
+# process belonging to this terminal instead of relying on its title.
+is_in_terminal() {
+ local pid="$1"
+ local parent
+
+ while [[ "$pid" =~ ^[0-9]+$ && "$pid" -gt 1 ]]; do
+ [[ "$pid" == "$terminal_pid" ]] && return 0
+ parent="$(ps -o ppid= -p "$pid" 2>/dev/null | tr -d '[:space:]')"
+ [[ -n "$parent" && "$parent" != "$pid" ]] || return 1
+ pid="$parent"
+ done
+
+ return 1
+}
+
+herdr_found=false
+if [[ "$terminal_pid" =~ ^[0-9]+$ ]]; then
+ while read -r pid process_group foreground_group; do
+ # The server has no foreground terminal; a suspended client is not active.
+ if [[ "$foreground_group" -gt 0 && "$process_group" == "$foreground_group" ]] &&
+ is_in_terminal "$pid"; then
+ herdr_found=true
+ break
+ fi
+ done < <(ps -C herdr -o pid=,pgid=,tpgid= 2>/dev/null)
+fi
+
+if [[ "$herdr_found" != true ]]; then
+ printf 'not-herdr\n'
+ exit
+fi
+
+herdr_bin="${HERDR_BIN_PATH:-$HOME/.local/share/mise/installs/herdr/latest/herdr}"
+
+if [[ ! -x "$herdr_bin" ]]; then
+ printf 'hyprland\n'
+ exit
+fi
+
+handled() {
+ printf 'handled\n'
+ exit
+}
+
+fall_through() {
+ printf 'hyprland\n'
+ exit
+}
+
+current="$("$herdr_bin" pane current --current 2>/dev/null)" || {
+ fall_through
+}
+
+pane_id="$(jq -r '.result.pane.pane_id // empty' <<<"$current")"
+
+if [[ -z "$pane_id" ]]; then
+ fall_through
+fi
+
+process_info="$(
+ "$herdr_bin" pane process-info --pane "$pane_id" 2>/dev/null || true
+)"
+
+nvim_pid="$(
+ jq -r '
+ [
+ (.result.process_info.foreground_processes // [])[]
+ | select(
+ ((.name // "") | ascii_downcase) == "nvim"
+ or ((.name // "") | ascii_downcase) == "vim"
+ )
+ | .pid
+ ][0] // empty
+ ' <<<"$process_info" 2>/dev/null
+)"
+
+if [[ -n "$nvim_pid" ]]; then
+ safe_pane_id="${pane_id//[^a-zA-Z0-9_.-]/_}"
+ runtime_dir="${XDG_RUNTIME_DIR:-/tmp}"
+
+ socket_path="$runtime_dir/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
+ handled
+ fi
+fi
+
+neighbor="$(
+ "$herdr_bin" pane neighbor \
+ --pane "$pane_id" \
+ --direction "$direction" \
+ 2>/dev/null
+)" || {
+ fall_through
+}
+
+# A zoomed pane deliberately falls through to Hyprland. Do not expose or
+# navigate to another Herdr pane.
+if jq -e '.result.neighbor.layout.zoomed == true' \
+ >/dev/null 2>&1 <<<"$neighbor"; then
+ fall_through
+fi
+
+neighbor_id="$(
+ jq -r '.result.neighbor.neighbor_pane_id // empty' <<<"$neighbor"
+)"
+
+# Herdr 0.7.5 returns the current pane itself when there is no neighbour.
+if [[ -z "$neighbor_id" || "$neighbor_id" == "$pane_id" ]]; then
+ fall_through
+fi
+
+if "$herdr_bin" pane focus \
+ --pane "$pane_id" \
+ --direction "$direction" \
+ >/dev/null 2>&1; then
+ handled
+else
+ fall_through
+fi