diff --git a/src/models/taskDefinition.ts b/src/models/taskDefinition.ts index e207c3a..2c82cd5 100644 --- a/src/models/taskDefinition.ts +++ b/src/models/taskDefinition.ts @@ -1,6 +1,7 @@ import * as vscode from 'vscode'; import { Location, Task } from './models.js'; import { settings } from '../utils/settings.js'; +import { useDedicatedTerminal, buildTaskCommand } from '../utils/taskPresentation.js'; export class TaskDefinition implements vscode.TaskDefinition { private _task: Task; @@ -37,17 +38,27 @@ export class TaskDefinition implements vscode.TaskDefinition { cliArgs = cliArgs?.filter(x => x !== "") || []; const uri = vscode.Uri.file(this.workspace); const workspaceFolder = vscode.workspace.getWorkspaceFolder(uri) || vscode.TaskScope.Workspace; + const taskLabel = cliArgs.length > 0 ? `${this.name} ${cliArgs.join(' ')}` : this.name; + const definition: vscode.TaskDefinition = { + type: this.type, + task: this.task, + workspace: this.workspace, + file: this.location.taskfile + }; + if (cliArgs.length > 0) { + definition.args = cliArgs; + } const task = new vscode.Task( - this, + definition, workspaceFolder, - this.name, + taskLabel, this.type, new vscode.ShellExecution( - `${settings.path} ${this.task}${cliArgs && cliArgs.length > 0 ? " -- " + cliArgs.join(' ') : ''}`, + buildTaskCommand(settings.path, this.task, cliArgs), {cwd: this.workspace} ) ); task.detail = this.description; - return task; + return useDedicatedTerminal(task); } } diff --git a/src/providers/taskProvider.ts b/src/providers/taskProvider.ts index ecc3228..194e539 100644 --- a/src/providers/taskProvider.ts +++ b/src/providers/taskProvider.ts @@ -4,7 +4,8 @@ import * as vscode from 'vscode'; import { Taskfile } from '../models/taskfile.js'; -import { TaskDefinition } from '../models/taskDefinition.js'; +import { useDedicatedTerminal, buildTaskCommand } from '../utils/taskPresentation.js'; +import { settings } from '../utils/settings.js'; export class TaskProvider implements vscode.TaskProvider { private _taskfiles: Taskfile[] = []; @@ -22,16 +23,24 @@ export class TaskProvider implements vscode.TaskProvider { } public resolveTask(_task: vscode.Task): vscode.Task | undefined { - const task = _task.definition.task; - if (task) { - const definition: TaskDefinition = _task.definition; - return new vscode.Task( + const taskName = _task.definition.task; + if (taskName) { + const definition = _task.definition; + const cliArgs = Array.isArray(definition.args) + ? definition.args.filter((arg: unknown): arg is string => typeof arg === 'string' && arg !== "") + : []; + const workspace = typeof definition.workspace === 'string' ? definition.workspace : undefined; + const executionOptions = workspace ? {cwd: workspace} : undefined; + return useDedicatedTerminal(new vscode.Task( definition, _task.scope ?? vscode.TaskScope.Workspace, - definition.task, + taskName, 'taskfile', - new vscode.ShellExecution(`task ${definition.task}`) - ); + new vscode.ShellExecution( + buildTaskCommand(settings.path, taskName, cliArgs), + executionOptions + ) + ), _task.presentationOptions); } return undefined; } diff --git a/src/utils/taskPresentation.ts b/src/utils/taskPresentation.ts new file mode 100644 index 0000000..cbb915d --- /dev/null +++ b/src/utils/taskPresentation.ts @@ -0,0 +1,19 @@ +import * as vscode from 'vscode'; + +const dedicatedTerminalDefaults: vscode.TaskPresentationOptions = { + panel: vscode.TaskPanelKind.Dedicated, + reveal: vscode.TaskRevealKind.Always, + clear: false, + showReuseMessage: false +}; + +// Applies our dedicated-terminal presentation defaults, while letting any +// user-supplied options (e.g. from tasks.json) take precedence. +export function useDedicatedTerminal(task: vscode.Task, overrides?: vscode.TaskPresentationOptions): vscode.Task { + task.presentationOptions = { ...dedicatedTerminalDefaults, ...overrides }; + return task; +} + +export function buildTaskCommand(taskBin: string, taskName: string, cliArgs: string[]): string { + return `${taskBin} ${taskName}${cliArgs.length > 0 ? " -- " + cliArgs.join(' ') : ''}`; +}