Created
March 21, 2023 01:19
-
-
Save felixSchl/91d548aa7181f09808104f9392737b78 to your computer and use it in GitHub Desktop.
TMUX FZF integration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# Author: Felix Schlitter | |
# Description: | |
# Manage sessions using FZF | |
# | |
# Place this into your .bashrc after installing FZF, | |
# Then update your .tmux.conf and create key-bindings. Example: | |
# | |
# unbind s | |
# bind s run "tmux new-window -n 'Switch Session' 'bash -ci "'"tmux-completions select_session"'"'" | |
# unbind K | |
# bind K run "tmux new-window -n 'Kill Session' 'bash -ci "'"tmux-completions kill_session"'"'" | |
# unbind C | |
# bind C run "tmux new-window -n 'Create Session' 'bash -ci "'"tmux-completions create_session"'"'" | |
PROJECT_PATHS=${VARIABLE:-~/dev:~/dev/dn3010} | |
if ! command -v > /dev/null fzf; then | |
if [[ -f ~/.fzf.bash ]]; then | |
source ~/.fzf.bash | |
else | |
'command "fzf" not found. Please install fzf first' | |
fi | |
fi | |
_tmux_select_session () ( | |
set -eo pipefail | |
local -r prompt=$1 | |
local -r fmt='#{session_id}:|#S|(#{session_attached} attached)' | |
{ tmux display-message -p -F "$fmt" && tmux list-sessions -F "$fmt"; } \ | |
| awk '!seen[$1]++' \ | |
| column -t -s'|' \ | |
| fzf -q'$' --reverse --prompt "$prompt> " \ | |
| cut -d':' -f1 | |
) | |
_find_existing_sid () ( | |
set -eo pipefail | |
local -r name=$1 | |
sid=$(tmux list-sessions -F '#{session_name}:#{session_id}' \ | |
| grep "$name:" \ | |
| head -n 1 \ | |
| cut -d ':' -f 2 | |
) | |
if [ -n "$sid" ]; then | |
echo "$sid" | |
return 0 | |
else | |
return 1 | |
fi | |
) | |
# Select selected tmux session | |
# Note: To be bound to a tmux key in from .tmux.conf | |
# Example: bind-key s run "tmux new-window -n 'Switch Session' 'bash -ci tmux_select_session'" | |
tmux_select_session () ( | |
set -eo pipefail | |
_tmux_select_session 'switch session' | xargs tmux switch-client -t | |
) | |
# Kill selected tmux session | |
# Note: To be bound to a tmux key in from .tmux.conf | |
# Example: bind-key K run "tmux new-window -n 'Kill Session' 'bash -ci tmux_kill_session'" | |
tmux_kill_session () ( | |
set -eo pipefail | |
_tmux_select_session 'kill session' \ | |
| { | |
read -r id | |
echo "$id" | |
next=$(tmux list-sessions -F '#{session_id}' | grep -v -F "$id" | head -n1) | |
if [ -n "$next" ]; then | |
tmux switch-client -t "$next" | |
fi && tmux kill-session -t "$id" | |
} | |
) | |
tmux_session_name () { | |
sed <<< "$1" 's/[.:]/-/g' | |
} | |
# Create a new tmux session | |
# Note: we must spawn the sessions in detached mode and the use | |
# `switch-client` to attach to them. Otherwise we'd get an error saying | |
# that the "terminal is not available" | |
# Note: To be bound to a tmux key in from .tmux.conf | |
# Example: bind-key C run "tmux new-window -n 'Create Session' 'bash -ci tmux_create_session'" | |
tmux_create_session () ( | |
unset TMUX | |
set -eo pipefail | |
local new_session_id | |
{ | |
new_session_id=$( | |
set -eo pipefail | |
if [ -z "$PROJECT_PATHS" ]; then | |
echo 'Create new session (Ctrl-C to cancel):' | |
echo 'Set $PROJECT_PATHS to streamline this process.' | |
echo | |
read -rep "Set working directory (default: \"$PWD\"):"$'\n> ' dir && \ | |
if [ -z "$dir" ]; then dir=$PWD; fi && \ | |
echo | |
read -rp "Set name (default \"${dir##*/}\"):"$'\n> ' name && \ | |
if [ -z "$name" ]; then name=${dir##*/}; fi | |
tmux new-session -d -c "$dir" -n "$name" -s "$(tmux_session_name "$name")" -P -F "#{session_id}" | |
else | |
local projects=(${PROJECT_PATHS//:/ }) | |
for dir in "${projects[@]}"; do | |
if [ -d "$dir" ]; then | |
find "${dir%*/}" -maxdepth 1 -type d | tail -n+2 | |
fi | |
done \ | |
| awk '!seen[$1]++' \ | |
| fzf --reverse --prompt 'Create new session - choose project: ' --expect='~' \ | |
| { | |
read -r key; | |
if [[ "$key" == '~' ]]; then | |
tmux new-session -d -c ~ -P -F "#{session_id}" | |
else | |
read -r dir; | |
name=${dir##*/} | |
_find_existing_sid "$name" || { | |
tmux new-session -d -c "$dir" -n "$name" -s "$(tmux_session_name "$name")" -P -F "#{session_id}" | |
} | |
fi | |
} | |
fi | |
) && tmux switch-client -t "$new_session_id" | |
} | |
) | |
case "$1" in | |
select_session) tmux_select_session ;; | |
kill_session) tmux_kill_session ;; | |
create_session) tmux_create_session ;; | |
*) "Command not understood: $1. Must be on of select_session|kill_session|create_session" | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment