From 2e419db5d945badaf7b6bcc0ed0bb58581418884 Mon Sep 17 00:00:00 2001 From: Gregory Pakosz Date: Mon, 28 Oct 2024 19:31:22 +0100 Subject: [PATCH] refactored TPM plugins discovery, resolves #671 lift the limitation that allows plugins to only be declared from the main `.local` customization file from now on, spawn an ephemeral tmux server/client pair to discover plugins with a mix of source-file -nvq and a recursive shell function the upside of the new approach is that it respects tmux conditionals and we only consider set -g @plugin that are really evaluated by tmux, e.g. within %if, %elif, %else blocks --- currently, source-file -v doesn't apply the -v flag to subsequent source-file commands being evaluated, so we use -n and recurse ourselves trying to (ab)use the after-set-option hook to accumulate all the evaluations of set -g @plugin into a variable was promising, but is not immune to configuration files that use set-(hook|option) -gu after-set-option to clear the hook, which makes plugin discovery fail partially or even entirely --- .tmux.conf | 53 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/.tmux.conf b/.tmux.conf index 6d50a69..c9efd01 100644 --- a/.tmux.conf +++ b/.tmux.conf @@ -164,6 +164,8 @@ run 'cut -c3- "$TMUX_CONF" | sh -s _apply_configuration' # # exit the script if any statement returns a non-true return value # set -e # +# unset SHELL +# # unset GREP_OPTIONS # export LC_NUMERIC=C # # shellcheck disable=SC3041 @@ -603,7 +605,7 @@ run 'cut -c3- "$TMUX_CONF" | sh -s _apply_configuration' # battery_status="$battery_status_charging" # fi # -# tmux set -g '@battery_status' "$battery_status" +# tmux set -g '@battery_status' "$battery_status" >/dev/null 2>/dev/null # } # # _pane_info() { @@ -916,7 +918,7 @@ run 'cut -c3- "$TMUX_CONF" | sh -s _apply_configuration' # if _is_true "$tmux_conf_preserve_stock_bindings"; then # probe_socket="$(dirname "$TMUX_SOCKET")/tmux-stock-bindings-$$" # TMUX_SOCKET="$probe_socket" tmux -f /dev/null list-keys >> "$cfg" -# rm -f "%probe_socket" +# rm -f "$probe_socket" # fi # # # tmux 3.0 doesn't include 02254d1e5c881be95fd2fc37b4c4209640b6b266 and the @@ -1619,8 +1621,48 @@ run 'cut -c3- "$TMUX_CONF" | sh -s _apply_configuration' # fi # mkdir -p "$TMUX_PLUGIN_MANAGER_PATH" # +# __discover_plugins() ( +# probe_socket="$(dirname "$TMUX_SOCKET")/tmux-discover-plugins-$$" +# TMUX_SOCKET="$probe_socket" tmux -f /dev/null start-server \; set-option exit-empty off +# ___discover_plugins() { +# depth=$((${depth:-0} + 1)) +# IFS=${_IFS:-$IFS} +# [ "$depth" -le 100 ] || return +# for current_file in "$@"; do +# current_file="$(cd "${current_file%/*}" 2>/dev/null && pwd)/${current_file##*/}" || continue +# while IFS= read -r line; do +# if plugin=$(printf '%s\n' "$line" | perl -s -n -E 'print if s/^set-option\s+-g\s+\@plugin\s+//g or die' 2>/dev/null); then +# discovered_plugins="${discovered_plugins}${discovered_plugins:+ }${plugin}" +# elif next_files=$(printf '%s\n' "$line" | perl -s -n -E 's/(?/dev/null); then +# next_files=$(TMUX_SOCKET="$probe_socket" tmux -f /dev/null \ +# set -g @current_file "$current_file" \; \ +# display -pF "$next_files") +# +# _IFS="$IFS" +# IFS=$(printf '\n\nx') +# IFS=${IFS%?} +# # we don't want quoting here as we want wildcard expansion +# # shellcheck disable=SC2046 +# ___discover_plugins $(printf '%s\n' "$next_files" | xargs printf '%s\n\n') +# fi +# done << EOF +# $(TMUX_SOCKET="$probe_socket" tmux -f /dev/null source -nvq "$current_file" | perl -s -n -E 'print if s/^$current_file:\d+:\s*(set-option\s+-g\s+\@plugin\s+|source-file)/\1/g' -- -current_file="$current_file") +# EOF +# done +# } +# ___discover_plugins "$@" +# TMUX_SOCKET="$probe_socket" tmux -f /dev/null kill-server +# rm -rf "$probe_socket" +# printf '%s\n' "$discovered_plugins" +# ) +# # tpm_plugins=$(tmux show -gvq '@tpm_plugins' 2>/dev/null) -# if [ -z "$(tmux show -gv '@plugin' 2>/dev/null)" ] && [ -z "$tpm_plugins" ]; then +# tpm_plugins=$(cat << EOF | tr ' ' '\n' | awk '/^\s*$/ {next;}; !seen[$0]++ { gsub(/^[ \t]+/,"",$0); gsub(/[ \t]+$/,"",$0); print $0 }' +# $tpm_plugins +# $(__discover_plugins "$TMUX_CONF_LOCAL") +# EOF +# ) +# if [ -z "$tpm_plugins" ]; then # if _is_true "$tmux_conf_uninstall_plugins_on_reload" && [ -d "$TMUX_PLUGIN_MANAGER_PATH/tpm" ]; then # tmux display 'Uninstalling tpm and plugins...' # tmux set-environment -gu TMUX_PLUGIN_MANAGER_PATH @@ -1629,11 +1671,6 @@ run 'cut -c3- "$TMUX_CONF" | sh -s _apply_configuration' # fi # else # if [ "$(command tmux display -p '#{pid} #{version} #{socket_path}')" = "$("$TMUX_PROGRAM" display -p '#{pid} #{version} #{socket_path}')" ]; then -# tpm_plugins=$(cat << EOF | tr ' ' '\n' | awk '/^\s*$/ {next;}; !seen[$0]++ { gsub(/^[ \t]+/,"",$0); gsub(/[ \t]+$/,"",$0); print $0 }' -# $tpm_plugins -# $(awk '/^[ \t]*set(-option)?.*[ \t]@plugin[ \t]/ { gsub(/'\''/, ""); gsub(/'\"'/, ""); print $NF }' "$TMUX_CONF_LOCAL" 2>/dev/null) -# EOF -# ) # tmux set-environment -g TMUX_PLUGIN_MANAGER_PATH "$TMUX_PLUGIN_MANAGER_PATH" # tmux set -g '@tpm_plugins' "$tpm_plugins" #