Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@
"theme": "light"
},
"activationEvents": [
"onLanguage:ino",
"onCommand:arduino.debug.start",
"onCommand:arduino.languageserver.start"
],
"contributes": {
Expand Down Expand Up @@ -93,8 +95,13 @@
"commands": [
{
"command": "arduino.languageserver.start",
"title": "Arduino: Start/Restart Language Server",
"description": "Start the language server or restart if there is a running instance"
"title": "Start Language Server",
"category": "Arduino"
},
{
"command": "arduino.debug.start",
"title": "Start Debug",
"category": "Arduino"
}
]
}
Expand Down
69 changes: 68 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import deepEqual from 'deep-equal';
import WebRequest from 'web-request';
import { join } from 'path';
import { spawnSync } from 'child_process';
import vscode, { ExtensionContext } from 'vscode';
import { LanguageClient, CloseAction, ErrorAction, InitializeError, Message, RevealOutputChannelOn } from 'vscode-languageclient';

Expand All @@ -19,6 +21,29 @@ interface LanguageServerConfig {
readonly flags?: string[];
}

interface DebugConfig {
readonly cliPath: string;
readonly board: {
readonly fqbn: string;
readonly name?: string;
}
readonly sketchPath: string;
}

interface DebugInfo {
readonly executable: string;
readonly toolchain: string;
readonly toolchain_path: string;
readonly toolchain_prefix: string;
readonly server: string;
readonly server_path: string;
readonly server_configuration: {
readonly path: string;
readonly script: string;
readonly scripts_dir: string;
}
}

let languageClient: LanguageClient | undefined;
let languageServerDisposable: vscode.Disposable | undefined;
let latestConfig: LanguageServerConfig | undefined;
Expand All @@ -28,10 +53,52 @@ let crashCount = 0;

export function activate(context: ExtensionContext) {
context.subscriptions.push(
vscode.commands.registerCommand('arduino.languageserver.start', (config: LanguageServerConfig) => startLanguageServer(context, config))
vscode.commands.registerCommand('arduino.languageserver.start', (config: LanguageServerConfig) => startLanguageServer(context, config)),
vscode.commands.registerCommand('arduino.debug.start', (config: DebugConfig) => startDebug(context, config))
);
}

async function startDebug(_: ExtensionContext, config: DebugConfig): Promise<boolean> {
let info: DebugInfo | undefined = undefined;
try {
const args = ['debug', '-I', '-b', config.board.fqbn, config.sketchPath, '--format', 'json'];
const rawInfo = spawnSync(config.cliPath, args, { encoding: 'utf8' }).stdout.trim();
info = JSON.parse(rawInfo);
} catch (err) {
const message = err instanceof Error ? err.stack || err.message : 'Unknown error';
vscode.window.showErrorMessage(message);
return false;
}
if (!info) {
return false;
}
const debugConfig = {
cwd: '${workspaceRoot}',
name: 'Arduino',
request: 'launch',
type: 'cortex-debug',
executable: info.executable,
servertype: info.server,
serverpath: join(info.server_path, info.server),
armToolchainPath: info.toolchain_path,
configFiles: [
info.server_configuration.script
]
};
// Create the `launch.json` if it does not exist. Otherwise, update the existing.
const configuration = vscode.workspace.getConfiguration();
const launchConfig = {
version: '0.2.0',
'configurations': [
{
...debugConfig
}
]
};
await configuration.update('launch', launchConfig, false);
return vscode.debug.startDebugging(undefined, debugConfig);
}

async function startLanguageServer(context: ExtensionContext, config: LanguageServerConfig): Promise<void> {
if (languageClient) {
if (languageClient.diagnostics) {
Expand Down