DEV Community

Luke Barnard
Luke Barnard

Posted on

Emulating Xmonad in JavaScript

One of my biggest obsessions is developing as fast as I can type on a keyboard. It has gotten so bad at times that previous managers of mine have suggested adding another column to the Kanban board for dev env optimisation just for me!

You might have seen another post that I wrote about how I deal with the pain of organising my terminals in macOS. Having used xmonad at work for over two years, I couldn't be happier - it's simple, quick and I feel unrestricted despite only using a single monitor. Xmonad does support multiple monitors but I find switching between monitors quite slow, not least for the increased cursor action.

Anyway, I want to explain my most recent project to reinvent my dev env at home. This is an attempt to use the same environment whether I'm at home or work. I'm sure many are faced with a similar dilemma where a Mac is best at home and of course linux is best at work (aside from those working hard on programs that must be developed on macOS or Windows or other proprietary software environents).

To that end, here is my progress so far. This GIF shows shmonad.js (renaming TBC) with the user giving some very basic interactions.

In the GIF, you can see a few boxes being drawn into the terminal. It's not much but eventually this will be a fully-fledged grid-organised terminal multiplexer that I will absolutely put on GitHub for those interested in running it.

Longer term I imagine a plugin-based system that allows for more functionality but let's not get ahead of the game.

How does this work?

Terminal Control Sequences

A while back, terminals were physical devices that came complete with a keyboard, a screen and that's about it. Until floating windows and cursors came along, this was all there was in the way of computer interaction.

In 1978, the VT100 video terminal was introduced by Digital Equipment Corporation, one of the first terminals to support ANSI escape codes.

If you haven't heard of escape codes or escape sequences in the context of terminals, fair enough - you'll almost never encounter them in your daily usage of a terminal as an end user. Essentially, these control sequences allow control of the terminal itself via the output of a program. These control sequences allow programs to control, for example, the colour of the text being sent to standard output or the current location of the cursor within a terminal.

At the time, each terminal shipped with different control sequences and so programs using control sequences were either only compatible with certain terminals or they were forced to use libraries such as Termcap in order to maintain portability.

The ANSI escape codes were proposed as a standard that all terminals could use, making portability of terminal interfaces much simpler. The resulting standard was adopted in 1976 as ECMA-48 (you may recognise ECMA from ECMAScript or ECMA-262, of which JavaScript is a well-know implementation).

Anyway, history lesson over. What are these control sequences and how do they manifest?

You may have encountered them more than you might expect.

Take for example, the very popular shell program, Bash. Bash is a widely-used shell program that allows the user to run commands, build scripts and view program output in a fairly intuitive way. A common misconception is that Bash is a terminal. This is actually false, Bash is a shell program that is most commonly run in a terminal.

For example, I'm writing this article in the following stack:

  • Vim
  • (Bash)
  • ...
  • macOS

So in my case, Bash (a shell) happens to be running in (the ... terminal).

As I type these words, they appear in within Vim, which displays a text editor GUI in my terminal. It does this by sending control sequences to my terminal (via Bash). Bash isn't doing anything at the moment but if I hit <CTRL-Z>, Bash actually interrupts Vim by pausing it and giving me direct access to Bash again.

You might not think about it too much when you're running commands in Bash, but Bash (and other shell programs) also use control sequences to provide features including coloured text, tab completion, history selection, that annoying "ding" or "beep" you hear when you reach the end of history or if there's nothing to complete when you hit tab, and many more!


I hope that gave you a better understanding of the foundation upon which my new project rests upon.

Let's call it a day and I'll post another update soon about the inner workings of this terminal multiplexer I'm writing.

Thanks for reading. Leave a comment! See you next time!

Top comments (1)

rounakcodes profile image
rounakcodes • Edited

Why are you confusing a window manager for a terminal multiplexer?