Sync CMUX environment through tmux automatically
This commit is contained in:
parent
c325e2b49d
commit
5e9a58d1d0
2 changed files with 217 additions and 0 deletions
|
|
@ -54,6 +54,111 @@ _CMUX_PORTS_LAST_RUN="${_CMUX_PORTS_LAST_RUN:-0}"
|
|||
_CMUX_SHELL_ACTIVITY_LAST="${_CMUX_SHELL_ACTIVITY_LAST:-}"
|
||||
_CMUX_TTY_NAME="${_CMUX_TTY_NAME:-}"
|
||||
_CMUX_TTY_REPORTED="${_CMUX_TTY_REPORTED:-0}"
|
||||
_CMUX_TMUX_PUSH_SIGNATURE="${_CMUX_TMUX_PUSH_SIGNATURE:-}"
|
||||
_CMUX_TMUX_PULL_SIGNATURE="${_CMUX_TMUX_PULL_SIGNATURE:-}"
|
||||
_CMUX_TMUX_SYNC_KEYS=(
|
||||
CMUX_BUNDLED_CLI_PATH
|
||||
CMUX_BUNDLE_ID
|
||||
CMUXD_UNIX_PATH
|
||||
CMUXTERM_REPO_ROOT
|
||||
CMUX_DEBUG_LOG
|
||||
CMUX_LOAD_GHOSTTY_ZSH_INTEGRATION
|
||||
CMUX_PANEL_ID
|
||||
CMUX_PORT
|
||||
CMUX_PORT_END
|
||||
CMUX_PORT_RANGE
|
||||
CMUX_REMOTE_DAEMON_ALLOW_LOCAL_BUILD
|
||||
CMUX_SHELL_INTEGRATION
|
||||
CMUX_SHELL_INTEGRATION_DIR
|
||||
CMUX_SOCKET_ENABLE
|
||||
CMUX_SOCKET_MODE
|
||||
CMUX_SOCKET_PATH
|
||||
CMUX_SURFACE_ID
|
||||
CMUX_TAB_ID
|
||||
CMUX_TAG
|
||||
CMUX_WORKSPACE_ID
|
||||
)
|
||||
|
||||
_cmux_tmux_shell_env_signature() {
|
||||
local key value first=1
|
||||
for key in "${_CMUX_TMUX_SYNC_KEYS[@]}"; do
|
||||
value="${!key}"
|
||||
[[ -n "$value" ]] || continue
|
||||
if (( first )); then
|
||||
printf '%s=%s' "$key" "$value"
|
||||
first=0
|
||||
else
|
||||
printf '\037%s=%s' "$key" "$value"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
_cmux_tmux_publish_cmux_environment() {
|
||||
[[ -z "$TMUX" ]] || return 0
|
||||
command -v tmux >/dev/null 2>&1 || return 0
|
||||
|
||||
local signature
|
||||
signature="$(_cmux_tmux_shell_env_signature)"
|
||||
[[ -n "$signature" ]] || return 0
|
||||
[[ "$signature" == "$_CMUX_TMUX_PUSH_SIGNATURE" ]] && return 0
|
||||
|
||||
local key value
|
||||
for key in "${_CMUX_TMUX_SYNC_KEYS[@]}"; do
|
||||
value="${!key}"
|
||||
[[ -n "$value" ]] || continue
|
||||
tmux set-environment -g "$key" "$value" >/dev/null 2>&1 || return 0
|
||||
done
|
||||
|
||||
_CMUX_TMUX_PUSH_SIGNATURE="$signature"
|
||||
}
|
||||
|
||||
_cmux_tmux_refresh_cmux_environment() {
|
||||
[[ -n "$TMUX" ]] || return 0
|
||||
command -v tmux >/dev/null 2>&1 || return 0
|
||||
|
||||
local output filtered line key value did_change=0
|
||||
output="$(tmux show-environment -g 2>/dev/null)" || return 0
|
||||
|
||||
while IFS= read -r line; do
|
||||
[[ "$line" == CMUX_* ]] || continue
|
||||
filtered+="${line}"$'\n'
|
||||
done <<< "$output"
|
||||
|
||||
[[ -n "$filtered" ]] || return 0
|
||||
[[ "$filtered" == "$_CMUX_TMUX_PULL_SIGNATURE" ]] && return 0
|
||||
|
||||
while IFS= read -r line; do
|
||||
[[ "$line" == CMUX_* ]] || continue
|
||||
key="${line%%=*}"
|
||||
value="${line#*=}"
|
||||
if [[ "${!key}" != "$value" ]]; then
|
||||
printf -v "$key" '%s' "$value"
|
||||
export "$key"
|
||||
did_change=1
|
||||
fi
|
||||
done <<< "$filtered"
|
||||
|
||||
_CMUX_TMUX_PULL_SIGNATURE="$filtered"
|
||||
if (( did_change )); then
|
||||
_CMUX_TTY_REPORTED=0
|
||||
_CMUX_SHELL_ACTIVITY_LAST=""
|
||||
_CMUX_PWD_LAST_PWD=""
|
||||
_CMUX_GIT_LAST_PWD=""
|
||||
_CMUX_GIT_HEAD_LAST_PWD=""
|
||||
_CMUX_GIT_HEAD_PATH=""
|
||||
_CMUX_GIT_HEAD_SIGNATURE=""
|
||||
_CMUX_PR_FORCE=1
|
||||
_cmux_stop_pr_poll_loop
|
||||
fi
|
||||
}
|
||||
|
||||
_cmux_tmux_sync_cmux_environment() {
|
||||
if [[ -n "$TMUX" ]]; then
|
||||
_cmux_tmux_refresh_cmux_environment
|
||||
else
|
||||
_cmux_tmux_publish_cmux_environment
|
||||
fi
|
||||
}
|
||||
|
||||
_cmux_git_resolve_head_path() {
|
||||
# Resolve the HEAD file path without invoking git (fast; works for worktrees).
|
||||
|
|
@ -348,6 +453,8 @@ _cmux_bash_cleanup() {
|
|||
}
|
||||
|
||||
_cmux_preexec_command() {
|
||||
_cmux_tmux_sync_cmux_environment
|
||||
|
||||
[[ -S "$CMUX_SOCKET_PATH" ]] || return 0
|
||||
[[ -n "$CMUX_TAB_ID" ]] || return 0
|
||||
[[ -n "$CMUX_PANEL_ID" ]] || return 0
|
||||
|
|
@ -370,6 +477,8 @@ _cmux_bash_preexec_hook() {
|
|||
}
|
||||
|
||||
_cmux_prompt_command() {
|
||||
_cmux_tmux_sync_cmux_environment
|
||||
|
||||
[[ -S "$CMUX_SOCKET_PATH" ]] || return 0
|
||||
[[ -n "$CMUX_TAB_ID" ]] || return 0
|
||||
[[ -n "$CMUX_PANEL_ID" ]] || return 0
|
||||
|
|
|
|||
|
|
@ -60,6 +60,111 @@ typeset -g _CMUX_TTY_NAME=""
|
|||
typeset -g _CMUX_TTY_REPORTED=0
|
||||
typeset -g _CMUX_GHOSTTY_SEMANTIC_PATCHED=0
|
||||
typeset -g _CMUX_WINCH_GUARD_INSTALLED=0
|
||||
typeset -g _CMUX_TMUX_PUSH_SIGNATURE=""
|
||||
typeset -g _CMUX_TMUX_PULL_SIGNATURE=""
|
||||
typeset -ga _CMUX_TMUX_SYNC_KEYS=(
|
||||
CMUX_BUNDLED_CLI_PATH
|
||||
CMUX_BUNDLE_ID
|
||||
CMUXD_UNIX_PATH
|
||||
CMUXTERM_REPO_ROOT
|
||||
CMUX_DEBUG_LOG
|
||||
CMUX_LOAD_GHOSTTY_ZSH_INTEGRATION
|
||||
CMUX_PANEL_ID
|
||||
CMUX_PORT
|
||||
CMUX_PORT_END
|
||||
CMUX_PORT_RANGE
|
||||
CMUX_REMOTE_DAEMON_ALLOW_LOCAL_BUILD
|
||||
CMUX_SHELL_INTEGRATION
|
||||
CMUX_SHELL_INTEGRATION_DIR
|
||||
CMUX_SOCKET_ENABLE
|
||||
CMUX_SOCKET_MODE
|
||||
CMUX_SOCKET_PATH
|
||||
CMUX_SURFACE_ID
|
||||
CMUX_TAB_ID
|
||||
CMUX_TAG
|
||||
CMUX_WORKSPACE_ID
|
||||
)
|
||||
|
||||
_cmux_tmux_shell_env_signature() {
|
||||
local key value
|
||||
local -a parts
|
||||
for key in "${_CMUX_TMUX_SYNC_KEYS[@]}"; do
|
||||
value="${(P)key}"
|
||||
[[ -n "$value" ]] || continue
|
||||
parts+=("${key}=${value}")
|
||||
done
|
||||
print -r -- "${(j:\x1f:)parts}"
|
||||
}
|
||||
|
||||
_cmux_tmux_publish_cmux_environment() {
|
||||
[[ -z "$TMUX" ]] || return 0
|
||||
command -v tmux >/dev/null 2>&1 || return 0
|
||||
|
||||
local signature
|
||||
signature="$(_cmux_tmux_shell_env_signature)"
|
||||
[[ -n "$signature" ]] || return 0
|
||||
[[ "$signature" == "$_CMUX_TMUX_PUSH_SIGNATURE" ]] && return 0
|
||||
|
||||
local key value
|
||||
for key in "${_CMUX_TMUX_SYNC_KEYS[@]}"; do
|
||||
value="${(P)key}"
|
||||
[[ -n "$value" ]] || continue
|
||||
tmux set-environment -g "$key" "$value" >/dev/null 2>&1 || return 0
|
||||
done
|
||||
|
||||
_CMUX_TMUX_PUSH_SIGNATURE="$signature"
|
||||
}
|
||||
|
||||
_cmux_tmux_refresh_cmux_environment() {
|
||||
[[ -n "$TMUX" ]] || return 0
|
||||
command -v tmux >/dev/null 2>&1 || return 0
|
||||
|
||||
local output
|
||||
output="$(tmux show-environment -g 2>/dev/null)" || return 0
|
||||
|
||||
local line filtered="" did_change=0
|
||||
while IFS= read -r line; do
|
||||
[[ "$line" == CMUX_* ]] || continue
|
||||
filtered+="${line}"$'\n'
|
||||
done <<< "$output"
|
||||
|
||||
[[ -n "$filtered" ]] || return 0
|
||||
[[ "$filtered" == "$_CMUX_TMUX_PULL_SIGNATURE" ]] && return 0
|
||||
|
||||
local key value
|
||||
while IFS= read -r line; do
|
||||
[[ "$line" == CMUX_* ]] || continue
|
||||
key="${line%%=*}"
|
||||
value="${line#*=}"
|
||||
if [[ "${(P)key}" != "$value" ]]; then
|
||||
export "$key=$value"
|
||||
did_change=1
|
||||
fi
|
||||
done <<< "$filtered"
|
||||
|
||||
_CMUX_TMUX_PULL_SIGNATURE="$filtered"
|
||||
if (( did_change )); then
|
||||
_CMUX_TTY_REPORTED=0
|
||||
_CMUX_SHELL_ACTIVITY_LAST=""
|
||||
_CMUX_PWD_LAST_PWD=""
|
||||
_CMUX_GIT_LAST_PWD=""
|
||||
_CMUX_GIT_HEAD_LAST_PWD=""
|
||||
_CMUX_GIT_HEAD_PATH=""
|
||||
_CMUX_GIT_HEAD_SIGNATURE=""
|
||||
_CMUX_GIT_FORCE=1
|
||||
_CMUX_PR_FORCE=1
|
||||
_cmux_stop_pr_poll_loop
|
||||
_cmux_stop_git_head_watch
|
||||
fi
|
||||
}
|
||||
|
||||
_cmux_tmux_sync_cmux_environment() {
|
||||
if [[ -n "$TMUX" ]]; then
|
||||
_cmux_tmux_refresh_cmux_environment
|
||||
else
|
||||
_cmux_tmux_publish_cmux_environment
|
||||
fi
|
||||
}
|
||||
|
||||
_cmux_ensure_ghostty_preexec_strips_both_marks() {
|
||||
local fn_name="$1"
|
||||
|
|
@ -506,6 +611,8 @@ _cmux_start_git_head_watch() {
|
|||
}
|
||||
|
||||
_cmux_preexec() {
|
||||
_cmux_tmux_sync_cmux_environment
|
||||
|
||||
if [[ -z "$_CMUX_TTY_NAME" ]]; then
|
||||
local t
|
||||
t="$(tty 2>/dev/null || true)"
|
||||
|
|
@ -533,6 +640,7 @@ _cmux_preexec() {
|
|||
|
||||
_cmux_precmd() {
|
||||
_cmux_stop_git_head_watch
|
||||
_cmux_tmux_sync_cmux_environment
|
||||
|
||||
# Skip if socket doesn't exist yet
|
||||
[[ -S "$CMUX_SOCKET_PATH" ]] || return 0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue