mirror of
https://github.com/fscotto/infra.git
synced 2026-05-30 15:39:58 +00:00
99 lines
2.8 KiB
Bash
Executable File
99 lines
2.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
basedir="$(cd "$(dirname "$0")/.." && pwd)"
|
|
# shellcheck source=../lib/tmux.bash
|
|
. "$basedir/lib/tmux.bash"
|
|
|
|
find_projects() {
|
|
local -a base_dirs rooters rooter_opts
|
|
|
|
IFS=',' read -ra base_dirs < <(get_tmux_option '@project-base-dirs')
|
|
IFS=',' read -ra rooters < <(get_tmux_option '@project-rooters' '.git')
|
|
|
|
for rooter in "${rooters[@]}"; do
|
|
rooter_opts+=("-o" "-name" "$rooter")
|
|
done
|
|
rooter_opts=('(' "${rooter_opts[@]:1}" ')')
|
|
|
|
for base_dir in "${base_dirs[@]}"; do
|
|
# If the base_dir is empty, skip it
|
|
if [[ -z "$base_dir" ]]; then
|
|
continue
|
|
fi
|
|
|
|
local -a tmp
|
|
IFS=':' read -ra tmp <<<"$base_dir"
|
|
path="${tmp[0]}"
|
|
min_depth="${tmp[1]:-0}"
|
|
max_depth="${tmp[2]:-${min_depth}}"
|
|
|
|
if [[ min_depth -eq 0 && max_depth -eq 0 ]]; then
|
|
# If min_depth and max_depth are both 0, that means we
|
|
# want to add the base_dir itself as a project.
|
|
# In that case, add the base_dir as a project even if it
|
|
# contains no rooter.
|
|
if [[ -d "$path" || -L "$path" ]]; then
|
|
echo "$path"
|
|
fi
|
|
else
|
|
find "$path" -mindepth "$((min_depth + 1))" \
|
|
-maxdepth "$((max_depth + 1))" \
|
|
"${rooter_opts[@]}" \
|
|
-printf '%h\n'
|
|
fi
|
|
done
|
|
}
|
|
|
|
# Convert a path to a session name. The session name is the last component of
|
|
# the path. Dots are replaced with underscores. If the path starts with a dot,
|
|
# the dot is removed.
|
|
# e.g. /home/username/.emacs.d -> emacs_d
|
|
to_session_name() {
|
|
local session_name="$1"
|
|
|
|
session_name="${session_name##*/}"
|
|
|
|
# Dots are not allowed in a tmux session name
|
|
# e.g. .emacs.d -> _emacs_d
|
|
session_name="${session_name//./_}"
|
|
# If the path starts with a slash (a dot), remove it
|
|
# e.g. .emacs.d -> _emacs_d -> emacs_d
|
|
session_name="${session_name#_}"
|
|
|
|
echo "$session_name"
|
|
}
|
|
|
|
main() {
|
|
local fzf_opts fzf_tmux_layout_opts selected_path session_name
|
|
|
|
# shellcheck disable=SC2207
|
|
fzf_opts="$(get_tmux_option "@project-fzf-opts" "--preview 'ls {}'")"
|
|
# shellcheck disable=SC2207
|
|
fzf_tmux_layout_opts="$(get_tmux_option "@project-fzf-tmux-layout-opts")"
|
|
|
|
selected_path="$(find_projects | eval "fzf-tmux ${fzf_tmux_layout_opts} -- ${fzf_opts}")"
|
|
if [[ -z "$selected_path" ]]; then
|
|
return 0
|
|
fi
|
|
|
|
# If the selected project has .tmuxinator.yml file, use tmuxinator to
|
|
# start the session.
|
|
if command -v tmuxinator &>/dev/null && [[ -f "${selected_path}/.tmuxinator.yml" ]]; then
|
|
tmuxinator start -p "${selected_path}/.tmuxinator.yml"
|
|
return 0
|
|
fi
|
|
|
|
session_name="$(to_session_name "$selected_path")"
|
|
|
|
# If the session already exists, attach to it. Otherwise, create a new
|
|
# session and attach to it.
|
|
if ! tmux has-session -t "$session_name" 2>/dev/null; then
|
|
# Return 0 even if creating the session fails.
|
|
tmux new-session -d -s "$session_name" -c "$selected_path" \; \
|
|
set -t "$session_name" destroy-unattached off || :
|
|
fi
|
|
tmux switch-client -t "$session_name"
|
|
}
|
|
|
|
main "$@"
|