summaryrefslogtreecommitdiff
path: root/mac/.local/bin/tmuxopen
diff options
context:
space:
mode:
Diffstat (limited to 'mac/.local/bin/tmuxopen')
-rwxr-xr-xmac/.local/bin/tmuxopen208
1 files changed, 208 insertions, 0 deletions
diff --git a/mac/.local/bin/tmuxopen b/mac/.local/bin/tmuxopen
new file mode 100755
index 0000000..5362215
--- /dev/null
+++ b/mac/.local/bin/tmuxopen
@@ -0,0 +1,208 @@
+#!/bin/sh
+
+wrapper() {
+ usage() {
+ echo "Search for files and open them in Neovim within tmux panes."
+ echo ""
+ echo "Usage: tmuxopen [OPTIONS]"
+ echo ""
+ echo "Options:"
+ echo " -h, --help : Show this help message"
+ echo ""
+ echo "Controls:"
+ echo " Tab Select files"
+ echo " Ctrl+f Search filenames"
+ echo " Ctrl+g Search file contents"
+ echo " Ctrl+d Search directories"
+ echo ""
+ echo "Environment Variables:"
+ echo " NVIM_SEARCH_REGISTRY Set to the search query, allowing Neovim to highlight matches"
+ echo ""
+ echo "Example:"
+ echo " tmuxopen # Run the normal search and open"
+ }
+
+ get_fzf_output() {
+ # Create temporary files to store search state
+ tmp_files="/tmp/search-files-$$"
+ tmp_content_query="/tmp/search-content-query-$$"
+
+ # Cleanup on exit
+ trap "rm -f $tmp_files $tmp_content_query" EXIT
+
+ rg_fixed_bind="ctrl-g:transform-query(
+ echo {q} > $tmp_content_query;
+ echo {q}
+ )+reload(
+ rm -f $tmp_files;
+ rg --line-number --follow --fixed-strings --hidden --no-heading --color=always --smart-case --glob '!**/.git/**' --glob '!node_modules/**' {q} 2>/dev/null || true
+ )"
+ file_bind="ctrl-f:transform-query(
+ current_query={q};
+ if [ ! -s $tmp_content_query ]; then
+ echo \$current_query > $tmp_content_query;
+ fi;
+ rg --hidden --follow --files-with-matches --no-messages --glob '!**/.git/**' --glob '!node_modules/**' -- \$current_query > $tmp_files;
+ )+reload(
+ if [ -s $tmp_files ]; then
+ if [ -n {q} ]; then
+ grep -i -- {q} $tmp_files || true;
+ else
+ cat $tmp_files;
+ fi | while IFS= read -r file; do
+ if [ -f \"\$file\" ]; then
+ echo \"\$file:1\";
+ fi;
+ done;
+ else
+ echo 'No matching files found';
+ fi
+ )"
+ if command -v fd >/dev/null 2>&1; then
+ dir_bind="ctrl-d:change-prompt(📁 )+reload(fd --follow --type d --hidden --absolute-path --color never --exclude .git --exclude node_modules --search-path \"\$PWD\")"
+ else
+ dir_bind="ctrl-d:change-prompt(📁 )+reload(find \"\$PWD\" -L -type d -name node_modules -prune -o -name .git -prune -o -type d -print)"
+ fi
+
+ rg --line-number --follow --no-heading --color=always --smart-case --glob '!**/.git/**' --glob '!LICENSE' '' 2>/dev/null |
+ fzf-tmux \
+ --ansi --multi --delimiter : \
+ --reverse \
+ --print-query \
+ --preview 'bat --style=numbers --color=always --highlight-line {2} {1} 2>/dev/null || bat --color=always {} 2>/dev/null || ls -la {} 2>/dev/null || echo "Preview is not available."' \
+ --preview-window 'right,55%,border-bottom,+{2}+3/3,~3' \
+ --bind "$file_bind" \
+ --bind "$rg_fixed_bind" \
+ --bind "$dir_bind" \
+ --bind 'ctrl-c:abort' \
+ --header "^f filenames | ^g contents | ^d directories" \
+ --prompt "🔎 "
+ }
+
+ set_nvim_search_variable() {
+ raw_output="$1"
+ tmp_content_query="/tmp/search-content-query-$$"
+ if [ -f "$tmp_content_query" ]; then
+ saved_query=$(cat "$tmp_content_query" 2>/dev/null)
+ if [ -n "$saved_query" ]; then
+ export NVIM_SEARCH_REGISTRY="$saved_query"
+ return
+ fi
+ fi
+ query=$(echo "$raw_output" | head -n1)
+ export NVIM_SEARCH_REGISTRY="$query"
+ }
+
+ open_files_in_nvim() {
+ pane="$1"
+ shift
+ file_indices="$*"
+ nvim_cmd="nvim"
+ for index in $file_indices; do
+ file=$(echo "$files" | awk -v idx="$index" '{print $idx}')
+ line=$(echo "$lines" | awk -v idx="$index" '{print $idx}')
+ nvim_cmd="$nvim_cmd +$line $file"
+ done
+ nvim_cmd="$nvim_cmd -c 'let @/=\"$NVIM_SEARCH_REGISTRY\"'"
+ tmux send-keys -t "$pane" "$nvim_cmd" C-m
+ }
+
+ # Parse command line arguments
+ while [ "$#" -gt 0 ]; do
+ case "$1" in
+ -h | --help)
+ usage
+ exit 0
+ ;;
+ *)
+ echo "Unknown option: $1" >&2
+ usage
+ exit 1
+ ;;
+ esac
+ done
+
+ raw_output=$(get_fzf_output)
+ set_nvim_search_variable "$raw_output"
+
+ # Split the newline-delimited output into an array, skipping the first line (query)
+ selections=$(echo "$raw_output" | sed 1d)
+
+ if [ -z "$selections" ]; then
+ echo "No selections made"
+ exit 0
+ fi
+
+ files=""
+ lines=""
+ count=0
+
+ # Use a here document to avoid subshell issues
+ while IFS= read -r selection; do
+ file=$(echo "$selection" | awk -F: '{print $1}')
+ line=$(echo "$selection" | awk -F: '{print $2}')
+ if [ -f "$file" ]; then
+ files="$files $file"
+ lines="$lines $line"
+ count=$((count + 1))
+ else
+ echo "File not found: $file"
+ fi
+ done <<EOF
+$selections
+EOF
+
+ if [ "$count" -eq 0 ]; then
+ echo "No valid files selected"
+ exit 0
+ fi
+
+ if [ "$count" -eq 1 ]; then
+ open_files_in_nvim "$(tmux display-message -p '#P')" 1
+ else
+ window_name="$(date +%s)"
+ tmux new-window -n "$window_name"
+ case "$count" in
+ 2)
+ tmux split-window -t "$window_name" -h -p 50
+ open_files_in_nvim "$window_name.1" 1
+ open_files_in_nvim "$window_name.2" 2
+ tmux select-pane -t "$window_name.1"
+ ;;
+ 3)
+ tmux split-window -t "$window_name" -h -p 50
+ tmux split-window -t "$window_name.2" -v -p 50
+ open_files_in_nvim "$window_name.1" 1
+ open_files_in_nvim "$window_name.2" 2
+ open_files_in_nvim "$window_name.3" 3
+ ;;
+ *)
+ tmux split-window -t "$window_name" -h -p 50
+ tmux split-window -t "$window_name.1" -v -p 50
+ tmux split-window -t "$window_name.3" -v -p 50
+ open_files_in_nvim "$window_name.1" 1
+ open_files_in_nvim "$window_name.2" 2
+ open_files_in_nvim "$window_name.3" 3
+ remaining_indices=""
+ for i in $(seq 4 "$count"); do
+ remaining_indices="$remaining_indices $i"
+ done
+ open_files_in_nvim "$window_name.4" "$remaining_indices"
+ ;;
+ esac
+ fi
+}
+
+for cmd in rg fzf bat tmux nvim; do
+ if ! command -v $cmd >/dev/null 2>&1; then
+ echo "Error: $cmd not found" >&2
+ exit 1
+ fi
+done
+
+if [ -z "$TMUX" ]; then
+ echo "Error: Not in a tmux session" >&2
+ exit 1
+fi
+
+wrapper "$@"