From dc1186257de742ec36c32c9cc07ab4bb7392f146 Mon Sep 17 00:00:00 2001 From: Anthony Kim Date: Tue, 12 Nov 2024 16:30:17 -0800 Subject: [PATCH 1/2] add ReplType for terminal and native --- src/client/repl/replCommands.ts | 7 ++++++- src/client/repl/types.ts | 9 +++++++++ .../terminals/codeExecution/codeExecutionManager.ts | 7 ++++++- src/client/terminals/codeExecution/helper.ts | 10 ++++++++-- src/client/terminals/types.ts | 3 ++- 5 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 src/client/repl/types.ts diff --git a/src/client/repl/replCommands.ts b/src/client/repl/replCommands.ts index e35cdbf8a7a0..eb2eb49aea76 100644 --- a/src/client/repl/replCommands.ts +++ b/src/client/repl/replCommands.ts @@ -17,6 +17,7 @@ import { import { registerCommand } from '../common/vscodeApis/commandApis'; import { sendTelemetryEvent } from '../telemetry'; import { EventName } from '../telemetry/constants'; +import { ReplType } from './types'; /** * Register Start Native REPL command in the command palette @@ -69,7 +70,11 @@ export async function registerReplCommands( if (activeEditor && activeEditor.document) { wholeFileContent = activeEditor.document.getText(); } - const normalizedCode = await executionHelper.normalizeLines(code!, wholeFileContent); + const normalizedCode = await executionHelper.normalizeLines( + code!, + ReplType.native, + wholeFileContent, + ); await nativeRepl.sendToNativeRepl(normalizedCode); } } diff --git a/src/client/repl/types.ts b/src/client/repl/types.ts new file mode 100644 index 000000000000..38de9bfe2137 --- /dev/null +++ b/src/client/repl/types.ts @@ -0,0 +1,9 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +'use strict'; + +export enum ReplType { + terminal = 'terminal', + native = 'native', +} diff --git a/src/client/terminals/codeExecution/codeExecutionManager.ts b/src/client/terminals/codeExecution/codeExecutionManager.ts index ff665af1a07a..120725f11983 100644 --- a/src/client/terminals/codeExecution/codeExecutionManager.ts +++ b/src/client/terminals/codeExecution/codeExecutionManager.ts @@ -21,6 +21,7 @@ import { CreateEnvironmentCheckKind, triggerCreateEnvironmentCheckNonBlocking, } from '../../pythonEnvironments/creation/createEnvironmentTrigger'; +import { ReplType } from '../../repl/types'; @injectable() export class CodeExecutionManager implements ICodeExecutionManager { @@ -149,7 +150,11 @@ export class CodeExecutionManager implements ICodeExecutionManager { if (activeEditor && activeEditor.document) { wholeFileContent = activeEditor.document.getText(); } - const normalizedCode = await codeExecutionHelper.normalizeLines(codeToExecute!, wholeFileContent); + const normalizedCode = await codeExecutionHelper.normalizeLines( + codeToExecute!, + ReplType.terminal, + wholeFileContent, + ); if (!normalizedCode || normalizedCode.trim().length === 0) { return; } diff --git a/src/client/terminals/codeExecution/helper.ts b/src/client/terminals/codeExecution/helper.ts index 49fdd59a00c0..31a626207bc4 100644 --- a/src/client/terminals/codeExecution/helper.ts +++ b/src/client/terminals/codeExecution/helper.ts @@ -23,6 +23,7 @@ import { traceError } from '../../logging'; import { IConfigurationService, Resource } from '../../common/types'; import { sendTelemetryEvent } from '../../telemetry'; import { EventName } from '../../telemetry/constants'; +import { ReplType } from '../../repl/types'; @injectable() export class CodeExecutionHelper implements ICodeExecutionHelper { @@ -52,7 +53,12 @@ export class CodeExecutionHelper implements ICodeExecutionHelper { this.activeResourceService = this.serviceContainer.get(IActiveResourceService); } - public async normalizeLines(code: string, wholeFileContent?: string, resource?: Uri): Promise { + public async normalizeLines( + code: string, + replType: ReplType, + wholeFileContent?: string, + resource?: Uri, + ): Promise { try { if (code.trim().length === 0) { return ''; @@ -119,7 +125,7 @@ export class CodeExecutionHelper implements ICodeExecutionHelper { await this.moveToNextBlock(lineOffset, activeEditor); } // For new _pyrepl for Python3.13 and above, we need to send code via bracketed paste mode. - if (object.attach_bracket_paste) { + if (object.attach_bracket_paste && replType === ReplType.terminal) { let trimmedNormalized = object.normalized.replace(/\n$/, ''); if (trimmedNormalized.endsWith(':\n')) { // In case where statement is unfinished via :, truncate so auto-indentation lands nicely. diff --git a/src/client/terminals/types.ts b/src/client/terminals/types.ts index 5fd129e8fe89..1384057c3b7c 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 { ReplType } from '../repl/types'; export const ICodeExecutionService = Symbol('ICodeExecutionService'); @@ -15,7 +16,7 @@ export interface ICodeExecutionService { export const ICodeExecutionHelper = Symbol('ICodeExecutionHelper'); export interface ICodeExecutionHelper { - normalizeLines(code: string, wholeFileContent?: string): Promise; + normalizeLines(code: string, replType: ReplType, wholeFileContent?: string, resource?: Uri): Promise; getFileToExecute(): Promise; saveFileIfDirty(file: Uri): Promise; getSelectedTextToExecute(textEditor: TextEditor): Promise; From 8c050a7a68571aa9711defdf9ec731f27afbc67b Mon Sep 17 00:00:00 2001 From: Anthony Kim Date: Tue, 12 Nov 2024 16:35:46 -0800 Subject: [PATCH 2/2] fix test --- src/test/terminals/codeExecution/helper.test.ts | 9 +++++---- .../terminals/codeExecution/smartSend.test.ts | 17 +++++++++++++---- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/test/terminals/codeExecution/helper.test.ts b/src/test/terminals/codeExecution/helper.test.ts index 7a3171ccf836..166c4db12e7d 100644 --- a/src/test/terminals/codeExecution/helper.test.ts +++ b/src/test/terminals/codeExecution/helper.test.ts @@ -34,6 +34,7 @@ import { EnvironmentType, PythonEnvironment } from '../../../client/pythonEnviro import { CodeExecutionHelper } from '../../../client/terminals/codeExecution/helper'; import { ICodeExecutionHelper } from '../../../client/terminals/types'; import { PYTHON_PATH } from '../../common'; +import { ReplType } from '../../../client/repl/types'; const TEST_FILES_PATH = path.join(EXTENSION_ROOT_DIR, 'src', 'test', 'python_files', 'terminalExec'); @@ -160,7 +161,7 @@ suite('Terminal - Code Execution Helper', () => { }; jsonParseStub.returns(mockResult); - const result = await helper.normalizeLines('print("Looks like you are on 3.13")'); + const result = await helper.normalizeLines('print("Looks like you are on 3.13")', ReplType.terminal); expect(result).to.equal(`\u001b[200~print("Looks like you are on 3.13")\u001b[201~`); jsonParseStub.restore(); @@ -190,7 +191,7 @@ suite('Terminal - Code Execution Helper', () => { actualProcessService.execObservable.apply(actualProcessService, [file, args, options]), ); - const result = await helper.normalizeLines('print("Looks like you are not on 3.13")'); + const result = await helper.normalizeLines('print("Looks like you are not on 3.13")', ReplType.terminal); expect(result).to.equal('print("Looks like you are not on 3.13")'); jsonParseStub.restore(); @@ -207,7 +208,7 @@ suite('Terminal - Code Execution Helper', () => { return ({} as unknown) as ObservableExecutionResult; }); - await helper.normalizeLines('print("hello")'); + await helper.normalizeLines('print("hello")', ReplType.terminal); expect(execArgs).to.contain('normalizeSelection.py'); }); @@ -228,7 +229,7 @@ suite('Terminal - Code Execution Helper', () => { .returns((file, args, options) => actualProcessService.execObservable.apply(actualProcessService, [file, args, options]), ); - const normalizedCode = await helper.normalizeLines(source); + const normalizedCode = await helper.normalizeLines(source, ReplType.terminal); const normalizedExpected = expectedSource.replace(/\r\n/g, '\n'); expect(normalizedCode).to.be.equal(normalizedExpected); } diff --git a/src/test/terminals/codeExecution/smartSend.test.ts b/src/test/terminals/codeExecution/smartSend.test.ts index 05c45f00f60f..b81d581033aa 100644 --- a/src/test/terminals/codeExecution/smartSend.test.ts +++ b/src/test/terminals/codeExecution/smartSend.test.ts @@ -25,6 +25,7 @@ import { PYTHON_PATH } from '../../common'; import { Architecture } from '../../../client/common/utils/platform'; import { ProcessService } from '../../../client/common/process/proc'; import { l10n } from '../../mocks/vsc'; +import { ReplType } from '../../../client/repl/types'; const TEST_FILES_PATH = path.join(EXTENSION_ROOT_DIR, 'src', 'test', 'python_files', 'terminalExec'); @@ -145,7 +146,7 @@ suite('REPL - Smart Send', () => { .setup((p) => p.execObservable(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())) .returns((file, args, options) => execObservable.apply(actualProcessService, [file, args, options])); - await codeExecutionHelper.normalizeLines('my_dict = {', wholeFileContent); + await codeExecutionHelper.normalizeLines('my_dict = {', ReplType.terminal, wholeFileContent); commandManager .setup((c) => c.executeCommand('cursorMove', TypeMoq.It.isAny())) @@ -197,7 +198,11 @@ suite('REPL - Smart Send', () => { .setup((p) => p.execObservable(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())) .returns((file, args, options) => execObservable.apply(actualProcessService, [file, args, options])); - const actualSmartOutput = await codeExecutionHelper.normalizeLines('my_dict = {', wholeFileContent); + const actualSmartOutput = await codeExecutionHelper.normalizeLines( + 'my_dict = {', + ReplType.terminal, + wholeFileContent, + ); // my_dict = { <----- smart shift+enter here // "key1": "value1", @@ -247,7 +252,11 @@ suite('REPL - Smart Send', () => { .setup((p) => p.execObservable(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())) .returns((file, args, options) => execObservable.apply(actualProcessService, [file, args, options])); - const actualNonSmartResult = await codeExecutionHelper.normalizeLines('my_dict = {', wholeFileContent); + const actualNonSmartResult = await codeExecutionHelper.normalizeLines( + 'my_dict = {', + ReplType.terminal, + wholeFileContent, + ); const expectedNonSmartResult = 'my_dict = {\n\n'; // Standard for previous normalization logic expect(actualNonSmartResult).to.be.equal(expectedNonSmartResult); }); @@ -285,7 +294,7 @@ suite('REPL - Smart Send', () => { .setup((p) => p.execObservable(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())) .returns((file, args, options) => execObservable.apply(actualProcessService, [file, args, options])); - await codeExecutionHelper.normalizeLines('my_dict = {', wholeFileContent); + await codeExecutionHelper.normalizeLines('my_dict = {', ReplType.terminal, wholeFileContent); applicationShell .setup((a) =>