mirror of https://github.com/coder/code-server.git
fix(lib/vscode): fix terminal channel
This commit is contained in:
parent
f10b703e84
commit
70bf7ed90b
|
@ -43,7 +43,7 @@ import { ExtensionScanner, ExtensionScannerInput } from 'vs/workbench/services/e
|
||||||
class Watcher extends DiskFileSystemProvider {
|
class Watcher extends DiskFileSystemProvider {
|
||||||
public readonly watches = new Map<number, IDisposable>();
|
public readonly watches = new Map<number, IDisposable>();
|
||||||
|
|
||||||
public dispose(): void {
|
public override dispose(): void {
|
||||||
this.watches.forEach((w) => w.dispose());
|
this.watches.forEach((w) => w.dispose());
|
||||||
this.watches.clear();
|
this.watches.clear();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
|
@ -263,6 +263,7 @@ export class ExtensionEnvironmentChannel implements IServerChannel {
|
||||||
globalStorageHome: this.environment.globalStorageHome,
|
globalStorageHome: this.environment.globalStorageHome,
|
||||||
workspaceStorageHome: this.environment.workspaceStorageHome,
|
workspaceStorageHome: this.environment.workspaceStorageHome,
|
||||||
userHome: this.environment.userHome,
|
userHome: this.environment.userHome,
|
||||||
|
useHostProxy: false,
|
||||||
os: platform.OS,
|
os: platform.OS,
|
||||||
marks: []
|
marks: []
|
||||||
};
|
};
|
||||||
|
@ -382,7 +383,7 @@ class VariableResolverService extends AbstractVariableResolverService {
|
||||||
getLineNumber: (): string | undefined => {
|
getLineNumber: (): string | undefined => {
|
||||||
return args.resolvedVariables.selectedText;
|
return args.resolvedVariables.selectedText;
|
||||||
},
|
},
|
||||||
}, undefined, env);
|
}, undefined, Promise.resolve(env));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,6 +443,7 @@ class Terminal extends TerminalProcess {
|
||||||
workspaceId: this.workspaceId,
|
workspaceId: this.workspaceId,
|
||||||
workspaceName: this.workspaceName,
|
workspaceName: this.workspaceName,
|
||||||
isOrphan: this.isOrphan,
|
isOrphan: this.isOrphan,
|
||||||
|
icon: 'bash' // TODO@oxy: used for icon, but not sure how to resolve it
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -472,8 +474,7 @@ export class TerminalProviderChannel implements IServerChannel<RemoteAgentConnec
|
||||||
|
|
||||||
// Buffer to reduce the number of messages going to the renderer.
|
// Buffer to reduce the number of messages going to the renderer.
|
||||||
private readonly bufferer = new TerminalDataBufferer((id, data) => {
|
private readonly bufferer = new TerminalDataBufferer((id, data) => {
|
||||||
// TODO: Not sure what sync means.
|
this._onProcessData.fire({ id, event: data });
|
||||||
this._onProcessData.fire({ id, event: { data, sync: true }});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
public constructor (private readonly logService: ILogService) {}
|
public constructor (private readonly logService: ILogService) {}
|
||||||
|
@ -514,7 +515,7 @@ export class TerminalProviderChannel implements IServerChannel<RemoteAgentConnec
|
||||||
switch (command) {
|
switch (command) {
|
||||||
case '$restartPtyHost': return this.restartPtyHost();
|
case '$restartPtyHost': return this.restartPtyHost();
|
||||||
case '$createProcess': return this.createProcess(context.remoteAuthority, args);
|
case '$createProcess': return this.createProcess(context.remoteAuthority, args);
|
||||||
case '$attachProcess': return this.attachProcess(args[0]);
|
case '$attachToProcess': return this.attachToProcess(args[0]);
|
||||||
case '$start': return this.start(args[0]);
|
case '$start': return this.start(args[0]);
|
||||||
case '$input': return this.input(args[0], args[1]);
|
case '$input': return this.input(args[0], args[1]);
|
||||||
case '$acknowledgeDataEvent': return this.acknowledgeDataEvent(args[0], args[1]);
|
case '$acknowledgeDataEvent': return this.acknowledgeDataEvent(args[0], args[1]);
|
||||||
|
@ -524,9 +525,12 @@ export class TerminalProviderChannel implements IServerChannel<RemoteAgentConnec
|
||||||
case '$getCwd': return this.getCwd(args[0]);
|
case '$getCwd': return this.getCwd(args[0]);
|
||||||
case '$sendCommandResult': return this.sendCommandResult(args[0], args[1], args[2], args[3]);
|
case '$sendCommandResult': return this.sendCommandResult(args[0], args[1], args[2], args[3]);
|
||||||
case '$orphanQuestionReply': return this.orphanQuestionReply(args[0]);
|
case '$orphanQuestionReply': return this.orphanQuestionReply(args[0]);
|
||||||
case '$listProcesses': return this.listProcesses(args[0]);
|
case '$listProcesses': return this.listProcesses();
|
||||||
case '$setTerminalLayoutInfo': return this.setTerminalLayoutInfo(args);
|
case '$setTerminalLayoutInfo': return this.setTerminalLayoutInfo(args);
|
||||||
case '$getTerminalLayoutInfo': return this.getTerminalLayoutInfo(args);
|
case '$getTerminalLayoutInfo': return this.getTerminalLayoutInfo(args);
|
||||||
|
case '$getShellEnvironment': return this.getShellEnvironment();
|
||||||
|
case '$getDefaultSystemShell': return this.getDefaultSystemShell(args[0]);
|
||||||
|
case '$reduceConnectionGraceTime': return this.reduceConnectionGraceTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new Error(`Invalid call '${command}'`);
|
throw new Error(`Invalid call '${command}'`);
|
||||||
|
@ -564,27 +568,26 @@ export class TerminalProviderChannel implements IServerChannel<RemoteAgentConnec
|
||||||
toResource: (relativePath: string) => resources.joinPath(activeWorkspaceUri, relativePath),
|
toResource: (relativePath: string) => resources.joinPath(activeWorkspaceUri, relativePath),
|
||||||
} : undefined;
|
} : undefined;
|
||||||
|
|
||||||
const resolverService = new VariableResolverService(remoteAuthority, args, process.env as platform.IProcessEnvironment);
|
const resolverService = new VariableResolverService(remoteAuthority, args, process.env);
|
||||||
const resolver = terminalEnvironment.createVariableResolver(activeWorkspace, resolverService);
|
const resolver = terminalEnvironment.createVariableResolver(activeWorkspace, process.env, resolverService);
|
||||||
|
|
||||||
const getDefaultShellAndArgs = async (): Promise<{ executable: string; args: string[] | string }> => {
|
const getDefaultShellAndArgs = async (): Promise<{ executable: string; args: string[] | string }> => {
|
||||||
if (shellLaunchConfig.executable) {
|
if (shellLaunchConfig.executable) {
|
||||||
const executable = resolverService.resolve(activeWorkspace, shellLaunchConfig.executable);
|
const executable = await resolverService.resolveAsync(activeWorkspace, shellLaunchConfig.executable);
|
||||||
let resolvedArgs: string[] | string = [];
|
let resolvedArgs: string[] | string = [];
|
||||||
if (shellLaunchConfig.args && Array.isArray(shellLaunchConfig.args)) {
|
if (shellLaunchConfig.args && Array.isArray(shellLaunchConfig.args)) {
|
||||||
for (const arg of shellLaunchConfig.args) {
|
for (const arg of shellLaunchConfig.args) {
|
||||||
resolvedArgs.push(resolverService.resolve(activeWorkspace, arg));
|
resolvedArgs.push(await resolverService.resolveAsync(activeWorkspace, arg));
|
||||||
}
|
}
|
||||||
} else if (shellLaunchConfig.args) {
|
} else if (shellLaunchConfig.args) {
|
||||||
resolvedArgs = resolverService.resolve(activeWorkspace, shellLaunchConfig.args);
|
resolvedArgs = await resolverService.resolveAsync(activeWorkspace, shellLaunchConfig.args);
|
||||||
}
|
}
|
||||||
return { executable, args: resolvedArgs };
|
return { executable, args: resolvedArgs };
|
||||||
}
|
}
|
||||||
|
|
||||||
const executable = terminalEnvironment.getDefaultShell(
|
const executable = terminalEnvironment.getDefaultShell(
|
||||||
(key) => args.configuration[key],
|
(key) => args.configuration[key],
|
||||||
args.isWorkspaceShellAllowed,
|
await getSystemShell(platform.OS, process.env as platform.IProcessEnvironment),
|
||||||
await getSystemShell(platform.platform, process.env as platform.IProcessEnvironment),
|
|
||||||
process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'),
|
process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432'),
|
||||||
process.env.windir,
|
process.env.windir,
|
||||||
resolver,
|
resolver,
|
||||||
|
@ -594,7 +597,6 @@ export class TerminalProviderChannel implements IServerChannel<RemoteAgentConnec
|
||||||
|
|
||||||
const resolvedArgs = terminalEnvironment.getDefaultShellArgs(
|
const resolvedArgs = terminalEnvironment.getDefaultShellArgs(
|
||||||
(key) => args.configuration[key],
|
(key) => args.configuration[key],
|
||||||
args.isWorkspaceShellAllowed,
|
|
||||||
false, // useAutomationShell
|
false, // useAutomationShell
|
||||||
resolver,
|
resolver,
|
||||||
this.logService,
|
this.logService,
|
||||||
|
@ -625,7 +627,7 @@ export class TerminalProviderChannel implements IServerChannel<RemoteAgentConnec
|
||||||
logger.debug('Resolved shell launch configuration', field('id', terminalId));
|
logger.debug('Resolved shell launch configuration', field('id', terminalId));
|
||||||
|
|
||||||
// Use instead of `terminal.integrated.env.${platform}` to make types work.
|
// Use instead of `terminal.integrated.env.${platform}` to make types work.
|
||||||
const getEnvFromConfig = (): terminal.ISingleTerminalConfiguration<ITerminalEnvironment> => {
|
const getEnvFromConfig = (): ITerminalEnvironment => {
|
||||||
if (platform.isWindows) {
|
if (platform.isWindows) {
|
||||||
return args.configuration['terminal.integrated.env.windows'];
|
return args.configuration['terminal.integrated.env.windows'];
|
||||||
} else if (platform.isMacintosh) {
|
} else if (platform.isMacintosh) {
|
||||||
|
@ -635,7 +637,7 @@ export class TerminalProviderChannel implements IServerChannel<RemoteAgentConnec
|
||||||
};
|
};
|
||||||
|
|
||||||
const getNonInheritedEnv = async (): Promise<platform.IProcessEnvironment> => {
|
const getNonInheritedEnv = async (): Promise<platform.IProcessEnvironment> => {
|
||||||
const env = await getMainProcessParentEnv();
|
const env = await getMainProcessParentEnv(process.env);
|
||||||
env.VSCODE_IPC_HOOK_CLI = process.env['VSCODE_IPC_HOOK_CLI']!;
|
env.VSCODE_IPC_HOOK_CLI = process.env['VSCODE_IPC_HOOK_CLI']!;
|
||||||
return env;
|
return env;
|
||||||
};
|
};
|
||||||
|
@ -644,7 +646,6 @@ export class TerminalProviderChannel implements IServerChannel<RemoteAgentConnec
|
||||||
shellLaunchConfig,
|
shellLaunchConfig,
|
||||||
getEnvFromConfig(),
|
getEnvFromConfig(),
|
||||||
resolver,
|
resolver,
|
||||||
args.isWorkspaceShellAllowed,
|
|
||||||
product.version,
|
product.version,
|
||||||
args.configuration['terminal.integrated.detectLocale'],
|
args.configuration['terminal.integrated.detectLocale'],
|
||||||
args.configuration['terminal.integrated.inheritEnv'] !== false
|
args.configuration['terminal.integrated.inheritEnv'] !== false
|
||||||
|
@ -700,7 +701,7 @@ export class TerminalProviderChannel implements IServerChannel<RemoteAgentConnec
|
||||||
return terminal;
|
return terminal;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async attachProcess(_id: number): Promise<void> {
|
private async attachToProcess(_id: number): Promise<void> {
|
||||||
// TODO: Won't be necessary until we have persistent terminals.
|
// TODO: Won't be necessary until we have persistent terminals.
|
||||||
throw new Error('not implemented');
|
throw new Error('not implemented');
|
||||||
}
|
}
|
||||||
|
@ -743,8 +744,14 @@ export class TerminalProviderChannel implements IServerChannel<RemoteAgentConnec
|
||||||
throw new Error('not implemented');
|
throw new Error('not implemented');
|
||||||
}
|
}
|
||||||
|
|
||||||
private async listProcesses(_reduceGraceTime: boolean): Promise<IProcessDetails[]> {
|
private async reduceConnectionGraceTime(): Promise<void> {
|
||||||
// TODO: reduceGraceTime.
|
// NOTE: Not required unless we implement orphan terminals, see above.
|
||||||
|
// Returning instead of throwing error as VSCode expects this function
|
||||||
|
// to always succeed and throwing an error causes the terminal to crash.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async listProcesses(): Promise<IProcessDetails[]> {
|
||||||
const terminals = await Promise.all(Array.from(this.terminals).map(async ([id, terminal]) => {
|
const terminals = await Promise.all(Array.from(this.terminals).map(async ([id, terminal]) => {
|
||||||
return terminal.description(id);
|
return terminal.description(id);
|
||||||
}));
|
}));
|
||||||
|
@ -786,6 +793,14 @@ export class TerminalProviderChannel implements IServerChannel<RemoteAgentConnec
|
||||||
|
|
||||||
return { tabs };
|
return { tabs };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getShellEnvironment(): Promise<platform.IProcessEnvironment> {
|
||||||
|
return { ...process.env };
|
||||||
|
}
|
||||||
|
|
||||||
|
async getDefaultSystemShell(osOverride: platform.OperatingSystem = platform.OS): Promise<string> {
|
||||||
|
return getSystemShell(osOverride, process.env);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function transformIncoming(remoteAuthority: string, uri: UriComponents | undefined): URI | undefined {
|
function transformIncoming(remoteAuthority: string, uri: UriComponents | undefined): URI | undefined {
|
||||||
|
|
Loading…
Reference in New Issue