ssh, tmux and vim: A Simple Yet Effective Pair Programming Setup

by Paul Cochrane on 2019-04-04

At Drift+Noise, we try to use Agile software development methods where possible. For instance, we use TDD largely for our unit tests, BDD for functional tests (sometimes also called customer tests) as well as Continuous Integration and Continuous Delivery via Jenkins. Basically, if the test suite passes, the new code gets rolled out to production automatically. Of course, this requires good test coverage and code quality.

One thing which can aid code quality is pair programming and I thought I’d share our work setup here, which we’ve found works well both in the office as well as remotely.

We’ve found it to be fun and it has worked rather well. We can’t always pair program because we’re not always working on the same project(s), but when we are, we’ve noticed an enhanced knowledge transfer due to both of us working on a single problem at the same time. Each person brings different perspectives to the task at hand, and if the coding task is rotated, then each person is able to stay refreshed and focussed for longer.

The technical setup

To set up the shared sessions, it’s useful to have a similar setup on both computers. This way it’s possible to pair program using the other person’s environment if necessary. For instance, if one person has a particular project set up on their laptop and it would take some time to get the same setup working on the other person’s system, then it’s as simple as logging in to the already set up environment and one can become productive straight away.

Because we both use vim as our editor, a console is sufficient for this setup to work. If you use a graphical IDE, however, then this setup won’t work and you’ll have to find some other way of sharing screens and programming environments.

Install the necessary software

In our setup both systems need tmux and vim installed as well as an ssh server running. On Debian-based systems this will do the job:

$ sudo apt install openssh-server tmux vim

We shall call the system hosting the shared session the “host” system, and the other system, the “guest” system.

It’s preferable that both systems be Unix-based so that the command listings mentioned below can be used as-is. However, if the guest user is on a Windows system, it should be possible to use PuTTY to log in to the host system and share the session this way, however such a setup doesn’t allow guest and host systems to be swapped.

Give users sufficient permissions

To allow the guest user to access the host system, a user needs to be created. This user should be added to the users group on the host system so that they can access the shared tmux socket.

$ sudo adduser <username>               # for user logging in remotely
$ sudo usermod -a -G users <username>   # for both users to pair

Both users have to be in the same group since the tmux session will be shared via a socket (which will appear as a file on the filesystem) and each user must be able to read and write to this socket so that both can control the tmux session.

For those wanting to be more restrictive, one could create a tmux group and assign specific users to this group. Nevertheless, using the users group here does the job nicely, especially for the laptop-based (effectively single user) systems used here.

Share a tmux session

To initialise the shared tmux session on the host computer, run:

$ tmux -S /tmp/sharedtmux new -s shared

This will create the special file sharedtmux under /tmp over which the session is shared and creates a new tmux session named shared.

We need to ensure that both users can access (read from and write to) the shared socket, so we change the group of the socket file to belong to the users group:

$ chgrp users /tmp/sharedtmux

The guest user then logs in via ssh and attaches to the shared session via:

$ tmux -S /tmp/sharedtmux attach -t shared

Now it’s possible for both users to type in the terminal. In order to reduce confusion it’s recommended that only one person type at a time!

Working together on your own computer: a win-win situation

At one point in time we used to use an external monitor connected to one of the laptops and both people in the pair would look at the same monitor. This way we could sit next to one another and point at code on the screen.

As it turns out this isn’t necessary, since both people have their own screen, and highlighting something is simple in tmux, so we either sit at our respective desks, or use the beanbags in our office1:

Beanbags in the Drift+Noise office

This allows us to be much more flexible with our working environment. The main thing, of course, is that we can talk to one another in order to discuss the changes that are being made or explain why something is being done the way it is.

Another advantage of this setup is that each participant is able to type more comfortably by using their own keyboard. If it were necessary to share a single physical keyboard this would reduce the efficiency of the programming session due to the time involved in shifting the keyboard between parties, as well as the cognitive break required in having to swap keyboards; the programming flow is thus better maintained with two separate keyboards.

One further advantage of this setup is that if the keyboard layouts are different, it doesn’t matter since the same characters end up getting through to tmux. This is handy if one of you has e.g. a German keyboard layout and the other has a US-English keyboard layout. Thus each person can work comfortably in their own most familiar environment.

Remote pair programming needs verbal communication

A further cool thing about this setup is that not much needs to be changed in order for it to work remotely. The missing ingredients are a VPN so that the login via ssh still works, and (most importantly) a verbal communication channel. We often use Telegram for this purpose, but one could use Skype or Google Hangouts or something similar. The main thing is that it’s possible to discuss what’s happening on the screen easily and that the work can flow with as little friction as possible.

The social setup

Not only are the technical aspects interesting but also the social aspects. Two people working on the one problem at the same time definitely changes the dynamics of development; my impression of pair programming for work tasks has on the whole been very positive. Here are some of my observations:

  • There is much more discussion. This seems an obvious observation, however it’s very important: if details of development aren’t discussed, then knowledge about the project isn’t transfered, potential solutions aren’t discussed, and it probably wouldn’t be as much fun. I find I try to explain what I’m doing as I type so that not only my colleague knows what I’m doing and why, but also I myself!
  • Work can also be a game. We try to make development game-like by swapping between writing tests and writing production code: first one person writes a test for some new functionality, then the other tries to write the minimum amount of code to get the test to pass. This helps ensure that both developers are actively involved in development and that one party doesn’t necessarily dominate by doing most of the coding, or the other doesn’t get bored and distracted.
  • One drives, the other thinks. Although both can type simultaneously, it’s important that this doesn’t happen since one person is thinking more or less exclusively about the problem while the other enters code, which leads to questions such as “hey, why are we doing it like that?”, or “wouldn’t it be an idea to consider this approach?”. Such questions stimulate thought and lead to discussion of potentially better solutions for the task at hand.
  • Project milestones can be celebrated. Such things like the addition of a new feature, or little things like the first commit to the main repository, or the first push to production can be celebrated, (e.g. with a high-five) giving the feeling that things are moving forward.
  • Don’t be a dominant driver. Sometimes one party drives more than the other (often the more experienced of the pair), and one needs to be careful not to type too much; the active, coding part is important for learning and gaining experience.
  • Assertive navigation is important. My colleague is very good at stopping me when he doesn’t understand something, which I believe to be a good habit as part of the social aspects of pair programming. By me having to explain the code, the situation, or the concepts, I get to understand the problem and its solution better myself, and sometimes we’ve come up with better solutions, since in the explaining it’s become clear that an alternative way of solving the problem would actually do a better job.
  • Have an open mind and be prepared to listen. My colleague often has different perspectives to a problem which I might not have seen and thus the solution space is much larger, leading sometimes to better solutions than I would have thought of alone.
  • The development intensity is higher. We tend to code hard out from the beginning of the day until lunchtime and then after lunch until the day’s end. Keeping up this intensity when working alone can be difficult.
  • It is still necessary to work alone. Although pair programming is a fun and productive way to get work done, there are times when one needs some quiet time working on tasks alone.

Conclusion

Pair programming is a fun and effective means of getting work done, it aids production of good quality code, and it helps knowledge transfer within a team. Because our setup uses console-based tools, it’s very low on resources (especially network bandwith). Also, our setup works well both locally and remotely, giving both participants a lot of flexibility in their working environment. I hope it works as well for you as it does for us!

  1. It’s fun to say this in German: die Sitzsäcke in der Sitzecke.