mirror of
https://github.com/ivuorinen/dotfiles.git
synced 2026-01-26 03:04:06 +00:00
144 lines
3.7 KiB
Bash
Executable File
144 lines
3.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Credit to ThePrimeagen, Jess Archer
|
|
# See https://github.com/jessarcher/dotfiles/blob/master/scripts/t
|
|
#
|
|
# Tweaks by Ismo Vuorinen <https://github.com/ivuorinen> 2025
|
|
# vim: ft=bash ts=2 sw=2 et
|
|
|
|
# Set environment variables for configuration with defaults
|
|
T_ROOT="${T_ROOT:-$HOME/Code}"
|
|
DOTFILES="${DOTFILES:-$HOME/.dotfiles}"
|
|
T_MAX_DEPTH="${T_MAX_DEPTH:-3}"
|
|
|
|
# Function to print an error message and exit
|
|
error_exit() {
|
|
echo "Error: $1" >&2
|
|
exit 1
|
|
}
|
|
|
|
# Validate that T_ROOT exists
|
|
if [[ ! -d "$T_ROOT" ]]; then
|
|
error_exit "T_ROOT directory '$T_ROOT' does not exist."
|
|
fi
|
|
|
|
|
|
# Check for required dependencies
|
|
check_dependencies() {
|
|
local T_DEPS=(tmux fzf find)
|
|
for cmd in "${T_DEPS[@]}"; do
|
|
if ! command -v "$cmd" &> /dev/null; then
|
|
error_exit "$cmd is not installed."
|
|
fi
|
|
done
|
|
}
|
|
|
|
check_dependencies
|
|
|
|
# Generate an array of '-not -path' rules for each exclusion pattern
|
|
# without using namerefs.
|
|
generate_exclude_rules() {
|
|
local result_var="$1"
|
|
shift
|
|
local arr=()
|
|
for pattern in "$@"; do
|
|
# Exclude both the directory and any subdirectories under it.
|
|
arr+=( -not -path "*/${pattern}" -not -path "*/${pattern}/*" )
|
|
done
|
|
# Use eval to assign the array to the variable whose name was passed.
|
|
eval "$result_var=(\"\${arr[@]}\")"
|
|
}
|
|
|
|
get_directories() {
|
|
local exclude_patterns=(
|
|
".bzr" ".git" ".hg" ".idea" ".obsidian" ".run" ".svn" ".vscode"
|
|
"build" "dist" "node_modules" "out" "target" "vendor"
|
|
)
|
|
local exclude_rules=()
|
|
generate_exclude_rules exclude_rules "${exclude_patterns[@]}"
|
|
|
|
local dirs
|
|
# Use $'string' to correctly process escape sequences.
|
|
dirs=$'# Directories\n'
|
|
dirs+=$(find "$T_ROOT" \
|
|
-maxdepth "$T_MAX_DEPTH" \
|
|
-mindepth 1 \
|
|
-type d \
|
|
"${exclude_rules[@]}"
|
|
)
|
|
echo -e "$dirs"
|
|
}
|
|
|
|
check_tmux() {
|
|
if ! command -v tmux &> /dev/null; then
|
|
error_exit "tmux is not installed."
|
|
fi
|
|
|
|
# Ensure tmux server is running
|
|
if ! tmux info &> /dev/null; then
|
|
tmux start-server
|
|
fi
|
|
}
|
|
|
|
get_sessions() {
|
|
check_tmux
|
|
|
|
T_TMUX_SESSIONS=$(tmux list-sessions -F "#{session_name}" 2> /dev/null)
|
|
|
|
if [[ -z "$T_TMUX_SESSIONS" ]]; then
|
|
echo ""
|
|
return
|
|
fi
|
|
|
|
echo -e "# Sessions\n$T_TMUX_SESSIONS"
|
|
}
|
|
|
|
# Determine selection from command-line argument or interactive fzf menu
|
|
if [[ $# -eq 1 ]]; then
|
|
selected="$1"
|
|
else
|
|
# Combine sessions and directories for selection
|
|
T_ITEMS="$(get_sessions | sort)
|
|
$(get_directories | sort)"
|
|
|
|
# Use sort to order the entries and fzf for interactive selection
|
|
selected=$(echo "$T_ITEMS" | fzf) || exit 0
|
|
fi
|
|
|
|
# Reject selection if it is a header line
|
|
[[ ${selected:0:1} == "#" ]] && error_exit "Header selected. Please choose a valid session or directory."
|
|
|
|
[[ -z "$selected" ]] && error_exit "No directory or session selected."
|
|
|
|
# Sanitize the session name
|
|
session_name=$(basename "$selected")
|
|
if [[ -z "$session_name" ]]; then
|
|
session_name="$selected"
|
|
fi
|
|
# Remove dots since tmux dislikes them
|
|
session_name="${session_name//./}"
|
|
|
|
# Attempt to switch to an existing session
|
|
tmux switch-client -t "=$session_name" 2>/dev/null
|
|
active_session=$(tmux display-message -p -F '#{session_name}' 2>/dev/null)
|
|
|
|
if [[ "$active_session" == "$session_name" ]]; then
|
|
exit 0
|
|
fi
|
|
|
|
# Create a new session (or attach to an existing one) based on the selection
|
|
if [ -z "$TMUX" ]; then
|
|
# Not inside tmux: create (or attach to) the session and attach.
|
|
tmux new-session -A -s "$session_name" -c "$selected"
|
|
else
|
|
# Inside tmux: check if the target session exists.
|
|
if tmux has-session -t "$session_name" 2>/dev/null; then
|
|
# Session exists; switch to it.
|
|
tmux switch-client -t "$session_name"
|
|
else
|
|
# Session does not exist; create it in detached mode and then switch.
|
|
tmux new-session -d -s "$session_name" -c "$selected"
|
|
tmux switch-client -t "$session_name"
|
|
fi
|
|
fi
|