mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-08 09:08:48 +01:00
Revert "Merge pull request #250670 from microsoft/copilot/fix-250669"
This reverts commitaa095f877e, reversing changes made to13ff4544a7.
This commit is contained in:
@@ -121,49 +121,20 @@ export async function getCwdForSplit(
|
||||
}
|
||||
|
||||
export const terminalSendSequenceCommand = async (accessor: ServicesAccessor, args: unknown) => {
|
||||
const configurationResolverService = accessor.get(IConfigurationResolverService);
|
||||
const historyService = accessor.get(IHistoryService);
|
||||
const quickInputService = accessor.get(IQuickInputService);
|
||||
const terminalService = accessor.get(ITerminalService);
|
||||
const workspaceContextService = accessor.get(IWorkspaceContextService);
|
||||
|
||||
const instance = terminalService.activeInstance || await terminalService.getActiveOrCreateInstance();
|
||||
if (!instance) {
|
||||
return;
|
||||
}
|
||||
|
||||
let text = isObject(args) && 'text' in args ? toOptionalString(args.text) : undefined;
|
||||
|
||||
// If no text provided, prompt user for input
|
||||
if (!text) {
|
||||
text = await quickInputService.input({
|
||||
value: '',
|
||||
placeHolder: 'Enter sequence to send (supports \\n, \\r, \\x escape sequences)',
|
||||
prompt: localize('workbench.action.terminal.sendSequence.prompt', "Enter sequence to send to the terminal"),
|
||||
});
|
||||
const instance = accessor.get(ITerminalService).activeInstance;
|
||||
if (instance) {
|
||||
const text = isObject(args) && 'text' in args ? toOptionalString(args.text) : undefined;
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
const configurationResolverService = accessor.get(IConfigurationResolverService);
|
||||
const workspaceContextService = accessor.get(IWorkspaceContextService);
|
||||
const historyService = accessor.get(IHistoryService);
|
||||
const activeWorkspaceRootUri = historyService.getLastActiveWorkspaceRoot(instance.isRemote ? Schemas.vscodeRemote : Schemas.file);
|
||||
const lastActiveWorkspaceRoot = activeWorkspaceRootUri ? workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) ?? undefined : undefined;
|
||||
const resolvedText = await configurationResolverService.resolveAsync(lastActiveWorkspaceRoot, text);
|
||||
instance.sendText(resolvedText, false);
|
||||
}
|
||||
|
||||
// Process escape sequences
|
||||
let processedText = text
|
||||
.replace(/\\n/g, '\n')
|
||||
.replace(/\\r/g, '\r');
|
||||
|
||||
// Process hex escape sequences (\xNN)
|
||||
while (true) {
|
||||
const match = processedText.match(/\\x([0-9a-fA-F]{2})/);
|
||||
if (match === null || match.index === undefined || match.length < 2) {
|
||||
break;
|
||||
}
|
||||
processedText = processedText.slice(0, match.index) + String.fromCharCode(parseInt(match[1], 16)) + processedText.slice(match.index + 4);
|
||||
}
|
||||
|
||||
const activeWorkspaceRootUri = historyService.getLastActiveWorkspaceRoot(instance.isRemote ? Schemas.vscodeRemote : Schemas.file);
|
||||
const lastActiveWorkspaceRoot = activeWorkspaceRootUri ? workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) ?? undefined : undefined;
|
||||
const resolvedText = await configurationResolverService.resolveAsync(lastActiveWorkspaceRoot, processedText);
|
||||
instance.sendText(resolvedText, false);
|
||||
};
|
||||
|
||||
export const terminalSendSignalCommand = async (accessor: ServicesAccessor, args: unknown) => {
|
||||
@@ -1036,13 +1007,14 @@ export function registerTerminalActions() {
|
||||
registerTerminalAction({
|
||||
id: TerminalCommandId.SendSequence,
|
||||
title: terminalStrings.sendSequence,
|
||||
f1: true,
|
||||
f1: false,
|
||||
metadata: {
|
||||
description: terminalStrings.sendSequence.value,
|
||||
args: [{
|
||||
name: 'args',
|
||||
schema: {
|
||||
type: 'object',
|
||||
required: ['text'],
|
||||
properties: {
|
||||
text: {
|
||||
description: localize('sendSequence', "The sequence of text to send to the terminal"),
|
||||
|
||||
+37
-1
@@ -17,11 +17,12 @@ import { IConfigurationService } from '../../../../../platform/configuration/com
|
||||
import { ContextKeyExpr } from '../../../../../platform/contextkey/common/contextkey.js';
|
||||
import { IFileService } from '../../../../../platform/files/common/files.js';
|
||||
import { IOpenerService } from '../../../../../platform/opener/common/opener.js';
|
||||
import { IQuickInputService } from '../../../../../platform/quickinput/common/quickInput.js';
|
||||
import { ITerminalCommand, TerminalCapability } from '../../../../../platform/terminal/common/capabilities/capabilities.js';
|
||||
import { ITerminalLogService, TerminalSettingId } from '../../../../../platform/terminal/common/terminal.js';
|
||||
import { IWorkspaceContextService } from '../../../../../platform/workspace/common/workspace.js';
|
||||
import { IStatusbarService, StatusbarAlignment, type IStatusbarEntry } from '../../../../services/statusbar/browser/statusbar.js';
|
||||
import { ITerminalContribution, ITerminalInstance, IXtermTerminal } from '../../../terminal/browser/terminal.js';
|
||||
import { IInternalXtermTerminal, ITerminalContribution, ITerminalInstance, IXtermTerminal } from '../../../terminal/browser/terminal.js';
|
||||
import { registerTerminalAction } from '../../../terminal/browser/terminalActions.js';
|
||||
import { registerTerminalContribution, type ITerminalContributionContext } from '../../../terminal/browser/terminalExtensions.js';
|
||||
import { TerminalContextKeys } from '../../../terminal/common/terminalContextKey.js';
|
||||
@@ -60,6 +61,41 @@ registerTerminalAction({
|
||||
}
|
||||
});
|
||||
|
||||
registerTerminalAction({
|
||||
id: TerminalDeveloperCommandId.WriteDataToTerminal,
|
||||
title: localize2('workbench.action.terminal.writeDataToTerminal', 'Write Data to Terminal'),
|
||||
category: Categories.Developer,
|
||||
run: async (c, accessor) => {
|
||||
const quickInputService = accessor.get(IQuickInputService);
|
||||
const instance = await c.service.getActiveOrCreateInstance();
|
||||
await c.service.revealActiveTerminal();
|
||||
await instance.processReady;
|
||||
if (!instance.xterm) {
|
||||
throw new Error('Cannot write data to terminal if xterm isn\'t initialized');
|
||||
}
|
||||
const data = await quickInputService.input({
|
||||
value: '',
|
||||
placeHolder: 'Enter data, use \\x to escape',
|
||||
prompt: localize('workbench.action.terminal.writeDataToTerminal.prompt', "Enter data to write directly to the terminal, bypassing the pty"),
|
||||
});
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
let escapedData = data
|
||||
.replace(/\\n/g, '\n')
|
||||
.replace(/\\r/g, '\r');
|
||||
while (true) {
|
||||
const match = escapedData.match(/\\x([0-9a-fA-F]{2})/);
|
||||
if (match === null || match.index === undefined || match.length < 2) {
|
||||
break;
|
||||
}
|
||||
escapedData = escapedData.slice(0, match.index) + String.fromCharCode(parseInt(match[1], 16)) + escapedData.slice(match.index + 4);
|
||||
}
|
||||
const xterm = instance.xterm as any as IInternalXtermTerminal;
|
||||
xterm._writeText(escapedData);
|
||||
}
|
||||
});
|
||||
|
||||
registerTerminalAction({
|
||||
id: TerminalDeveloperCommandId.RecordSession,
|
||||
title: localize2('workbench.action.terminal.recordSession', 'Record Terminal Session'),
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export const enum TerminalDeveloperCommandId {
|
||||
WriteDataToTerminal = 'workbench.action.terminal.writeDataToTerminal',
|
||||
RecordSession = 'workbench.action.terminal.recordSession',
|
||||
ShowTextureAtlas = 'workbench.action.terminal.showTextureAtlas',
|
||||
RestartPtyHost = 'workbench.action.terminal.restartPtyHost',
|
||||
|
||||
@@ -41,7 +41,7 @@ export enum TerminalCommandIdWithValue {
|
||||
NewWithProfile = 'workbench.action.terminal.newWithProfile',
|
||||
SelectDefaultProfile = 'workbench.action.terminal.selectDefaultShell',
|
||||
AttachToSession = 'workbench.action.terminal.attachToSession',
|
||||
SendSequence = 'workbench.action.terminal.sendSequence'
|
||||
WriteDataToTerminal = 'workbench.action.terminal.writeDataToTerminal'
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,7 +156,7 @@ export class Terminal {
|
||||
/**
|
||||
* Creates an empty terminal by opening a regular terminal and resetting its state such that it
|
||||
* essentially acts like an Pseudoterminal extension API-based terminal. This can then be paired
|
||||
* with `TerminalCommandIdWithValue.SendSequence` to make more reliable tests.
|
||||
* with `TerminalCommandIdWithValue.WriteDataToTerminal` to make more reliable tests.
|
||||
*/
|
||||
async createEmptyTerminal(expectedLocation?: 'editor' | 'panel'): Promise<void> {
|
||||
await this.createTerminal(expectedLocation);
|
||||
@@ -167,11 +167,11 @@ export class Terminal {
|
||||
await this.waitForTerminalText(buffer => buffer.some(line => line.startsWith('initialized')));
|
||||
|
||||
// Erase all content and reset cursor to top
|
||||
await this.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `${csi('2J')}${csi('H')}`);
|
||||
await this.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `${csi('2J')}${csi('H')}`);
|
||||
|
||||
// Force windows pty mode off; assume all sequences are rendered in correct position
|
||||
if (process.platform === 'win32') {
|
||||
await this.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `${vsc('P;IsWindows=False')}`);
|
||||
await this.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `${vsc('P;IsWindows=False')}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -98,33 +98,33 @@ export function setup(options?: { skipSuite: boolean }) {
|
||||
// Use the simplest profile to get as little process interaction as possible
|
||||
await terminal.createEmptyTerminal();
|
||||
// Erase all content and reset cursor to top
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `${csi('2J')}${csi('H')}`);
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `${csi('2J')}${csi('H')}`);
|
||||
});
|
||||
describe('VS Code sequences', () => {
|
||||
it('should handle the simple case', async () => {
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `${vsc('A')}Prompt> ${vsc('B')}exitcode 0`);
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `${vsc('A')}Prompt> ${vsc('B')}exitcode 0`);
|
||||
await terminal.assertCommandDecorations({ placeholder: 1, success: 0, error: 0 });
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `\\r\\n${vsc('C')}Success\\r\\n${vsc('D;0')}`);
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `\\r\\n${vsc('C')}Success\\r\\n${vsc('D;0')}`);
|
||||
await terminal.assertCommandDecorations({ placeholder: 0, success: 1, error: 0 });
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `${vsc('A')}Prompt> ${vsc('B')}exitcode 1`);
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `${vsc('A')}Prompt> ${vsc('B')}exitcode 1`);
|
||||
await terminal.assertCommandDecorations({ placeholder: 1, success: 1, error: 0 });
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `\\r\\n${vsc('C')}Failure\\r\\n${vsc('D;1')}`);
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `\\r\\n${vsc('C')}Failure\\r\\n${vsc('D;1')}`);
|
||||
await terminal.assertCommandDecorations({ placeholder: 0, success: 1, error: 1 });
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `${vsc('A')}Prompt> ${vsc('B')}`);
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `${vsc('A')}Prompt> ${vsc('B')}`);
|
||||
await terminal.assertCommandDecorations({ placeholder: 1, success: 1, error: 1 });
|
||||
});
|
||||
});
|
||||
describe('Final Term sequences', () => {
|
||||
it('should handle the simple case', async () => {
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `${ft('A')}Prompt> ${ft('B')}exitcode 0`);
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `${ft('A')}Prompt> ${ft('B')}exitcode 0`);
|
||||
await terminal.assertCommandDecorations({ placeholder: 1, success: 0, error: 0 });
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `\\r\\n${ft('C')}Success\\r\\n${ft('D;0')}`);
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `\\r\\n${ft('C')}Success\\r\\n${ft('D;0')}`);
|
||||
await terminal.assertCommandDecorations({ placeholder: 0, success: 1, error: 0 });
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `${ft('A')}Prompt> ${ft('B')}exitcode 1`);
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `${ft('A')}Prompt> ${ft('B')}exitcode 1`);
|
||||
await terminal.assertCommandDecorations({ placeholder: 1, success: 1, error: 0 });
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `\\r\\n${ft('C')}Failure\\r\\n${ft('D;1')}`);
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `\\r\\n${ft('C')}Failure\\r\\n${ft('D;1')}`);
|
||||
await terminal.assertCommandDecorations({ placeholder: 0, success: 1, error: 1 });
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, `${ft('A')}Prompt> ${ft('B')}exitcode 1`);
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, `${ft('A')}Prompt> ${ft('B')}exitcode 1`);
|
||||
await terminal.assertCommandDecorations({ placeholder: 1, success: 1, error: 1 });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -35,7 +35,7 @@ export function setup(options?: { skipSuite: boolean }) {
|
||||
expectedLineCount: number = 1
|
||||
): Promise<void> {
|
||||
const data = generateCommandAndOutput(prompt, command, exitCode);
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.SendSequence, data);
|
||||
await terminal.runCommandWithValue(TerminalCommandIdWithValue.WriteDataToTerminal, data);
|
||||
// Verify line count
|
||||
await app.code.waitForElements('.terminal-sticky-scroll .xterm-rows > *', true, e => e.length === expectedLineCount);
|
||||
// Verify content
|
||||
|
||||
Reference in New Issue
Block a user