Tmux: custom project workspace

Tmux: custom project workspace
Image courtesy of justinlincoln

Tmux is a wonderful tool to increase my productivity by multiplexing windows and apps to a single terminal. I use it all the time when working on a project to organize my tools, and quickly switch between them.

One things I do these days is create a shell script to launch, and customize, my tmux session for the specific project that I am working on. This give me quick access to a complex setup, allowing me to jump into a project and get moving quickly.

When working on projects with a deep directory structure it is really helpful. I especially enjoy using this for Golang projects. I can jump into my Go root, run my script, and have a tmux session with all the windows I need loaded to the correct location.

The custom script defines a new session, creates windows with specific locations, names them, and sets the environment. It could do more, even starting processes, or running utility scripts.

Step by step

To begin with, a little check to ensure that my project exist. From time to time I move these scripts between machines, and I don’t need to bang my head against the monitor trying to discover why tmux isn’t cd’ing to my project directory.

1
2
3
4
5
6
PROJDIR="$HOME/go/src/github.com/kong/kubernetes-ingress-controller"

if [ ! -d "$PROJDIR" ]; then
    >&2 echo "target directory does not exist: $PROJDIR"
    exit -1
fi

The next piece is to start a new tmux session, give it a session name, a working directory, and give the initial window a custom name. Here we use -d to start the session detached. Only after we’ve finished mucking about with getting everything in it’s right place will we attach the session.

1
 tmux new-session -d -s king -c $PROJDIR -n Control

Next we can create some new windows. This example uses a straightforward Go project, so it doesn’t have much need for windows with custom paths. Though, I have set the fourth window use a custom path, and name.

1
2
3
tmux new-window -c $PROJDIR -t king
tmux new-window -c $PROJDIR -t king
tmux new-window -c $PROJDIR/docs -t king -n Docs

This is often useful to me when working on a web project. I will have one of my windows cd to the templates directory. It makes it easy to know that all my templates will be on window 3, and all my code will be on window 2.

Next I want to set my environment. I did not have a good experience using tmux’s set-environment command. I’m not sure if it doesn’t do what I want, or if I was doing it wrong. Either way I moved on to a brute force way of looping over all of my session’s panes and sending a bash command to set the environment.

1
2
3
4
5
6
for _pane in $(tmux list-panes -s -t king -F '#{pane_id}'); do \
  tmux send-keys -t ${_pane} "export GOPATH=~/go" Enter
  tmux send-keys -t ${_pane} "export GO111MODULE=off" Enter
  tmux send-keys -t ${_pane} "clear" Enter
  tmux clear-history -t ${_pane}
done

For this project I am setting the GOPATH and using a custom go modules configuration; I’m turning it off. This could just as easily be used to set Docker or Kubernetes environmental variables.

Finally I jump back to the first window, attach the session, and I’m ready to go.

1
2
tmux select-window -t Control
tmux attach-session -E -t king

Bring it all together

Here is our final script. It can be run from anywhere on the filesystem, but I tend to keep them in the GOPATH root, or someplace with my other projects.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/env sh

PROJDIR="$HOME/go/src/github.com/kong/kubernetes-ingress-controller"

if [ ! -d "$PROJDIR" ]; then
    >&2 echo "target directory does not exist: $PROJDIR"
    exit -1
fi

tmux new-session -d -s king -c $PROJDIR -n Control
tmux new-window -c $PROJDIR -t king
tmux new-window -c $PROJDIR -t king
tmux new-window -c $PROJDIR/docs -t king -n Docs

for _pane in $(tmux list-panes -s -t king -F '#{pane_id}'); do \
  tmux send-keys -t ${_pane} "export GOPATH=~/go" Enter
  tmux send-keys -t ${_pane} "export GO111MODULE=off" Enter
  tmux send-keys -t ${_pane} "clear" Enter
  tmux clear-history -t ${_pane}
done

tmux select-window -t Control
tmux attach-session -E -t king

You can find this on github in my tmux playground repository with other tmux scripts and snippets.

Tmux: custom project workspace by  
  tmux  tools  bash 
Like what you read? Share it:
  Facebook   Twitter   Google+