From 768aa4259fce15f313042892739ed4d8b7e518b4 Mon Sep 17 00:00:00 2001 From: Tim Date: Mon, 30 Mar 2020 18:12:22 +0100 Subject: Add basic task support This adds basic support for running `cargo build`, `cargo run`, etc. --- editors/code/src/client.ts | 5 ++-- editors/code/src/ctx.ts | 9 +++++-- editors/code/src/main.ts | 9 ++++++- editors/code/src/tasks.ts | 60 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 editors/code/src/tasks.ts (limited to 'editors') diff --git a/editors/code/src/client.ts b/editors/code/src/client.ts index d72ecc58f..c9819e457 100644 --- a/editors/code/src/client.ts +++ b/editors/code/src/client.ts @@ -30,15 +30,14 @@ export function configToServerOptions(config: Config) { }; } -export async function createClient(config: Config, serverPath: string): Promise { +export async function createClient(config: Config, serverPath: string, workspaceFolder: vscode.WorkspaceFolder | null): Promise { // '.' Is the fallback if no folder is open // TODO?: Workspace folders support Uri's (eg: file://test.txt). // It might be a good idea to test if the uri points to a file. - const workspaceFolderPath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath ?? '.'; const run: lc.Executable = { command: serverPath, - options: { cwd: workspaceFolderPath }, + options: { cwd: workspaceFolder?.uri.fsPath ?? '.' }, }; const serverOptions: lc.ServerOptions = { run, diff --git a/editors/code/src/ctx.ts b/editors/code/src/ctx.ts index d2f49cd23..0e705bc84 100644 --- a/editors/code/src/ctx.ts +++ b/editors/code/src/ctx.ts @@ -15,8 +15,13 @@ export class Ctx { } - static async create(config: Config, extCtx: vscode.ExtensionContext, serverPath: string): Promise { - const client = await createClient(config, serverPath); + static async create( + config: Config, + extCtx: vscode.ExtensionContext, + serverPath: string, + workspaceFolder: vscode.WorkspaceFolder | null, + ): Promise { + const client = await createClient(config, serverPath, workspaceFolder); const res = new Ctx(config, extCtx, client, serverPath); res.pushCleanup(client.start()); await client.onReady(); diff --git a/editors/code/src/main.ts b/editors/code/src/main.ts index a46dbde33..40701e4f5 100644 --- a/editors/code/src/main.ts +++ b/editors/code/src/main.ts @@ -13,6 +13,7 @@ import { log, assert } from './util'; import { PersistentState } from './persistent_state'; import { fetchRelease, download } from './net'; import { spawnSync } from 'child_process'; +import { activateTaskProvider } from './tasks'; let ctx: Ctx | undefined; @@ -41,11 +42,13 @@ export async function activate(context: vscode.ExtensionContext) { const state = new PersistentState(context.globalState); const serverPath = await bootstrap(config, state); + const workspaceFolder = vscode.workspace.workspaceFolders?.[0] ?? null; + // Note: we try to start the server before we activate type hints so that it // registers its `onDidChangeDocument` handler before us. // // This a horribly, horribly wrong way to deal with this problem. - ctx = await Ctx.create(config, context, serverPath); + ctx = await Ctx.create(config, context, serverPath, workspaceFolder); // Commands which invokes manually via command palette, shortcut, etc. @@ -85,6 +88,10 @@ export async function activate(context: vscode.ExtensionContext) { ctx.registerCommand('applySourceChange', commands.applySourceChange); ctx.registerCommand('selectAndApplySourceChange', commands.selectAndApplySourceChange); + if (workspaceFolder !== null) { + ctx.pushCleanup(activateTaskProvider(workspaceFolder)); + } + activateStatusDisplay(ctx); if (!ctx.config.highlightingSemanticTokens) { diff --git a/editors/code/src/tasks.ts b/editors/code/src/tasks.ts new file mode 100644 index 000000000..be036b872 --- /dev/null +++ b/editors/code/src/tasks.ts @@ -0,0 +1,60 @@ +import { + Disposable, + ShellExecution, + Task, + TaskGroup, + TaskProvider, + tasks, + WorkspaceFolder, +} from 'vscode'; + +// This ends up as the `type` key in tasks.json. RLS also uses `cargo` and +// our configuration should be compatible with it so use the same key. +const TASK_TYPE = 'cargo'; + +export function activateTaskProvider(target: WorkspaceFolder): Disposable { + const provider: TaskProvider = { + // Detect Rust tasks. Currently we do not do any actual detection + // of tasks (e.g. aliases in .cargo/config) and just return a fixed + // set of tasks that always exist. These tasks cannot be removed in + // tasks.json - only tweaked. + provideTasks: () => getStandardCargoTasks(target), + + // We don't need to implement this. + resolveTask: () => undefined, + }; + + return tasks.registerTaskProvider(TASK_TYPE, provider); +} + +function getStandardCargoTasks(target: WorkspaceFolder): Task[] { + return [ + { command: 'build', group: TaskGroup.Build }, + { command: 'check', group: TaskGroup.Build }, + { command: 'test', group: TaskGroup.Test }, + { command: 'clean', group: TaskGroup.Clean }, + { command: 'run', group: undefined }, + ] + .map(({ command, group }) => { + const vscodeTask = new Task( + // The contents of this object end up in the tasks.json entries. + { + type: TASK_TYPE, + command, + }, + // The scope of the task - workspace or specific folder (global + // is not supported). + target, + // The task name, and task source. These are shown in the UI as + // `${source}: ${name}`, e.g. `rust: cargo build`. + `cargo ${command}`, + 'rust', + // What to do when this command is executed. + new ShellExecution('cargo', [command]), + // Problem matchers. + ['$rustc'], + ); + vscodeTask.group = group; + return vscodeTask; + }); +} -- cgit v1.2.3