diff --git a/README.md b/README.md index 9c4bc5b..48df5a8 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,12 @@ Replaces the `#H` format and adds a `#U` format option. ### Usage -- `#H` will be the hostname of your current path. If there is an ssh session opened, the ssh hostname will show instead of the local one. +- `#H` (`#{hostname}`) will be the hostname of your current path. If there is an ssh session opened, the ssh hostname will show instead of the local one. - `#{hostname_short}` will be the short hostname of your current path (up to the first dot). If there is an ssh session opened, the ssh hostname will show instead of the local one. -- `#U` will show the `whoami` result or the user that logged in an ssh session. +- `#U` (`#{username}`) will show the `whoami` result or the user that logged in an ssh session. - `#{pane_ssh_port}` if an open ssh session will show the connection port, otherwise it will be empty. - `#{pane_ssh_connected}` will be set to 1 if the currently selected pane has an active ssh connection. (Useful for `#{?#{pane_ssh_connected},ssh,no-ssh}` which will evaluate to `ssh` if there is an active ssh in the currently selected pane and `no-ssh` otherwise.) +- `#{pane_ssh_connect}` if an open ssh session will show the connection info in `"username@hostname:port"` format, otherwise it will be empty. Here's the example in `.tmux.conf`: diff --git a/current_pane_hostname.tmux b/current_pane_hostname.tmux index aa88cf2..49a92ab 100755 --- a/current_pane_hostname.tmux +++ b/current_pane_hostname.tmux @@ -2,22 +2,31 @@ CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -interpolation=('\#H' '\#{hostname_short}' '\#U' '\#\{pane_ssh_port\}' '\#\{pane_ssh_connected\}') -script=("#($CURRENT_DIR/scripts/hostname.sh)" "#($CURRENT_DIR/scripts/hostname_short.sh)" "#($CURRENT_DIR/scripts/whoami.sh)" "#($CURRENT_DIR/scripts/port.sh)" "#($CURRENT_DIR/scripts/pane_ssh_connected.sh)") +# Create map placeholders to handle scripts +# to provide one handler for multiple placeholders. +# Use '//' as separator, due to unix limitation in filenames +placeholders_to_scripts=( + "\#U//#($CURRENT_DIR/scripts/user.sh)" + "\#\{username\}//#($CURRENT_DIR/scripts/user.sh)" + "\#H//#($CURRENT_DIR/scripts/host.sh)" + "\#\{hostname\}//#($CURRENT_DIR/scripts/host.sh)" + "\#\{hostname_short\}//#($CURRENT_DIR/scripts/host_short.sh)" + "\#\{pane_ssh_port\}//#($CURRENT_DIR/scripts/port.sh)" + "\#\{pane_ssh_connected\}//#($CURRENT_DIR/scripts/pane_ssh_connected.sh)" + "\#\{pane_ssh_connect\}//#($CURRENT_DIR/scripts/pane_ssh_connect.sh)") source $CURRENT_DIR/scripts/shared.sh do_interpolation() { - local interpolated=$1 - local j=0 - - for i in "${interpolation[@]}"; do - local s=${script[$j]} - local interpolated=${interpolated//$i/$s} - ((j+=1)) - done - echo "$interpolated" + local interpolated=$1 + for assignment in ${placeholders_to_scripts[@]}; do + # ${assignment%\/\/*} - remove from // til EOL + # ${assignment#*\/\/} - remove from BOL til // + # ${interpolated//A/B} - replace all occurrences of A in interpolated with B + local interpolated=${interpolated//${assignment%\/\/*}/${assignment#*\/\/}} + done + echo "$interpolated" } update_tmux_option() { diff --git a/scripts/whoami.sh b/scripts/host.sh similarity index 87% rename from scripts/whoami.sh rename to scripts/host.sh index 3ca5b0b..6d564ec 100755 --- a/scripts/whoami.sh +++ b/scripts/host.sh @@ -5,7 +5,7 @@ CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" source $CURRENT_DIR/shared.sh main() { - get_info "whoami" + get_info host } main diff --git a/scripts/hostname.sh b/scripts/host_short.sh similarity index 85% rename from scripts/hostname.sh rename to scripts/host_short.sh index 7c6d4a0..f07e3f6 100755 --- a/scripts/hostname.sh +++ b/scripts/host_short.sh @@ -5,7 +5,7 @@ CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" source $CURRENT_DIR/shared.sh main() { - get_info "hostname" + get_info host_short } main diff --git a/scripts/hostname_short.sh b/scripts/pane_ssh_connect.sh similarity index 84% rename from scripts/hostname_short.sh rename to scripts/pane_ssh_connect.sh index 67583b5..9652ca4 100755 --- a/scripts/hostname_short.sh +++ b/scripts/pane_ssh_connect.sh @@ -5,7 +5,7 @@ CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" source $CURRENT_DIR/shared.sh main() { - get_info "hostname -s" + get_info } main diff --git a/scripts/pane_ssh_connected.sh b/scripts/pane_ssh_connected.sh index 1c8cf39..dce5ef8 100755 --- a/scripts/pane_ssh_connected.sh +++ b/scripts/pane_ssh_connected.sh @@ -5,11 +5,7 @@ CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" source $CURRENT_DIR/shared.sh main() { - if ssh_connected; then - echo 1 - else - echo 0 - fi + ssh_connected && echo 1 || echo 0 } main diff --git a/scripts/port.sh b/scripts/port.sh index ff0885c..32ba557 100755 --- a/scripts/port.sh +++ b/scripts/port.sh @@ -5,9 +5,7 @@ CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" source $CURRENT_DIR/shared.sh main() { - if ssh_connected; then - get_info "port" - fi + get_info port } main diff --git a/scripts/shared.sh b/scripts/shared.sh index 063ef21..39efd8e 100644 --- a/scripts/shared.sh +++ b/scripts/shared.sh @@ -4,11 +4,7 @@ get_tmux_option() { local option=$1 local default_value=$2 local option_value=$(tmux show-option -gqv "$option") - if [ -z "$option_value" ]; then - echo "$default_value" - else - echo "$option_value" - fi + [[ -z "$option_value" ]] && echo "$default_value" || echo "$option_value" } set_tmux_option() { @@ -17,87 +13,46 @@ set_tmux_option() { tmux set-option -gq "$option" "$value" } -parse_ssh_port() { - # If there is a port get it - local port=$(echo $1|grep -Eo '\-p\s*([0-9]+)'|sed 's/-p\s*//') - - if [ -z $port ]; then - local port=22 - fi - - echo $port -} - -get_ssh_user() { - local ssh_user=$(whoami) - - for ssh_config in `awk ' - $1 == "Host" { - gsub("\\\\.", "\\\\.", $2); - gsub("\\\\*", ".*", $2); - host = $2; - next; - } - $1 == "User" { - $1 = ""; - sub( /^[[:space:]]*/, "" ); - printf "%s|%s\n", host, $0; - }' .ssh/config`; do - local host_regex=${ssh_config%|*} - local host_user=${ssh_config#*|} - if [[ "$1" =~ $host_regex ]]; then - ssh_user=$host_user - break - fi - done - - echo $ssh_user -} - get_remote_info() { - local command=$1 - - # First get the current pane command pid to get the full command with arguments - local cmd=$({ pgrep -flaP `tmux display-message -p "#{pane_pid}"` ; ps -o command -p `tmux display-message -p "#{pane_pid}"` ; } | xargs -I{} echo {} | grep ssh | sed -E 's/^[0-9]*[[:blank:]]*ssh //') - - local port=$(parse_ssh_port "$cmd") - - local cmd=$(echo $cmd|sed 's/\-p\s*'"$port"'//g') - local user=$(echo $cmd | awk '{print $NF}'|cut -f1 -d@) - local host=$(echo $cmd | awk '{print $NF}'|cut -f2 -d@) + local command=$1 + local pane_pid=$(tmux display-message -p "#{pane_pid}") - if [ $user == $host ]; then - local user=$(get_ssh_user $host) - fi - - case "$1" in - "whoami") - echo $user - ;; - "hostname") - echo $host - ;; - "port") - echo $port - ;; - *) - echo "$user@$host:$port" - ;; - esac + # First get the current pane command pid to get the full command with arguments + local cmd=$({ pgrep -flaP $pane_pid ; ps -o command -p $pane_pid ; } | xargs -I{} echo {} | grep ssh | sed -E 's/^[0-9]*[[:blank:]]*ssh //') + # Fetch configuration with given cmd + ssh -G $cmd 2>/dev/null | grep -E -e '^host\s' -e '^port\s' -e '^user\s' | sort | cut -f 2 -d ' ' | xargs } get_info() { - # If command is ssh do some magic - if ssh_connected; then - echo $(get_remote_info $1) - else - echo $($1) - fi + # If command is ssh, fetch connection info + if ssh_connected; then + read -r host port user <<<$(get_remote_info) + fi + # Return requested info + case "$1" in + "user") # user from ssh info or `whoami` + [[ -z "$user" ]] && whoami || echo "$user" + ;; + "host") # host from ssh info or `hostname` + [[ -z "$host" ]] && hostname || echo "$host" + ;; + "host_short") # host from ssh info or `hostname -s` + [[ -z "$host" ]] && hostname -s || echo "$host" + ;; + "port") # port from ssh info or empty + echo "$port" + ;; + *) # user from ssh info + "@host" if host is not empty + ":port" if port is not empty + echo "${user}${host:+@$host}${port:+:$port}" + ;; + esac } ssh_connected() { - # Get current pane command - local cmd=$(tmux display-message -p "#{pane_current_command}") + local pane_pid=$(tmux display-message -p "#{pane_pid}") + + # Get current pane command + local cmd=$(pgrep -flaP $pane_pid) - [ $cmd = "ssh" ] || [ $cmd = "sshpass" ] + [[ $cmd =~ " ssh " ]] || [[ $cmd =~ " sshpass " ]] } diff --git a/scripts/user.sh b/scripts/user.sh new file mode 100755 index 0000000..9ec87a0 --- /dev/null +++ b/scripts/user.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source $CURRENT_DIR/shared.sh + +main() { + get_info user +} + +main