Skip to content

Commit 63cbb30

Browse files
authored
Do not use bracketed paste mode for native repl (#24433)
Resolves: #24417
1 parent 3e30f9d commit 63cbb30

File tree

7 files changed

+49
-13
lines changed

7 files changed

+49
-13
lines changed

src/client/repl/replCommands.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
import { registerCommand } from '../common/vscodeApis/commandApis';
1818
import { sendTelemetryEvent } from '../telemetry';
1919
import { EventName } from '../telemetry/constants';
20+
import { ReplType } from './types';
2021

2122
/**
2223
* Register Start Native REPL command in the command palette
@@ -69,7 +70,11 @@ export async function registerReplCommands(
6970
if (activeEditor && activeEditor.document) {
7071
wholeFileContent = activeEditor.document.getText();
7172
}
72-
const normalizedCode = await executionHelper.normalizeLines(code!, wholeFileContent);
73+
const normalizedCode = await executionHelper.normalizeLines(
74+
code!,
75+
ReplType.native,
76+
wholeFileContent,
77+
);
7378
await nativeRepl.sendToNativeRepl(normalizedCode);
7479
}
7580
}

src/client/repl/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
'use strict';
5+
6+
export enum ReplType {
7+
terminal = 'terminal',
8+
native = 'native',
9+
}

src/client/terminals/codeExecution/codeExecutionManager.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
CreateEnvironmentCheckKind,
2222
triggerCreateEnvironmentCheckNonBlocking,
2323
} from '../../pythonEnvironments/creation/createEnvironmentTrigger';
24+
import { ReplType } from '../../repl/types';
2425

2526
@injectable()
2627
export class CodeExecutionManager implements ICodeExecutionManager {
@@ -149,7 +150,11 @@ export class CodeExecutionManager implements ICodeExecutionManager {
149150
if (activeEditor && activeEditor.document) {
150151
wholeFileContent = activeEditor.document.getText();
151152
}
152-
const normalizedCode = await codeExecutionHelper.normalizeLines(codeToExecute!, wholeFileContent);
153+
const normalizedCode = await codeExecutionHelper.normalizeLines(
154+
codeToExecute!,
155+
ReplType.terminal,
156+
wholeFileContent,
157+
);
153158
if (!normalizedCode || normalizedCode.trim().length === 0) {
154159
return;
155160
}

src/client/terminals/codeExecution/helper.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { traceError } from '../../logging';
2323
import { IConfigurationService, Resource } from '../../common/types';
2424
import { sendTelemetryEvent } from '../../telemetry';
2525
import { EventName } from '../../telemetry/constants';
26+
import { ReplType } from '../../repl/types';
2627

2728
@injectable()
2829
export class CodeExecutionHelper implements ICodeExecutionHelper {
@@ -52,7 +53,12 @@ export class CodeExecutionHelper implements ICodeExecutionHelper {
5253
this.activeResourceService = this.serviceContainer.get<IActiveResourceService>(IActiveResourceService);
5354
}
5455

55-
public async normalizeLines(code: string, wholeFileContent?: string, resource?: Uri): Promise<string> {
56+
public async normalizeLines(
57+
code: string,
58+
replType: ReplType,
59+
wholeFileContent?: string,
60+
resource?: Uri,
61+
): Promise<string> {
5662
try {
5763
if (code.trim().length === 0) {
5864
return '';
@@ -119,7 +125,7 @@ export class CodeExecutionHelper implements ICodeExecutionHelper {
119125
await this.moveToNextBlock(lineOffset, activeEditor);
120126
}
121127
// For new _pyrepl for Python3.13 and above, we need to send code via bracketed paste mode.
122-
if (object.attach_bracket_paste) {
128+
if (object.attach_bracket_paste && replType === ReplType.terminal) {
123129
let trimmedNormalized = object.normalized.replace(/\n$/, '');
124130
if (trimmedNormalized.endsWith(':\n')) {
125131
// In case where statement is unfinished via :, truncate so auto-indentation lands nicely.

src/client/terminals/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import { Event, Terminal, TextEditor, Uri } from 'vscode';
55
import { IDisposable, Resource } from '../common/types';
6+
import { ReplType } from '../repl/types';
67

78
export const ICodeExecutionService = Symbol('ICodeExecutionService');
89

@@ -15,7 +16,7 @@ export interface ICodeExecutionService {
1516
export const ICodeExecutionHelper = Symbol('ICodeExecutionHelper');
1617

1718
export interface ICodeExecutionHelper {
18-
normalizeLines(code: string, wholeFileContent?: string): Promise<string>;
19+
normalizeLines(code: string, replType: ReplType, wholeFileContent?: string, resource?: Uri): Promise<string>;
1920
getFileToExecute(): Promise<Uri | undefined>;
2021
saveFileIfDirty(file: Uri): Promise<Resource>;
2122
getSelectedTextToExecute(textEditor: TextEditor): Promise<string | undefined>;

src/test/terminals/codeExecution/helper.test.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import { EnvironmentType, PythonEnvironment } from '../../../client/pythonEnviro
3434
import { CodeExecutionHelper } from '../../../client/terminals/codeExecution/helper';
3535
import { ICodeExecutionHelper } from '../../../client/terminals/types';
3636
import { PYTHON_PATH } from '../../common';
37+
import { ReplType } from '../../../client/repl/types';
3738

3839
const TEST_FILES_PATH = path.join(EXTENSION_ROOT_DIR, 'src', 'test', 'python_files', 'terminalExec');
3940

@@ -160,7 +161,7 @@ suite('Terminal - Code Execution Helper', () => {
160161
};
161162
jsonParseStub.returns(mockResult);
162163

163-
const result = await helper.normalizeLines('print("Looks like you are on 3.13")');
164+
const result = await helper.normalizeLines('print("Looks like you are on 3.13")', ReplType.terminal);
164165

165166
expect(result).to.equal(`\u001b[200~print("Looks like you are on 3.13")\u001b[201~`);
166167
jsonParseStub.restore();
@@ -190,7 +191,7 @@ suite('Terminal - Code Execution Helper', () => {
190191
actualProcessService.execObservable.apply(actualProcessService, [file, args, options]),
191192
);
192193

193-
const result = await helper.normalizeLines('print("Looks like you are not on 3.13")');
194+
const result = await helper.normalizeLines('print("Looks like you are not on 3.13")', ReplType.terminal);
194195

195196
expect(result).to.equal('print("Looks like you are not on 3.13")');
196197
jsonParseStub.restore();
@@ -207,7 +208,7 @@ suite('Terminal - Code Execution Helper', () => {
207208
return ({} as unknown) as ObservableExecutionResult<string>;
208209
});
209210

210-
await helper.normalizeLines('print("hello")');
211+
await helper.normalizeLines('print("hello")', ReplType.terminal);
211212

212213
expect(execArgs).to.contain('normalizeSelection.py');
213214
});
@@ -228,7 +229,7 @@ suite('Terminal - Code Execution Helper', () => {
228229
.returns((file, args, options) =>
229230
actualProcessService.execObservable.apply(actualProcessService, [file, args, options]),
230231
);
231-
const normalizedCode = await helper.normalizeLines(source);
232+
const normalizedCode = await helper.normalizeLines(source, ReplType.terminal);
232233
const normalizedExpected = expectedSource.replace(/\r\n/g, '\n');
233234
expect(normalizedCode).to.be.equal(normalizedExpected);
234235
}

src/test/terminals/codeExecution/smartSend.test.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { PYTHON_PATH } from '../../common';
2525
import { Architecture } from '../../../client/common/utils/platform';
2626
import { ProcessService } from '../../../client/common/process/proc';
2727
import { l10n } from '../../mocks/vsc';
28+
import { ReplType } from '../../../client/repl/types';
2829

2930
const TEST_FILES_PATH = path.join(EXTENSION_ROOT_DIR, 'src', 'test', 'python_files', 'terminalExec');
3031

@@ -145,7 +146,7 @@ suite('REPL - Smart Send', () => {
145146
.setup((p) => p.execObservable(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()))
146147
.returns((file, args, options) => execObservable.apply(actualProcessService, [file, args, options]));
147148

148-
await codeExecutionHelper.normalizeLines('my_dict = {', wholeFileContent);
149+
await codeExecutionHelper.normalizeLines('my_dict = {', ReplType.terminal, wholeFileContent);
149150

150151
commandManager
151152
.setup((c) => c.executeCommand('cursorMove', TypeMoq.It.isAny()))
@@ -197,7 +198,11 @@ suite('REPL - Smart Send', () => {
197198
.setup((p) => p.execObservable(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()))
198199
.returns((file, args, options) => execObservable.apply(actualProcessService, [file, args, options]));
199200

200-
const actualSmartOutput = await codeExecutionHelper.normalizeLines('my_dict = {', wholeFileContent);
201+
const actualSmartOutput = await codeExecutionHelper.normalizeLines(
202+
'my_dict = {',
203+
ReplType.terminal,
204+
wholeFileContent,
205+
);
201206

202207
// my_dict = { <----- smart shift+enter here
203208
// "key1": "value1",
@@ -247,7 +252,11 @@ suite('REPL - Smart Send', () => {
247252
.setup((p) => p.execObservable(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()))
248253
.returns((file, args, options) => execObservable.apply(actualProcessService, [file, args, options]));
249254

250-
const actualNonSmartResult = await codeExecutionHelper.normalizeLines('my_dict = {', wholeFileContent);
255+
const actualNonSmartResult = await codeExecutionHelper.normalizeLines(
256+
'my_dict = {',
257+
ReplType.terminal,
258+
wholeFileContent,
259+
);
251260
const expectedNonSmartResult = 'my_dict = {\n\n'; // Standard for previous normalization logic
252261
expect(actualNonSmartResult).to.be.equal(expectedNonSmartResult);
253262
});
@@ -285,7 +294,7 @@ suite('REPL - Smart Send', () => {
285294
.setup((p) => p.execObservable(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny()))
286295
.returns((file, args, options) => execObservable.apply(actualProcessService, [file, args, options]));
287296

288-
await codeExecutionHelper.normalizeLines('my_dict = {', wholeFileContent);
297+
await codeExecutionHelper.normalizeLines('my_dict = {', ReplType.terminal, wholeFileContent);
289298

290299
applicationShell
291300
.setup((a) =>

0 commit comments

Comments
 (0)