Skip to content

Commit

Permalink
Some improvements
Browse files Browse the repository at this point in the history
- Run selected code with alt-t (or cmd-t on Mac),not the full buffer
- Highlight errors as reported by the Sonic Pi server
- Root path setting, in case the default one does not work for you
- Send the force mono and invert stereo options to the server,
so now they actually do something
- Some code reorganization and white space and formatting fixes
  • Loading branch information
llloret committed May 28, 2020
1 parent b517f3a commit f88a955
Show file tree
Hide file tree
Showing 5 changed files with 294 additions and 106 deletions.
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,18 @@ This is just starting, but we already have enough features to have some fun!
- ruby: launches the server when there is a ruby file visible in vscode (this is the default)
- custom: launches the server when there is a file with your given custom extension visible in vscode
- never: do not launch the server automatically (use the Sonic Pi: Start Server command)
- Configurable Sonic Pi root path, in case the default does not work for you
- Can run code pressing Alt-R (or Cmd-R on Mac, just like in Sonic Pi's editor) or with command palette "Sonic Pi: Run" (see [Screenshot](image/command-palette.png))
- Can stop running audio with Alt-S (or Cmd-S on Mac) or "Sonic Pi: Stop"
- Can run the selected code with Alt-T (or Cmd-T on Mac). If there is no code selected, it will offer to run the whole file instead (and persist the choice)
- Shows logs and cues in the output panel (see [logs](image/output-pane.png) and [cues](image/output-pane-cues.png))
- Some snippets like live_loop, effects, synths, samples, and possibly more coming soon. See the snippets directory for the full list, and contribute new ones if you feel like it!
- fx -> instantiate effect with automcomplete list chooser
- Some snippets like live_loop, effects, synths, samples, and possibly more coming soon. See the snippets directory for the full list and contribute new ones if you feel like it!
- fx -> instantiate effect with autocomplete list chooser
- fx x (where x is a letter) -> effect instantiation
- us -> instantiate synth with autocomplete list chooser
- us x (where x is a letter) -> specific synth instantiation
- sa -> instantiate sample with automcomplete list chooser
- sa -> instantiate sample with autocomplete list chooser
- Highlight errors as reported by the Sonic Pi server
- And of course, you have syntax highlighting, autoformatting, all the goodies that you usually have with vscode!

* See a very short video of Robin Newman's arrangement of "Pase El Agua" launched from this extension, showing
Expand All @@ -48,8 +51,9 @@ The extension runs in development mode. Follow these steps:

If you run into problems, let me know, and I'll do my best to help you set this up.

**Make sure you configure the paths in main.ts (rootPath and rubypath) to match your own system.** This will
be automated or offer better configuration / platform dependent defaults in the future.
**Make sure you configure the Sonic Pi root path in the configuration if the default setting does not work for you**
Open Settings -> Extensions -> Sonic Pi -> Sonic Pi Root Directory


## Known Issues

Expand Down
3 changes: 1 addition & 2 deletions TODO
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
A list of things that would be nice to have
- Add setting to change Sonic Pi's root path if the default does not work
- Sonic Pi help
- Better diagnostics in case the server does not start
- Colorize output panel (log and cues), if possible
- Syntax highlight synths and FX
- Show useful feedback when there is an error (/syntax osc message)
- I18n

37 changes: 26 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@
"title": "Run",
"category": "Sonic Pi"
},
{
"command": "sonicpieditor.runselected",
"title": "Run selected text",
"category": "Sonic Pi"
},
{
"command": "sonicpieditor.stop",
"title": "Stop",
Expand All @@ -51,6 +56,12 @@
"mac": "cmd+r",
"when": "editorTextFocus"
},
{
"command": "sonicpieditor.runselected",
"key": "alt+t",
"mac": "cmd+t",
"when": "editorTextFocus"
},
{
"command": "sonicpieditor.stop",
"key": "alt+s",
Expand All @@ -71,6 +82,11 @@
"configuration": {
"title": "Sonic Pi",
"properties": {
"sonicpieditor.sonicPiRootDirectory": {
"type": "string",
"description": "Set Sonic Pi installation directory.\nOnly use this if the default does not work for you."

},
"sonicpieditor.launchSonicPiServerAutomatically": {
"type": "string",
"enum": [
Expand All @@ -85,12 +101,21 @@
"Do not start the server automatically (must launch it manually through the Sonic Pi: Start Server command)",
"Start the server when opening a custom file extension - enter in the Launch Sonic Pi Server Custom Extension setting"
],
"default": "ruby",
"description": "Launch Sonic Pi Server automatically when..."
},
"sonicpieditor.launchSonicPiServerCustomExtension": {
"type": "string",
"description": "If the Launch server automatically setting is set to custom, what extension triggers the launch?"
},
"sonicpieditor.runFileWhenRunSelectedIsEmpty": {
"type": "string",
"enum": [
"always",
"never"
],
"description": "If there is no selection when Run selected is triggered, run the whole file"
},
"sonicpieditor.invertStereo": {
"type": "boolean",
"default": false,
Expand All @@ -104,17 +129,7 @@
"sonicpieditor.safeMode": {
"type": "boolean",
"default": true,
"description": "Synth argument checking functions"
},
"sonicpieditor.logSynths": {
"type": "boolean",
"default": true,
"description": "Log the synths"
},
"sonicpieditor.logCues": {
"type": "boolean",
"default": true,
"description": "Log the cues"
"description": "Synth argument checking functions.\nIf disabled, certain synth opt values may\ncreate unexpectedly loud or uncomfortable sounds."
},
"sonicpieditor.logAutoscroll": {
"type": "boolean",
Expand Down
87 changes: 65 additions & 22 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,78 +24,121 @@
// what you have in tab 9 on your Sonic Pi session. This should be smarter in the future, and
// I think there are plans to make this more flexible on Sonic Pi's side

// At the moment this has been tested on Windows... my Linux VM with Linux Mint refuses to
// At the moment this has been tested on Windows... my Linux VM with Linux Mint refuses to
// start Supercollider. Something to do with jackd and pulseaudio. Will investigate later.
// It would be great if someone can check if it works in Linux, and provide a PR if it doesn't.

import * as vscode from 'vscode';
const { v4: uuidv4 } = require('uuid');
const OSC = require('osc-js');

import { Main } from './main';

export function activate(context: vscode.ExtensionContext) {
console.log('Ruby detected. Sonic Pi editor extension active!');

// create an uuid for the editor
let guiUuid = uuidv4();

let main = new Main();
let config = vscode.workspace.getConfiguration('sonicpieditor');
if (config.launchSonicPiServerAutomatically === 'start'){
main.startServer();
}

let isRecording = false;

// Register the editor commands. For now, run, stop and recording. Those should be enough for
// some initial fun...
let disposable = vscode.commands.registerCommand('sonicpieditor.startserver', () => {
let disposable = vscode.commands.registerCommand('sonicpieditor.startserver', () => {
main.startServer();
});

disposable = vscode.commands.registerTextEditorCommand('sonicpieditor.run', (textEditor) => {
disposable = vscode.commands.registerTextEditorCommand('sonicpieditor.run', (textEditor) => {
let doc = textEditor.document;
// If the focus is on something that is not ruby (i.e. something on the output pane),
// If the focus is on something that is not ruby (i.e. something on the output pane),
// run the first found open ruby editor instead
if (doc.languageId !== 'ruby'){
let textEditors = vscode.window.visibleTextEditors;
let rubyEditors = textEditors.filter((editor) => {
return editor.document.languageId === 'ruby';
});

// TODO: if no ruby editors, show a warning to indicate that this will not have effect
if (!rubyEditors.length){
return;
}
doc = rubyEditors[0].document;
}
let code = doc.getText();
var message = new OSC.Message('/run-code', guiUuid, code);
main.sendOsc(message);
main.sendRunCode(code);
});


disposable = vscode.commands.registerTextEditorCommand('sonicpieditor.runselected', (textEditor) => {
let doc = textEditor.document;
// If the focus is on something that is not ruby (i.e. something on the output pane),
// run the first found open ruby editor instead
if (doc.languageId !== 'ruby'){
let textEditors = vscode.window.visibleTextEditors;
let rubyEditors = textEditors.filter((editor) => {
return editor.document.languageId === 'ruby';
});

// TODO: if no ruby editors, show a warning to indicate that this will not have effect
if (!rubyEditors.length){
return;
}
doc = rubyEditors[0].document;
}
let code = doc.getText(textEditor.selection);
if (!code){
let runFileWhenRunSelectedIsEmpty = vscode.workspace.getConfiguration('sonicpieditor').runFileWhenRunSelectedIsEmpty;
if (!runFileWhenRunSelectedIsEmpty){
vscode.window.showWarningMessage('You tried to Run selected code with no code selected.' +
'Do you want to run the whole file when this happens?', 'Yes, once', 'Yes, always', 'No, never').then(
item => {
if (item === 'Yes, once'){
code = doc.getText();
main.sendRunCode(code);
}
else if (item === 'Yes, always'){
vscode.workspace.getConfiguration('sonicpieditor').update('runFileWhenRunSelectedIsEmpty', 'always', true);
code = doc.getText();
main.sendRunCode(code);
}
else if (item === 'No, never'){
vscode.workspace.getConfiguration('sonicpieditor').update('runFileWhenRunSelectedIsEmpty', 'never', true);
}
}
);
return;
}
else if (runFileWhenRunSelectedIsEmpty === 'never'){
return;
}
else if (runFileWhenRunSelectedIsEmpty === 'always'){
code = doc.getText();
main.sendRunCode(code);
}

}
main.sendRunCode(code);
});


disposable = vscode.commands.registerCommand('sonicpieditor.stop', () => {
var message = new OSC.Message('/stop-all-jobs', guiUuid);
main.sendOsc(message);
main.sendStopAllJobs();
});

disposable = vscode.commands.registerCommand('sonicpieditor.togglerecording', () => {
isRecording = !isRecording;
if (isRecording){
var message = new OSC.Message('/start-recording', guiUuid);
main.sendOsc(message);
main.sendStartRecording();
}
else{
var message = new OSC.Message('/stop-recording', guiUuid);
main.sendOsc(message);
main.sendStopRecording();
vscode.window.showSaveDialog({filters: {'Wave file': ['wav']}}).then(uri => {
if (uri){
var message = new OSC.Message('/save-recording', guiUuid, uri.fsPath);
main.sendOsc(message);
main.sendSaveRecording(uri.fsPath);
}
else{
var message = new OSC.Message('/delete-recording', guiUuid);
main.sendOsc(message);
main.sendDeleteRecording();
}
});
}
Expand Down
Loading

0 comments on commit f88a955

Please sign in to comment.