Skip to content

Commit 95c9166

Browse files
committed
Revert "Merge pull request microsoft#250670 from microsoft/copilot/fix-250669"
This reverts commit aa095f8, reversing changes made to 13ff454.
1 parent a76a1c4 commit 95c9166

File tree

6 files changed

+66
-57
lines changed

6 files changed

+66
-57
lines changed

src/vs/workbench/contrib/terminal/browser/terminalActions.ts

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -121,49 +121,20 @@ export async function getCwdForSplit(
121121
}
122122

123123
export const terminalSendSequenceCommand = async (accessor: ServicesAccessor, args: unknown) => {
124-
const configurationResolverService = accessor.get(IConfigurationResolverService);
125-
const historyService = accessor.get(IHistoryService);
126-
const quickInputService = accessor.get(IQuickInputService);
127-
const terminalService = accessor.get(ITerminalService);
128-
const workspaceContextService = accessor.get(IWorkspaceContextService);
129-
130-
const instance = terminalService.activeInstance || await terminalService.getActiveOrCreateInstance();
131-
if (!instance) {
132-
return;
133-
}
134-
135-
let text = isObject(args) && 'text' in args ? toOptionalString(args.text) : undefined;
136-
137-
// If no text provided, prompt user for input
138-
if (!text) {
139-
text = await quickInputService.input({
140-
value: '',
141-
placeHolder: 'Enter sequence to send (supports \\n, \\r, \\x escape sequences)',
142-
prompt: localize('workbench.action.terminal.sendSequence.prompt', "Enter sequence to send to the terminal"),
143-
});
124+
const instance = accessor.get(ITerminalService).activeInstance;
125+
if (instance) {
126+
const text = isObject(args) && 'text' in args ? toOptionalString(args.text) : undefined;
144127
if (!text) {
145128
return;
146129
}
130+
const configurationResolverService = accessor.get(IConfigurationResolverService);
131+
const workspaceContextService = accessor.get(IWorkspaceContextService);
132+
const historyService = accessor.get(IHistoryService);
133+
const activeWorkspaceRootUri = historyService.getLastActiveWorkspaceRoot(instance.isRemote ? Schemas.vscodeRemote : Schemas.file);
134+
const lastActiveWorkspaceRoot = activeWorkspaceRootUri ? workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) ?? undefined : undefined;
135+
const resolvedText = await configurationResolverService.resolveAsync(lastActiveWorkspaceRoot, text);
136+
instance.sendText(resolvedText, false);
147137
}
148-
149-
// Process escape sequences
150-
let processedText = text
151-
.replace(/\\n/g, '\n')
152-
.replace(/\\r/g, '\r');
153-
154-
// Process hex escape sequences (\xNN)
155-
while (true) {
156-
const match = processedText.match(/\\x([0-9a-fA-F]{2})/);
157-
if (match === null || match.index === undefined || match.length < 2) {
158-
break;
159-
}
160-
processedText = processedText.slice(0, match.index) + String.fromCharCode(parseInt(match[1], 16)) + processedText.slice(match.index + 4);
161-
}
162-
163-
const activeWorkspaceRootUri = historyService.getLastActiveWorkspaceRoot(instance.isRemote ? Schemas.vscodeRemote : Schemas.file);
164-
const lastActiveWorkspaceRoot = activeWorkspaceRootUri ? workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) ?? undefined : undefined;
165-
const resolvedText = await configurationResolverService.resolveAsync(lastActiveWorkspaceRoot, processedText);
166-
instance.sendText(resolvedText, false);
167138
};
168139

