sway smart term fix
This commit is contained in:
@@ -1,25 +1,109 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Opens a new terminal, using the current terminal's working directory if focused window is a terminal
|
# Opens a new terminal, using the current terminal's working directory if focused window is a terminal
|
||||||
|
# Defaults to home directory (~) if no terminal is focused
|
||||||
|
|
||||||
|
# Parse file URI to extract path
|
||||||
|
parse_file_uri() {
|
||||||
|
local uri="$1"
|
||||||
|
|
||||||
|
# Remove file:// prefix
|
||||||
|
local path="${uri#file://}"
|
||||||
|
|
||||||
|
# Handle localhost or hostname prefix: file://hostname/path -> /path
|
||||||
|
if [[ "$path" =~ ^localhost(/.*) ]] || [[ "$path" =~ ^[a-zA-Z0-9.-]+(/.*) ]]; then
|
||||||
|
path="${BASH_REMATCH[1]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$path"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Try to get cwd from focused wezterm window
|
||||||
|
# Arguments: window_title from Sway's focused window
|
||||||
|
get_wezterm_cwd() {
|
||||||
|
local sway_window_title="$1"
|
||||||
|
|
||||||
|
# Check if wezterm is available
|
||||||
|
if ! command -v wezterm &> /dev/null; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get list of wezterm windows/panes
|
||||||
|
local wezterm_data
|
||||||
|
wezterm_data=$(wezterm cli list --format json 2>/dev/null) || return 1
|
||||||
|
|
||||||
|
# Return early if no data
|
||||||
|
if [ -z "$wezterm_data" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
local cwd
|
||||||
|
|
||||||
|
# Try to match the Sway window title with wezterm's window_title first
|
||||||
|
# (this handles windows with explicit titles set)
|
||||||
|
if [ -n "$sway_window_title" ] && [ "$sway_window_title" != "null" ]; then
|
||||||
|
cwd=$(echo "$wezterm_data" | jq -r --arg title "$sway_window_title" '.[] | select(.window_title == $title) | .cwd' | head -n 1)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If no match by window_title, try matching by pane title
|
||||||
|
# When multiple matches exist, pick the highest window_id (most recent)
|
||||||
|
if [ -z "$cwd" ] || [ "$cwd" = "null" ]; then
|
||||||
|
cwd=$(echo "$wezterm_data" | jq -r --arg title "$sway_window_title" '[.[] | select(.title == $title)] | sort_by(.window_id) | .[-1] | .cwd' 2>/dev/null)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If the Sway window title looks like an app (nvim, vim, pi, claude, etc),
|
||||||
|
# look for the pane with a visible cursor (likely the active app)
|
||||||
|
if [ -z "$cwd" ] || [ "$cwd" = "null" ]; then
|
||||||
|
local app_pattern="nvim|vim|pi|claude|less|more|man|htop|top|nano|emacs"
|
||||||
|
if [[ "$sway_window_title" =~ ^($app_pattern) ]]; then
|
||||||
|
# Try to find a pane with visible cursor (most likely the active one)
|
||||||
|
cwd=$(echo "$wezterm_data" | jq -r '.[] | select(.cursor_visibility == "Visible") | .cwd' | head -n 1)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Final fallback: just get most recent pane with valid cwd
|
||||||
|
if [ -z "$cwd" ] || [ "$cwd" = "null" ]; then
|
||||||
|
cwd=$(echo "$wezterm_data" | jq -r '[.[] | select(.cwd != null and .cwd != "")] | sort_by(.window_id) | .[-1] | .cwd' 2>/dev/null)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If still nothing, fail
|
||||||
|
if [ -z "$cwd" ] || [ "$cwd" = "null" ]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Parse the URI if needed
|
||||||
|
if [[ "$cwd" == file://* ]]; then
|
||||||
|
cwd=$(parse_file_uri "$cwd")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify path exists
|
||||||
|
if [ -d "$cwd" ]; then
|
||||||
|
echo "$cwd"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main logic
|
||||||
|
cwd=""
|
||||||
|
|
||||||
# Get focused window info from Sway
|
# Get focused window info from Sway
|
||||||
focused_info=$(swaymsg -t get_tree | jq -r '.. | select(.focused? == true) | {app_id: .app_id, name: .name}')
|
if command -v swaymsg &> /dev/null; then
|
||||||
app_id=$(echo "$focused_info" | jq -r '.app_id')
|
focused_window=$(swaymsg -t get_tree 2>/dev/null | jq -r '.. | select(.focused? == true and .app_id? != null) | [.app_id, .name] | @tsv' | head -n 1)
|
||||||
window_name=$(echo "$focused_info" | jq -r '.name')
|
|
||||||
|
|
||||||
if [ "$app_id" = "org.wezfurlong.wezterm" ]; then
|
# Parse tab-separated values
|
||||||
# Match the Sway window title with wezterm's window_title to get the correct pane's cwd
|
app_id=$(echo "$focused_window" | cut -f1)
|
||||||
cwd=$(wezterm cli list --format json 2>/dev/null | jq -r --arg title "$window_name" '.[] | select(.window_title == $title) | .cwd' | head -n 1)
|
window_name=$(echo "$focused_window" | cut -f2)
|
||||||
|
|
||||||
if [ -n "$cwd" ] && [ "$cwd" != "null" ]; then
|
# Check if focused window is wezterm (app_id contains "wez")
|
||||||
# Remove file:// prefix and hostname (format: file://hostname/path)
|
if [ -n "$app_id" ] && [[ "$app_id" == *"wez"* ]]; then
|
||||||
cwd=$(echo "$cwd" | sed 's|^file://[^/]*/|/|')
|
cwd=$(get_wezterm_cwd "$window_name")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -d "$cwd" ]; then
|
# Open terminal with cwd if we found one, otherwise default to home
|
||||||
|
if [ -n "$cwd" ] && [ -d "$cwd" ]; then
|
||||||
wezterm start --cwd "$cwd" &
|
wezterm start --cwd "$cwd" &
|
||||||
exit 0
|
else
|
||||||
|
wezterm start --cwd "$HOME" &
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Fallback: open terminal in home directory
|
|
||||||
wezterm &
|
|
||||||
|
|||||||
Reference in New Issue
Block a user