Tmux Session Creator
A tutorial on how to create a tmux session selection script.
Get the list of projects
The first step is to get the list of projects. I store them in two different locations.
~/perso
, ~/work
. The easiest way to create that list is to use ls
.
First attempt: ls ~/perso ~/work
gives me extra lines
Second attempt: ls -d ~/perso/* ~/work/*
. The -d
argument prevents ls from recursively listing directories. In combination with *
globbing, this makes my ls
command more precise and removes the extra lines.
Prepare the list and pass it to fzf
- Sort the results
ls -d ~/perso/* ~/work/* | sort
- Remove the $HOME prefix as it is not usual while selecting the project. $HOME is a special shell variable that represents your user directory.
I use
cut -c
which cuts X characters from a string.echo $HOME | wc -c
returns the number of characters for $HOME.ls -d ~/perso/* ~/work/* ~/dotfiles | sort | cut -c$(echo $HOME | wc -c)-
- Pass the list to fzf-tmux. It’s like fzf—a general-purpose command-line fuzzy finder—except if you are using tmux you get additional functionalities. I like
-p
, it shows the fzf input in a tmux popupls -d ~/perso/* ~/work/* ~/dotfiles | sort | cut -c$(echo $HOME | wc -c)- | fzf-tmux -p
- Pass the selected item to my
tat
script. Note the use ofxargs
. This is a good example of how to use interpolation with pipe chains.-I "{}"
specifies I want to replace{}
with the passed argument in$HOME{}
. Now that I have selected the project I want to work on, I add back$HOME
to the path as it make things easier with my tmux session creation script:tat
ls -d ~/perso/* ~/work/* ~/dotfiles | sort | cut -c$(echo $HOME | wc -c)- | fzf-tmux -p | xargs -I "{}" tat "$HOME{}"
Tmux
My tat
script. The main function is create_if_needed_and_attach
and is called at the very end of the script.
#!/bin/sh
#
# Attach or create tmux session named the same as:
# - current directory if no argument is passed
# - otherwise parent_directory/basename of the argument—must be a path—passed
#
# names are sanitized to ensure there are compatible with tmux
DIR=${1:-$PWD}
sanitized_path_name="/$(dirname $DIR | xargs basename)/$(basename $DIR | tr . -)"
session_name=$sanitized_path_name
create_if_needed_and_attach() {
if is_in_tmux; then
if ! does_session_exist; then
create_detached_session
fi
tmux switch-client -t "$session_name"
else
start_tmux
fi
}
is_in_tmux() {
[ -n "$TMUX" ]
}
does_session_exist() {
tmux list-sessions | sed -E 's/:.*$//' | grep -q "^$session_name$"
}
create_detached_session() {
(TMUX='' tmux -f ~/.config/tmux/tmux.conf new-session -c $DIR -Ad -s "$session_name")
}
start_tmux() {
tmux -u -f ~/.config/tmux/tmux.conf new-session -As "$session_name"
}
create_if_needed_and_attach
Add the command to my tmux config
Inside tmux.conf
bind C-c run-shell "ls -d ~/perso/* ~/work/* ~/dotfiles | sort | cut -c$(echo $HOME | wc -c)- | fzf-tmux -p | xargs -I\"{}\" tat \"$HOME\"{}"
Run the command withC-b C-c
. C-c
as a mnemonic for create.