Using VScode for Sonic Pi
Tags: vscode, sonicpi
Published: 2020-07-22 06:02:19

I love Sonic Pi, but I'd prefer using VScode over the default editor. An extension is currently in the works. Here are some relevant links:
- [VS Code extension](https://in-thread.sonic-pi.net/t/vs-code-extension/3935/38)
- [llloret/sonic-pi-vscode-editor](https://github.com/llloret/sonic-pi-vscode-editor)

Until then, here's a quick and simple way to run/play Sonic Pi music from VScode directly.

## 1. Install [sonic-pi-cli](https://github.com/Widdershin/sonic-pi-cli) 👨‍💻

Sonic-pi-cli can be installed by running:

```bash
gem install sonic-pi-cli
```

Check out their [GitHub repository](https://github.com/Widdershin/sonic-pi-cli) for more details.

{% github Widdershin/sonic-pi-cli %}

Once it's been installed, make sure it's working properly. Keep the Sonic Pi app running, then run the following command in your terminal:

```bash
sonic_pi play 50
```

> The Sonic Pi app needs to be running for sonic-pi-cli to work.


## 2. Using sonic-pi-cli to play a file 🎵

Say for example, you have your Sonic Pi code in `music.rb`. Run 

```bash
cat music.rb | sonic_pi
```

to play the music.

If you don't understand what this command does, you can read more [here](https://www.geeksforgeeks.org/piping-in-unix-or-linux/). In short, the pipe (`|`) passes the output of a command to another command.

To stop the music playing, run

```bash
sonic_pi stop
```

## 3. Configuring keyboard shortcuts ⌨️

Running `cat music.rb | sonic_pi` and `sonic_pi stop` every time is a little annoying. Luckily, VScode makes it easier to defne custom **tasks** and **keyindings**. 

### Tasks
To open `tasks.json`, use the keyboard shortcut `cmd+shift+P`. Type `>Tasks: Open user tasks`, and you should see a JSON file that looks like this:

```json
{
  // See https://go.microsoft.com/fwlink/?LinkId=733558
  // for the documentation about the tasks.json format
  "version": "2.0.0",
  "tasks": [
  ]
}
```

We need to add 2 tasks:
1. To start playing the **current file** with Sonic Pi: `cat <current file> | sonic_pi`
2. To stop playing: `sonic_pi stop`.

We also have to give them unique labels. I'm going to use `sp-run` and `sp-stop`.

Now edit `tasks.json`:

```json
{
  // See https://go.microsoft.com/fwlink/?LinkId=733558
  // for the documentation about the tasks.json format
  "version": "2.0.0",
  "tasks": [
    // PLAY MUSIC
    {
      "label": "sp-run",
      "type": "shell",
      "command": "cat ${file} | sonic_pi"
    },

    // STOP PLAYING
    {
      "label": "sp-stop",
      "type": "shell",
      "command": "sonic_pi stop"
    }
  ]
}
```

As you can see, the task `sp-run` runs the shell command `cat ${file} | sonic_pi`, and `sp-stop` runs the command `sonic_pi stop`.

### Keybindings
Now we need to add keybindings to these tasks.

To open `keybindings.json`, use the keyboard shortcut `cmd+K cmd+s`. Click the button at the top right to open it in the JSON format. It should like similar to this:
```json
// Place your key bindings in this file to override the defaults
[
  // ..
  // all of your keybindings
  // ...
]
```

To bind a keyboard shortcut to a task, we have to set its `command` to `workbench.action.tasks.runTask`. We also want to limit this keyboard shortcut to ruby (`.rb`) files.

Edit `keybindings.json`:

```json
// Place your key bindings in this file to override the defaults
[
  // ..
  // all your other keybindings
  // ...
  
  // for sonic pi
  {
    "key": "ctrl+alt+s",
    "command": "workbench.action.tasks.runTask",
    "args": "sp-run",
    "when": "editorLangId == ruby" // limit these keybindings to work in ruby files
  },
  {
    "key": "ctrl+alt+d",
    "command": "workbench.action.tasks.runTask",
    "args": "sp-stop",
    "when": "editorLangId == ruby"
  }
]
```

I've added `ctrl+alt S` to play the file, and `ctrl+alt D` to stop. Feel free to change them.

To make sure this works, create a file with the extension `.rb`, and some code:

```ruby
live_loop :main do
  play :E4
  sleep 1
end
```

Start the Sonic Pi app,

Now use the keyboard shortcut you defined for `sp-run`, (`ctrl+alt S` in this example), and you should here the music playing!

Make a change. For example:

```ruby
live_loop :main do
  play :C4  # <-- change
  sleep 1
end
```

Use the keyboard shortcut (`ctrl+alt S`) to play the music again. Great! No need to stop playing every time you make a change!

Finally, top stop the music playback, use the keyboard shortcut for `sp-stop` (`ctrl+alt D` in this example)

## Logs 📝

Unfortunately, logs cannot be shown in VScode (yet). But you can still view them in the Sonic Pi app.

## Files 📁
If you would like to refer to any files changed in this tutorial, check out the [GitHub gist](https://gist.github.com/ninest/da9a240a33ac80f82ff95a4c39c2d31f).

## References 📖
- [Key Bindings for Visual Studio Code](https://code.visualstudio.com/docs/getstarted/keybindings)
- [r/vscode: Can I get keyboard shortcuts to only work on files of a specific extension? ](https://www.reddit.com/r/vscode/comments/h8cy6z/can_i_get_keyboard_shortcuts_to_only_work_on/)