Using VScode for Sonic Pi

Configuring tasks and keybindings in VScode for Sonic Pi

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:

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

1. Install sonic-pi-cli 👨‍💻

Sonic-pi-cli can be installed by running:

gem install sonic-pi-cli

Check out their GitHub repository for more details.

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:

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

cat music.rb | sonic_pi

to play the music.

If you don't understand what this command does, you can read more here. In short, the pipe (|) passes the output of a command to another command.

To stop the music playing, run

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:

{
  // 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:

{
  // 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:

// 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:

// 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:

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:

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.

If you would like to refer to any files changed in this tutorial, check out the GitHub gist.

References 📖

If you liked this, please like and comment on Dev.to 😁