nix/modules/home-manager/cli/tmux/files/create-tmux-session.sh
2025-05-12 09:04:21 +02:00

218 lines
4.8 KiB
Bash
Executable file

#!/usr/bin/env bash
set -e
set -o pipefail
DEBUG=0
declare -a COMMANDS
help() {
cat <<EOF
${0}
Create a tmux session with defined elements (windows, panes, launch command).
This script need 'ghq' and 'fzf',
USAGE
-----
create-tmux-session -n <name> -i <id> -p <project> <command> <command>
-n --name <name> define a session name
-i --id <id> define a session id,
-r --repo <project> define the repo used as base directory if not defined
'ghq' and 'fzf' will be use to let you select one
<command> a command launched in the new created session. you can
use it many time.
COMMANDS
--------
All commands take only one parameter separated rom command by coma (':') for
example 'neww:shell'.
vsplit Split current pane vertically
parameter: new pane vertical size in % (default 20)
hsplit Split current pane horizontally (default 20)
parameter: new pane horizontal size in % (default 20)
neww Create a new window, parameter: windows name
run Run command into last created element (pane, window)
parameter: command
repo Change repo, useful to create a pane / window with a different base
directory
parameter: repo name
EOF
}
error() {
local message
printf -v message "\e[31mERROR:\e[0m %s\n" "$1"
>&2 printf "%b" "${message}"
}
debug() {
local message
if [[ $DEBUG -eq 1 ]]; then
printf -v message "\e[3;34mDEBUG:\e[0m %s\n" "$*"
>&2 printf "%b" "$message"
fi
}
process_args() {
until [[ -z $1 ]]; do
case $1 in
-i | --session-id | --id)
SESSION_ID="$2"
shift
;;
-n | --session-name | --name)
SESSION_NAME="$2"
shift
;;
-r | --repository-name | --repo)
PROJECT="$2"
shift
;;
-d | --debug)
DEBUG=1
;;
-h | --help)
help
exit 0
;;
*)
COMMANDS+=("$1")
;;
esac
shift
done
}
check_command() {
local command="$1"
if ! command -v "${command}" >/dev/null 2>&1; then
error "Command '$command' not available"
exit 2
fi
}
has_session() {
tmux has-session -t "${SESSION_NAME:-$SESSION_ID}" 2>/dev/null
}
get_repo_path() {
local identifier="${1}"
debug "get project path with identifier '$identifier'"
if [[ -z "$identifier" ]]; then
CURRENT_PATH=$(ghq list -p | fzf)
else
CURRENT_PATH=$(ghq list -p -e "$identifier")
fi
}
is_running_in_tmux() {
debug "check if running in tmux"
if [[ -z $TMUX ]]; then
error "This script should run in a running instance of Tmux"
exit 10
fi
}
check_available_commands() {
# Check commands dependencies
for c in fzf ghq; do
check_command "$c"
done
}
check_script_inputs() {
debug "check script inputs"
if [[ -z "$SESSION_ID" ]] && [[ -z "$SESSION_NAME" ]]; then
error "You must provide session ID or a session name"
exit 5
fi
SESSION_NAME=${SESSION_NAME:-$SESSION_ID}
}
process_command() {
local input="$1"
debug "Process command '$input'"
local cmd arg
if [[ "$input" =~ ^.*:.*$ ]]; then
debug "command and parameter found"
arg=${input##*:}
cmd=${input%%:*}
else
debug "command found without parameter"
cmd="$input"
fi
if ! "tmux_${cmd}" "${arg}"; then
error "Command \`$cmd\` not exist"
fi
}
tmux_vsplit() {
local size="${1:-20}"
debug "execute vsplit with size '${size}'"
tmux split-window -t "${SESSION_NAME}" -c "$CURRENT_PATH" -v -p "$size"
}
tmux_hsplit() {
local size="${1:-20}"
debug "execute hsplit with size '${size}'"
tmux split-window "${SESSION_NAME}" -c "$CURRENT_PATH" -h -p "$size"
}
tmux_neww() {
local name="$1"
debug "execute neww with name '${name}'"
local command=(tmux new-window -t "${SESSION_NAME}" -c "$CURRENT_PATH" -a)
if [[ -n "$name" ]]; then
command+=(-n "$name")
fi
"${command[@]}"
}
tmux_run() {
local shell_command="$1"
debug "execute run with command '${shell_command}'"
if [[ -z "$shell_command" ]]; then
error "tmux-run need a command"
else
tmux send-keys -t "${SESSION_NAME}" "$shell_command" "C-m"
fi
}
tmux_repo() {
local arg="$1"
debug "execute project with arg '${arg}'"
get_repo_path "$arg"
}
create_session() {
tmux new-session -ds "${SESSION_NAME}" -c "${CURRENT_PATH}" -n "${PROJECT}"
if [[ "$SESSION_NAME" == "$SESSION_ID" ]]; then
tmux rename-session -t "$SESSION_ID" "$SESSION_ID ${CURRENT_PATH##*/}"
fi
}
main() {
check_available_commands
process_args "$@"
is_running_in_tmux
check_script_inputs
if ! has_session "${SESSION_NAME}"; then
get_repo_path "${PROJECT}"
create_session
# Process tmux commands passed with command line
for command in "${COMMANDS[@]}"; do
process_command "$command"
done
fi
tmux switch-client -t "${SESSION_NAME:-$SESSION_ID}"
}
main "${@}"