# Synesthete Hear the state of your code in Sublime Text. Synesthete plays your code. The music walks through it line by line on recorded instruments, so every file has its own melody, and when the code changes the music jumps to where it changed. How good the code is decides how the music sounds: beautiful code is a harp over a cello section; worse code moves to marimba, then piano in a minor key, then tubular bells and a droning contrabass, until cursed code is a singing saw sliding over trembling strings, gongs and bowed cymbals. Changes also get a short accent: rising if things got better, falling if they got worse. ## Stages | Health | Stage | Sound | | --------- | --------- | ----------------------------------------------------------- | | 0.90–1.00 | beautiful | harp in major pentatonic, glockenspiel, cello section | | 0.75–0.90 | good | harp in major, pizzicato bass | | 0.60–0.75 | decent | marimba in open fourths and fifths, pizzicato bass | | 0.45–0.60 | meh | piano in minor, cello section | | 0.30–0.45 | bad | sparse piano in Phrygian, tubular bells, sustained bass | | 0.15–0.30 | awful | detuned piano clusters, tubular bells, cello tremolo, timpani | | 0.00–0.15 | cursed | a singing saw over contrabass tremolo, gongs, bowed cymbal | As things get worse the tempo slows, the timing loosens, notes drop out, the tuning drifts and the room grows from a small hall into a cavern. ## How the code becomes music Each line is one step. Its indentation sets how high it sits in the stage's scale, so deeper code climbs; a hash of its text nudges the note, so different lines make different melodies while identical lines sound identical (duplicated code sounds repetitive); and its length sets how hard it's played. Blank lines are rests. Comments ring on a second instrument, lines that start functions bring in the bass, and lines the syntax definition flags as broken sound a dissonant cluster as the music passes them. Eight lines make a bar; each bar is rendered once and cached, so code that hasn't changed costs nothing to play again. The instruments are real recordings from [VSCO 2 Community Edition](https://versilian-studios.com/vsco-community/), which is public domain; see [samples/README.md](samples/README.md). The singing saw, an almost pure tone, is synthesized. ## How code is judged **Quality** starts at 1.0 and falls toward 0.3 as smells pile up: functions longer than 40 lines, functions with more than 10 branches, code nested more than four levels inside its function (lines inside brackets, such as arguments, nested arrays or hash literals, continue an expression rather than nest; blocks still nest), duplicated chunks, lines longer than your widest ruler (not counting URLs, which can't be broken), trailing whitespace, tabs mixed with spaces, and TODO, FIXME, XXX and HACK comments. Smells count in proportion to the file's size, so one long function sinks a short file more than a long one. Mess alone never drops below bad. **Bugs** divide what's left: spans the syntax definition marks as `invalid` (code it cannot parse) and brackets that never close, outside strings and comments. One bug in beautiful code sounds meh, two bad, three awful, eight cursed. Syntax highlighting misses a lot of broken code, such as a Ruby class without its `end`, so Synesthete also asks the language's own parser: `ruby -c`, Python's `ast`, `node --check`, `bash -n` and `php -l`. None of them run the code. A file that doesn't parse counts as at least three bugs. Add other languages in the `syntax_checkers` setting. Everything comes from Sublime's own syntax definitions (scopes such as `entity.name.function` and `keyword.control.conditional`), so it works for any language with a decent syntax. `Synesthete: Explain Score` shows what went into the current score, and the status bar shows the stage. ## Listening to a file or a project - **file** (default): the file you are looking at, as you type. While no code file is open, the window's project plays instead. - **project**: every source file in the window's folders, as it changes on disk. Made for coding agents: you don't need to look at any file to hear the agent work. The music walks through every file in the project, one after another. Each file the agent writes plays an accent in that file's stage, rising or falling with the change, and the music jumps to where it changed, then walks on from there. The stage follows the whole project: quality averaged by file size, with every bug in every file counted. Synesthete checks for changes twice a second and skips whatever git ignores. Switch with `Synesthete: Listen to File` and `Synesthete: Listen to Project`. Synesthete follows you between windows and files, switching at the end of the bar. When the window or file it's playing closes, it moves on to whatever is open, and when nothing is, it fades out, the same as when you quit. ## The map `Synesthete: Show Map` opens a tab with a bird's-eye view of the code: every file is a tile, grouped by folder, as wide as the file is long and colored by its stage. A file that changes lights up and fades over ten seconds, so you can watch an agent move through the project; broken files carry a ⚠, and clicking a tile opens its file. Above the tiles, a timeline shows the last ten minutes of health, with a tick for every change: green when it got better, red when it got worse. In file mode the map shows the open files. ## The visualizer `Synesthete: Open Visualizer` opens a browser tab where you fly through a tunnel made of your code: each file is a band of color around its walls, in its stage's color, as wide as the file is long. How healthy the code is decides how the flight feels. Beautiful code is a fast, smooth, neon flight toward a bright light; as it gets worse the tunnel slows, twists and sways, the colors bruise, and at the bottom the picture tears and splits and the light at the end goes out. Every change sends light racing down the tunnel from its file, green when it got better and red when it got worse. Nothing flashes more than twice a second, the rings are kept soft, and the motion calms down when macOS's Reduce Motion setting is on. The page talks to Sublime through a small server on 127.0.0.1 that only answers requests carrying the random token in the page's address. To try it without Sublime, run `python3 tools/visualizer_demo.py` and open the address it prints. ## The tiles `Synesthete: Open Tiles` opens a browser tab with every file as a tile, laid out in path order in one square, like a contribution graph, and colored by its health, from green for beautiful through yellow and orange to dark red for cursed. A file that changes glows and fades over a few seconds, ringed green when it got better and red when it got worse; broken files carry a dot. Hover a tile to see its file and score. It runs on the visualizer’s server, and `python3 tools/visualizer_demo.py` prints its address too. ## Modes - **ambient** (default): the code played continuously, plus the accents. When the stage changes, the next bar starts right away. - **chime**: only the accents, and a bar when the stage changes. ## Install With [Package Control](https://packagecontrol.io): run `Package Control: Install Package` and pick `Synesthete`. By hand: link this folder into Sublime Text's `Packages` folder under the name `Synesthete`. On macOS: ```bash ln -s "$PWD" "$HOME/Library/Application Support/Sublime Text/Packages/Synesthete" ``` Then run `Synesthete: Play All Stages` from the command palette to hear the current file in every stage. Requires Sublime Text 4. Sound is played with `afplay` on macOS and `paplay`, `pw-play`, or `aplay` on Linux. On Windows it uses `winsound`, which cannot overlap sounds, so each sound cuts off the one before. ## Usage Synesthete plays as soon as it’s installed: - Open a code file to hear it change as you type. Open a folder without opening a file to hear the whole project. - Working with a coding agent? Run `Synesthete: Listen to Project` to hear every file in the window’s folders as the agent changes them, whichever file you’re looking at. - Run `Synesthete: Open Visualizer` to fly through the tunnel, `Synesthete: Open Tiles` to watch files glow as they change, or `Synesthete: Show Map` to see every file at a glance. - Run `Synesthete: Explain Score` to see why the code sounds the way it does. - If continuous music is too much, `Synesthete: Chime Mode` plays only the accents. - `Synesthete: Toggle` turns it off, and it stays off until you turn it on again. ## Commands - `Synesthete: Toggle` - `Synesthete: Listen to File` and `Synesthete: Listen to Project` - `Synesthete: Ambient Mode` and `Synesthete: Chime Mode` - `Synesthete: Play Now` plays a bar of the current code - `Synesthete: Explain Score` - `Synesthete: Show Map` - `Synesthete: Open Visualizer` - `Synesthete: Open Tiles` - `Synesthete: Play All Stages` - `Preferences: Synesthete Settings` - `Preferences: Synesthete Key Bindings` The same commands are under Tools > Synesthete. Synesthete adds no key bindings. To toggle it with ctrl+alt+s, run `Preferences: Synesthete Key Bindings` and copy the example on the left to your key bindings on the right: ```json { "keys": ["ctrl+alt+s"], "command": "synesthete_toggle" } ``` ## Tests ```bash python3 -m unittest discover -s tests ```