169140
export const terminalSendSignalCommand = async (accessor: ServicesAccessor, args: unknown) => {
@@ -1036,13 +1007,14 @@ export function registerTerminalActions() {
10361007
registerTerminalAction({
10371008
id: TerminalCommandId.SendSequence,
10381009
title: terminalStrings.sendSequence,
1039-
f1: true,
1010+
f1: false,
10401011
metadata: {
10411012
description: terminalStrings.sendSequence.value,
10421013
args: [{
10431014
name: 'args',
10441015
schema: {
10451016
type: 'object',
1017+
required: ['text'],
10461018
properties: {
10471019
text: {
10481020
description: localize('sendSequence', "The sequence of text to send to the terminal"),

src/vs/workbench/contrib/terminalContrib/developer/browser/terminal.developer.contribution.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ import { IConfigurationService } from '../../../../../platform/configuration/com
1717
import { ContextKeyExpr } from '../../../../../platform/contextkey/common/contextkey.js';
1818
import { IFileService } from '../../../../../platform/files/common/files.js';
1919
import { IOpenerService } from '../../../../../platform/opener/common/opener.js';
20+
import { IQuickInputService } from '../../../../../platform/quickinput/common/quickInput.js';
2021
import { ITerminalCommand, TerminalCapability } from '../../../../../platform/terminal/common/capabilities/capabilities.js';
2122
import { ITerminalLogService, TerminalSettingId } from '../../../../../platform/terminal/common/terminal.js';
2223
import { IWorkspaceContextService } from '../../../../../platform/workspace/common/workspace.js';
2324
import { IStatusbarService, StatusbarAlignment, type IStatusbarEntry } from '../../../../services/statusbar/browser/statusbar.js';
24-
import { ITerminalContribution, ITerminalInstance, IXtermTerminal } from '../../../terminal/browser/terminal.js';
25+
import { IInternalXtermTerminal, ITerminalContribution, ITerminalInstance, IXtermTerminal } from '../../../terminal/browser/terminal.js';
2526
import { registerTerminalAction } from '../../../terminal/browser/terminalActions.js';
2627
import { registerTerminalContribution, type ITerminalContributionContext } from '../../../terminal/browser/terminalExtensions.js';
2728
import { TerminalContextKeys } from '../../../terminal/common/terminalContextKey.js';
@@ -60,6 +61,41 @@ registerTerminalAction({
6061
}
6162
});
6263

64+
registerTerminalAction({
65+
id: TerminalDeveloperCommandId.WriteDataToTerminal,
66+
title: localize2('workbench.action.terminal.writeDataToTerminal', 'Write Data to Terminal'),
67+
category: Categories.Developer,
68+
run: async (c, accessor) => {
69+
const quickInputService = accessor.get(IQuickInputService);
70+
const instance = await c.service.getActiveOrCreateInstance();
71+
await c.service.revealActiveTerminal();
72+
await instance.processReady;
73+
if (!instance.xterm) {
74+
throw new Error('Cannot write data to terminal if xterm isn\'t initialized');
75+
}
76+
const data = await quickInputService.input({
77+
value: '',
78+
placeHolder: 'Enter data, use \\x to escape',
79+
prompt: localize('workbench.action.terminal.writeDataToTerminal.prompt', "Enter data to write directly to the terminal, bypassing the pty"),
80+
});
81+
if (!data) {
82+
return;
83+
}
84+
let escapedData = data
85+
.replace(/\\n/g, '\n')
86+
.replace(/\\r/g, '\r');
87+
while (true) {
88+
const match = escapedData.match(/\\x([0-9a-fA-F]{2})/);
89+
if (match === null || match.index === undefined || match.length < 2) {
90+
break;
91+
}
92+
escapedData = escapedData.slice(0, match.index) + String.fromCharCode(parseInt(match[1], 16)) + escapedData.slice(match.index + 4);
93+
}
94+
const xterm = instance.xterm as any as IInternalXtermTerminal;
95+
xterm._writeText(escapedData);
96+
}
97+
});
98+
6399
registerTerminalAction({
64100
id: TerminalDeveloperCommandId.RecordSession,
65101
title: localize2('workbench.action.terminal.recordSession', 'Record Terminal Session'),

src/vs/workbench/contrib/terminalContrib/developer/common/terminal.developer.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
export const enum TerminalDeveloperCommandId {
7+
WriteDataToTerminal = 'workbench.action.terminal.writeDataToTerminal',
78
RecordSession = 'workbench.action.terminal.recordSession',
89
ShowTextureAtlas = 'workbench.action.terminal.showTextureAtlas',
910
RestartPtyHost = 'workbench.action.terminal.restartPtyHost',

test/automation/src/terminal.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export enum TerminalCommandIdWithValue {
4141
NewWithProfile = 'workbench.action.terminal.newWithProfile',
4242
SelectDefaultProfile = 'workbench.action.terminal.selectDefaultShell',
4343
AttachToSession = 'workbench.action.terminal.attachToSession',
44-
SendSequence = 'workbench.action.terminal.sendSequence'
44+
WriteDataToTerminal = 'workbench.action.terminal.writeDataToTerminal'
4545
}
4646

4747
/**
@@ -156,7 +156,7 @@ export class Terminal {
156156
/**
157157
* Creates an empty terminal by opening a regular terminal and resetting its state such that it
158158
* essentially acts like an Pseudoterminal extension API-based terminal. This can then be paired
159-
* with `TerminalCommandIdWithValue.SendSequence` to make more reliable tests.
159+
* with `TerminalCommandIdWithValue.WriteDataToTerminal` to make more reliable tests.
160160
*/
161161
async createEmptyTerminal(expectedLocation?: 'editor' | 'panel'): Promise<void> {
162162
await this.createTerminal(expectedLocation);
@@ -167,11 +167,11 @@ export class Terminal {
167167
await this.waitForTerminalText(buffer => buffer.some(line => line.startsWith('initialized')));
168168

169169
// Erase all content and reset cursor to top
170-
await this.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `${csi('2J')}${csi('H')}`);
170+
await this.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `${csi('2J')}${csi('H')}`);
171171

172172
// Force windows pty mode off; assume all sequences are rendered in correct position
173173
if (process.platform === 'win32') {
174-
await this.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `${vsc('P;IsWindows=False')}`);
174+
await this.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `${vsc('P;IsWindows=False')}`);
175175
}
176176
}
177177

test/smoke/src/areas/terminal/terminal-shellIntegration.test.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -98,33 +98,33 @@ export function setup(options?: { skipSuite: boolean }) {
9898
// Use the simplest profile to get as little process interaction as possible
9999
await terminal.createEmptyTerminal();
100100
// Erase all content and reset cursor to top
101-
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `${csi('2J')}${csi('H')}`);
101+
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `${csi('2J')}${csi('H')}`);
102102
});
103103
describe('VS Code sequences', () => {
104104
it('should handle the simple case', async () => {
105-
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `${vsc('A')}Prompt> ${vsc('B')}exitcode 0`);
105+
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `${vsc('A')}Prompt> ${vsc('B')}exitcode 0`);
106106
await terminal.assertCommandDecorations({ placeholder: 1, success: 0, error: 0 });
107-
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `\\r\\n${vsc('C')}Success\\r\\n${vsc('D;0')}`);
107+
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `\\r\\n${vsc('C')}Success\\r\\n${vsc('D;0')}`);
108108
await terminal.assertCommandDecorations({ placeholder: 0, success: 1, error: 0 });
109-
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `${vsc('A')}Prompt> ${vsc('B')}exitcode 1`);
109+
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `${vsc('A')}Prompt> ${vsc('B')}exitcode 1`);
110110
await terminal.assertCommandDecorations({ placeholder: 1, success: 1, error: 0 });
111-
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `\\r\\n${vsc('C')}Failure\\r\\n${vsc('D;1')}`);
111+
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `\\r\\n${vsc('C')}Failure\\r\\n${vsc('D;1')}`);
112112
await terminal.assertCommandDecorations({ placeholder: 0, success: 1, error: 1 });
113-
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `${vsc('A')}Prompt> ${vsc('B')}`);
113+
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `${vsc('A')}Prompt> ${vsc('B')}`);
114114
await terminal.assertCommandDecorations({ placeholder: 1, success: 1, error: 1 });
115115
});
116116
});
117117
describe('Final Term sequences', () => {
118118
it('should handle the simple case', async () => {
119-
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `${ft('A')}Prompt> ${ft('B')}exitcode 0`);
119+
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `${ft('A')}Prompt> ${ft('B')}exitcode 0`);
120120
await terminal.assertCommandDecorations({ placeholder: 1, success: 0, error: 0 });
121-
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `\\r\\n${ft('C')}Success\\r\\n${ft('D;0')}`);
121+
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `\\r\\n${ft('C')}Success\\r\\n${ft('D;0')}`);
122122
await terminal.assertCommandDecorations({ placeholder: 0, success: 1, error: 0 });
123-
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `${ft('A')}Prompt> ${ft('B')}exitcode 1`);
123+
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `${ft('A')}Prompt> ${ft('B')}exitcode 1`);
124124
await terminal.assertCommandDecorations({ placeholder: 1, success: 1, error: 0 });
125-
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `\\r\\n${ft('C')}Failure\\r\\n${ft('D;1')}`);
125+
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `\\r\\n${ft('C')}Failure\\r\\n${ft('D;1')}`);
126126
await terminal.assertCommandDecorations({ placeholder: 0, success: 1, error: 1 });
127-
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `${ft('A')}Prompt> ${ft('B')}exitcode 1`);
127+
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `${ft('A')}Prompt> ${ft('B')}exitcode 1`);
128128
await terminal.assertCommandDecorations({ placeholder: 1, success: 1, error: 1 });
129129
});
130130
});

test/smoke/src/areas/terminal/terminal-stickyScroll.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export function setup(options?: { skipSuite: boolean }) {
3535
expectedLineCount: number = 1
3636
): Promise<void> {
3737
const data = generateCommandAndOutput(prompt, command, exitCode);
38-
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, data);
38+
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, data);
3939
// Verify line count
4040
await app.code.waitForElements('.terminal-sticky-scroll .xterm-rows > *', true, e => e.length === expectedLineCount);
4141
// Verify content

0 commit comments

Comments
 (0)