DEV Community

Michael Welford
Michael Welford

Posted on • Originally published at michaelwelford.blog

Saving time with a preset Tmux setup

Programming is all about doing the same thing... over and over again, ad nauseam. No, not the computer, the poor programmer as they work on similar projects bouncing around all the different tools.

For example, let's take Drupal development - usually once you are in the midst of it, you may be accessing:

  • An editor (Vim, naturally)
  • A terminal for running system commands e.g. drush cr, drush cedit, drupal generate:module etc.
  • Maybe a todo list / notes
  • Log output
  • Watch output e.g. npm run watch
  • Test output e.g. phpunit, codeception etc.
  • File ops e.g. ranger
  • Reference material
  • etc.

That may end up looking a bit like this:

drupal development screenshot

Note the Tmux status, bottom left, where it shows that I am in the first window of three.

As this is typical, wouldn't it be nice if, I don't know, you could run a command such as tmd <name of session> and it would set everything up just so. Also, over time, we could then refine this setup and get all the benefits of finessing it - or have multiple scripts depending on the type of project.

The script

No problem, take a look at this script drupal.sh:

#!/bin/zsh

# Note that this assumes base index of 1

# check for existence of required things
# $1 is the name of the window
# we are in the directory of the drupal project

if [ $# -eq 0 ]
  then
    echo "No arguments supplied, requires name of window."
    exit 1
fi

CWD=$(pwd)
SESSION_NAME="$1"

# detach from a tmux session if in one
tmux detach > /dev/null

# Create a new session, -d means detached itself
set -- $(stty size) # $1 = rows $2 = columns
tmux new-session -d -s $SESSION_NAME -x "$2" -y "$(($1 - 1))"

tmux new-window -t $SESSION_NAME:1 -n 'code'
tmux new-window -t $SESSION_NAME:2 -n 'logs'
tmux new-window -t $SESSION_NAME:3 -n 'zsh'

## Logs window
tmux select-window -t $SESSION_NAME:2

# Start up the logs listener
tmux send-keys "vbin/tail -f /var/log/apache2/error.log | clog drupal" C-m

## Zsh window
tmux select-window -t $SESSION_NAME:3
tmux rename-window 'Zsh'

## Main Window
tmux select-window -t $SESSION_NAME:1
tmux rename-window 'code'

# Split into left and right
tmux split-window -h -p30

# Right ready for taking commands / tests.
tmux select-pane -t 2
tmux send-keys "figlet -f roman Ready! | lolcat -t" C-m

# Left for neovim.
tmux select-pane -t 1
tmux send-keys "v" C-m

# Finally attach to it
tmux attach -t $SESSION_NAME
Enter fullscreen mode Exit fullscreen mode

How it works

The process can be broken down as follows:

  • Creating a new session
  • Creating windows
  • Creating panes
  • Sending commands to the panes / windows

Creating a new session

Creating a new session is as simple as tmux new-session -s <name-of-session>. In the example script I have a bit more going on:

# Create a new session, -d means detached itself
set -- $(stty size) # $1 = rows $2 = columns
tmux new-session -d -s $SESSION_NAME -x "$2" -y "$(($1 - 1))"
Enter fullscreen mode Exit fullscreen mode

What I am doing here is getting the current screen resolution and then creating a detached session of that size - the reason being that if you don't specify a size using the -x parameter then if you try to specify window split sizes it will wig out since it has no point of reference for "size".

Creating windows

Creating a window can be accomplished via tmux new-window -n <name-of-window>. In the example we have:

tmux new-window -t $SESSION_NAME:1 -n 'code'
tmux new-window -t $SESSION_NAME:2 -n 'logs'
tmux new-window -t $SESSION_NAME:3 -n 'zsh'
Enter fullscreen mode Exit fullscreen mode

Here we create three windows - the -t flag is so that we can specify the target of the windows, which in this case is the session that we just created and the index of where they should appear.

We can then target windows with tmux select-window -t <name-of-session>:<index> for further commands.

Creating panes

Often you will want to split up a window into multiple panes. This can be done with something like tmux split-window -h -p<percentage> where -h signifies a horizontal split (guess how a vertical split is specified?) and -p signifies a percentage split. In the example I create a 30 percent split but you can of course specify by pixel if that is your jam.

Once you have created one or more splits, you can target panes with tmux select-pane -t <index-of-pane> for more commands.

Sending commands to the panes / windows

Lastly, once we have our windows and panes ready, we can send them further commands to start things up. Some examples from the above:

  • tmux send-keys "vbin/tail -f /var/log/apache2/error.log | clog drupal" C-m

(run the tail command in watch mode against the apache error log, piped into clog - the C-m is used to send an <Enter> to a pane or window)

  • tmux send-keys "figlet -f roman Ready! | lolcat -t" C-m

(run figlet with the string "Ready!", piped into lolcat in true colour mode )

Finishing up

Rounding out the script we have a call to tmux attach -t <name-of-session> which makes it visible. In the script, the name of the session is passed in as a parameter. For extra convenience I have the following alias in my .zshrc to run this script:

alias tmd='~/.config/tmux/drupal.sh'
Enter fullscreen mode Exit fullscreen mode

Obviously you don't have to attach to a Tmux session - if you had the need, your script could start up all kinds of processes and then you could attach only to check it whilst doing other things (or not!). Tmux also supports multiple people attaching to a session, sending commands to specific sessions, saving sessions (via plugins) etc. The possibilities runneth over.


This article originally appeared on michaelwelford.blog

Top comments (8)

Collapse
 
xxkeith20xx profile image
Keith 20

Love tmux but it can have a steep learning curve imo. These links helped me a lot:

github.com/rothgar/awesome-tmux
leanpub.com/the-tao-of-tmux/read
rushiagr.com/blog/2016/06/16/every...

Collapse
 
fenetikm profile image
Michael Welford

Thanks for the links!

Agreed - thankfully I feel like the curve eventually tapers off (more so than Vim, for example).

Collapse
 
codehakase profile image
Francis Sunday

Great post Michael! I've been using tmux for a while now, and its really a great addon to boost one's productivity, especially when one spends a lot of time in the terminal (vim is my primary editor).

Do you screencast your vim/tmux workflows?

Collapse
 
fenetikm profile image
Michael Welford • Edited

Thanks Francis, appreciate it.

Re screencasts: I literally bought a bunch of gear (probably unnecessarily) and then haven't followed through on recording anything.

I pledge to do at least one by end of next month :)

Collapse
 
coumbole profile image
Ville Kumpulainen

This is really neat, thanks for taking the time to write about this! I'm running an almost identical setup so this was just perfect.

Collapse
 
weirdmayo profile image
Daniel Mayovsky

I actually followed this explanation, read the Tao of Tmux, made a few of my own scripts for different projects, and actually saved time and became more productive.

Collapse
 
biros profile image
Boris Jamot ✊ /

I use tmuxp that brings a lot of simplicity to tmux' sessions.

Great post !

Collapse
 
fenetikm profile image
Michael Welford

Fab - I also tried tmuxinator but it wouldn't quite do what I wanted it to do and then of course the tinkering impulse kicked in...