diff --git a/src/client/extension.ts b/src/client/extension.ts index 45d60e21dda6..b9f32187413b 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -28,7 +28,7 @@ initializeFileLogging(logDispose); //=============================================== // loading starts here -import { commands, ProgressLocation, ProgressOptions, ShellExecution, Task, tasks, TaskScope, window } from 'vscode'; +import { ProgressLocation, ProgressOptions, window } from 'vscode'; import { buildApi } from './api'; import { IApplicationShell, IWorkspaceService } from './common/application/types'; import { IDisposableRegistry, IExperimentService, IExtensionContext } from './common/types'; @@ -47,7 +47,6 @@ import { disposeAll } from './common/utils/resourceLifecycle'; import { ProposedExtensionAPI } from './proposedApiTypes'; import { buildProposedApi } from './proposedApi'; import { GLOBAL_PERSISTENT_KEYS } from './common/persistentState'; -import { registerPythonTaskProvider } from './taskProblemMatcher'; durations.codeLoadingTime = stopWatch.elapsedTime; @@ -139,33 +138,6 @@ async function activateUnsafe( await Promise.all(nonBlocking); })(); - // register task provider for the workspace - - const taskProvider = registerPythonTaskProvider(); - - context.subscriptions.push(taskProvider); - - commands.executeCommand('workbench.action.tasks.registerTaskDefinition', { - label: '$pythonCustomMatcher', - owner: 'python', - source: 'python', - fileLocation: 'autoDetect', - pattern: [ - { - regexp: '^.*File \\"([^\\"]|.*)\\", line (\\d+).*', - file: 1, - line: 2, - }, - { - regexp: '^.*raise.*$', - }, - { - regexp: '^\\s*(.*)\\s*$', - message: 1, - }, - ], - }); - //=============================================== // activation ends here diff --git a/src/client/extensionActivation.ts b/src/client/extensionActivation.ts index fe5d18a8b83f..1e5a4ab1f605 100644 --- a/src/client/extensionActivation.ts +++ b/src/client/extensionActivation.ts @@ -3,7 +3,7 @@ 'use strict'; -import { DebugConfigurationProvider, debug, languages, window } from 'vscode'; +import { DebugConfigurationProvider, commands, debug, languages, window } from 'vscode'; import { registerTypes as activationRegisterTypes } from './activation/serviceRegistry'; import { IExtensionActivationManager } from './activation/types'; @@ -32,7 +32,12 @@ import { TerminalProvider } from './providers/terminalProvider'; import { setExtensionInstallTelemetryProperties } from './telemetry/extensionInstallTelemetry'; import { registerTypes as tensorBoardRegisterTypes } from './tensorBoard/serviceRegistry'; import { registerTypes as commonRegisterTerminalTypes } from './terminals/serviceRegistry'; -import { ICodeExecutionHelper, ICodeExecutionManager, ITerminalAutoActivation } from './terminals/types'; +import { + ICodeExecutionHelper, + ICodeExecutionManager, + ICodeExecutionService, + ITerminalAutoActivation, +} from './terminals/types'; import { registerTypes as unitTestsRegisterTypes } from './testing/serviceRegistry'; // components @@ -54,6 +59,7 @@ import { DebuggerTypeName } from './debugger/constants'; import { StopWatch } from './common/utils/stopWatch'; import { registerReplCommands, registerReplExecuteOnEnter, registerStartNativeReplCommand } from './repl/replCommands'; import { registerTriggerForTerminalREPL } from './terminals/codeExecution/terminalReplWatcher'; +import { registerPythonTaskProvider } from './taskProblemMatcher'; export async function activateComponents( // `ext` is passed to any extra activation funcs. @@ -109,6 +115,33 @@ export function activateFeatures(ext: ExtensionState, _components: Components): ); const executionHelper = ext.legacyIOC.serviceContainer.get(ICodeExecutionHelper); const commandManager = ext.legacyIOC.serviceContainer.get(ICommandManager); + const codeExecutionService = ext.legacyIOC.serviceContainer.get(ICodeExecutionService); + // register task provider for the workspace + + const taskProvider = registerPythonTaskProvider(executionHelper, codeExecutionService); + + // TODO: use command manager and not command directly from VS Code + commands.executeCommand('workbench.action.tasks.registerTaskDefinition', { + label: '$pythonCustomMatcher', + owner: 'python', + source: 'python', + fileLocation: 'autoDetect', + pattern: [ + { + regexp: '^.*File \\"([^\\"]|.*)\\", line (\\d+).*', + file: 1, + line: 2, + }, + { + regexp: '^.*raise.*$', + }, + { + regexp: '^\\s*(.*)\\s*$', + message: 1, + }, + ], + }); + registerTriggerForTerminalREPL(ext.disposables); registerStartNativeReplCommand(ext.disposables, interpreterService); registerReplCommands(ext.disposables, interpreterService, executionHelper, commandManager); diff --git a/src/client/taskProblemMatcher.ts b/src/client/taskProblemMatcher.ts index 01da6fdfdf0f..36d3162765ff 100644 --- a/src/client/taskProblemMatcher.ts +++ b/src/client/taskProblemMatcher.ts @@ -1,10 +1,15 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -import { ShellExecution, Task, TaskScope, tasks, Disposable } from 'vscode'; +import { ShellExecution, Task, TaskScope, tasks } from 'vscode'; +import { Disposable } from 'vscode-jsonrpc'; import { traceLog } from './logging'; +import { ICodeExecutionHelper, ICodeExecutionService } from './terminals/types'; -export function registerPythonTaskProvider(): Disposable { +export function registerPythonTaskProvider( + executionHelper: ICodeExecutionHelper, + codeExecutionService: ICodeExecutionService, +): Disposable { const taskProvider = tasks.registerTaskProvider('pythonTask', { provideTasks: () => Promise.resolve([ @@ -23,18 +28,28 @@ export function registerPythonTaskProvider(): Disposable { }, }); - tasks.onDidStartTask((e) => { + tasks.onDidStartTask(async (e) => { traceLog(`Task started: ${e.execution.task.name}`); if (e.execution.task.name === 'Trigger Python Task') { - // TODO: If the task started is for Python extension, - // Create new task, + // TODO: If the task(dummy task/entry point task --> may cd to prep execution) started is for Python extension, + // Create new task (Real task that will run current Python file), // execute that new task with their current python file - const runCurrentFileCommand = ''; // TODO: Get the file to execute - // TODO: set cwd for file execution using await this.setCwdForFileExecution(file, options); + + const pythonFile = await executionHelper.getFileToExecute(); + // TODO: MIGHT NEED TO set cwd for file execution using await this.setCwdForFileExecution(file, options); + // TODO: const { command, args } = await this.getExecuteFileArgs(file, [file.fsPath.fileToCommandArgumentForPythonExt(),]); + const { command, args } = await codeExecutionService.getExecuteFileArgs( + [ + pythonFile!.fsPath.fileToCommandArgumentForPythonExt(), // TODO: Remove bang ! + ], + pythonFile!, + ); + // TODO: build command for specific terminal + const finalCommand = terminalHelper.buildCommandForTerminal(terminalShellType, command, args); // TODO: pass command, args as argument to new ShellExecution below const currentPythonFileTask = new Task( @@ -42,7 +57,7 @@ export function registerPythonTaskProvider(): Disposable { TaskScope.Workspace, 'Run current Python file', 'pythonTask', - new ShellExecution('python joke.py'), // TODO: Get the current active Python file and make command to run this + new ShellExecution(finalCommand), // TODO: Get the current active Python file and make command to run this '$pythonCustomMatcher', // Use the custom problem matcher defined in package.json ); diff --git a/src/client/terminals/codeExecution/djangoShellCodeExecution.ts b/src/client/terminals/codeExecution/djangoShellCodeExecution.ts index 05a1470b5727..0daf9f1b195b 100644 --- a/src/client/terminals/codeExecution/djangoShellCodeExecution.ts +++ b/src/client/terminals/codeExecution/djangoShellCodeExecution.ts @@ -63,7 +63,7 @@ export class DjangoShellCodeExecutionProvider extends TerminalCodeExecutionProvi return copyPythonExecInfo(info, [managePyPath.fileToCommandArgumentForPythonExt(), 'shell']); } - public async getExecuteFileArgs(resource?: Uri, executeArgs: string[] = []): Promise { + public async getExecuteFileArgs(executeArgs: string[] = [], resource?: Uri): Promise { // We need the executable info but not the 'manage.py shell' args const info = await super.getExecutableInfo(resource); return copyPythonExecInfo(info, executeArgs); diff --git a/src/client/terminals/codeExecution/terminalCodeExecution.ts b/src/client/terminals/codeExecution/terminalCodeExecution.ts index f2750fedaa07..417c6c695f4e 100644 --- a/src/client/terminals/codeExecution/terminalCodeExecution.ts +++ b/src/client/terminals/codeExecution/terminalCodeExecution.ts @@ -39,9 +39,10 @@ export class TerminalCodeExecutionProvider implements ICodeExecutionService { public async executeFile(file: Uri, options?: { newTerminalPerFile: boolean }) { await this.setCwdForFileExecution(file, options); - const { command, args } = await this.getExecuteFileArgs(file, [ - file.fsPath.fileToCommandArgumentForPythonExt(), - ]); + const { command, args } = await this.getExecuteFileArgs( + [file.fsPath.fileToCommandArgumentForPythonExt()], + file, + ); await this.getTerminalService(file, options).sendCommand(command, args); } @@ -121,7 +122,7 @@ export class TerminalCodeExecutionProvider implements ICodeExecutionService { } // Overridden in subclasses, see djangoShellCodeExecution.ts - public async getExecuteFileArgs(resource?: Uri, executeArgs: string[] = []): Promise { + public async getExecuteFileArgs(executeArgs: string[] = [], resource?: Uri): Promise { return this.getExecutableInfo(resource, executeArgs); } private getTerminalService(resource: Resource, options?: { newTerminalPerFile: boolean }): ITerminalService { diff --git a/src/client/terminals/types.ts b/src/client/terminals/types.ts index 4c73da63dd1e..139136b7090d 100644 --- a/src/client/terminals/types.ts +++ b/src/client/terminals/types.ts @@ -3,6 +3,7 @@ import { Event, Terminal, TextEditor, Uri } from 'vscode'; import { IDisposable, Resource } from '../common/types'; +import { PythonExecInfo } from '../pythonEnvironments/exec'; export const ICodeExecutionService = Symbol('ICodeExecutionService'); @@ -10,6 +11,7 @@ export interface ICodeExecutionService { execute(code: string, resource?: Uri): Promise; executeFile(file: Uri, options?: { newTerminalPerFile: boolean }): Promise; initializeRepl(resource?: Uri): Promise; + getExecuteFileArgs(executeArgs: string[], resource?: Uri): Promise; } export const ICodeExecutionHelper = Symbol('ICodeExecutionHelper');