extHostTerminalService.ts ×31

Frontier kind: Joint frontier

unlabeled · c_bbd8518cdbf8

1 test · 76166 LOC · 260 files · introduces 1 test · 156 LOC · 3 files

Introduces — evidence that enters the hierarchy at this concept

Code
34 ranges156 lines · 3 files
Tests
1 test

Contains — complete concept membership

All code (extent)
5072 ranges76166 lines · 260 files · Browse complete extent
All tests (intent)
1 testBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

1 test introduced at this concept.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

3 files ranked by introduced lines: 156 introduced LOC across 34 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

src/vs/workbench/api/common/extHostTerminalService.ts 148 introduced LOC · 31 ranges

Open complete file

103
104 constructor(
105 > private _proxy: MainThreadTerminalServiceShape, extHostTerminalService.ts
106 > public _id: ExtHostTerminalIdentifier,
107 > private readonly _creationOptions: vscode.TerminalOptions | vscode.ExtensionTerminalOptions,
108 > private _name?: string,
109 > ) {
110 > super();
111 >
112 > this._creationOptions = Object.freeze(this._creationOptions);
113 > this._pidPromise = new Promise<number | undefined>(c => this._pidPromiseComplete = c);
114 >
115 > const that = this;
116 > this.value = {
117 > get name(): string {
118 return that._name || '';
119 },
120 > get processId(): Promise<number | undefined> { extHostTerminalService.ts
121 return that._pidPromise;
122 },
123 > get creationOptions(): Readonly<vscode.TerminalOptions | vscode.ExtensionTerminalOptions> { extHostTerminalService.ts
124 return that._creationOptions;
125 },
126 > get exitStatus(): vscode.TerminalExitStatus | undefined { extHostTerminalService.ts
127 return that._exitStatus;
128 },
129 > get state(): vscode.TerminalState { extHostTerminalService.ts
130 return that._state;
131 },
132 > get selection(): string | undefined { extHostTerminalService.ts
133 return that._selection;
134 },
135 > get shellIntegration(): vscode.TerminalShellIntegration | undefined { extHostTerminalService.ts
136 return that.shellIntegration;
137 },
138 > sendText(text: string, shouldExecute: boolean = true): void { extHostTerminalService.ts
139 that._checkDisposed();
140 that._proxy.$sendText(that._id, text, shouldExecute);
141 },
142 > show(preserveFocus: boolean): void { extHostTerminalService.ts
143 that._checkDisposed();
144 that._proxy.$show(that._id, preserveFocus);
145 },
146 > hide(): void { extHostTerminalService.ts
147 that._checkDisposed();
148 that._proxy.$hide(that._id);
149 },
150 > dispose(): void { extHostTerminalService.ts
151 if (!that._disposed) {
152 that._disposed = true;
154 }
155 },
156 > get dimensions(): vscode.TerminalDimensions | undefined { extHostTerminalService.ts
157 if (that._cols === undefined || that._rows === undefined) {
158 return undefined;
249
250 public setExitStatus(code: number | undefined, reason: TerminalExitReason) {
251 > this._exitStatus = Object.freeze({ code, reason }); extHostTerminalService.ts
252 > }
253
254 public setDimensions(cols: number, rows: number): boolean {
461
462 constructor(
463 > supportsProcesses: boolean, extHostTerminalService.ts
464 > @IExtHostCommands private readonly _extHostCommands: IExtHostCommands,
465 > @IExtHostRpcService extHostRpc: IExtHostRpcService
466 > ) {
467 > super();
468 > this._proxy = extHostRpc.getProxy(MainContext.MainThreadTerminalService);
469 > this._bufferer = new TerminalDataBufferer(this._proxy.$sendProcessData);
470 > this._proxy.$registerProcessSupport(supportsProcesses);
471 > this._extHostCommands.registerArgumentProcessor({
472 > processArgument: arg => {
473 const deserialize = (arg: ISerializedTerminalInstanceContext) => {
474 return this.getTerminalById(arg.instanceId)?.value;
492 }
493 }
495 > this._register({
496 > dispose: () => {
497 > for (const [_, terminalProcess] of this._terminalProcesses) {
498 terminalProcess.shutdown(true);
499 }
501 > });
502 > }
503
504 public abstract createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal;
612
613 public async $acceptTerminalClosed(id: number, exitCode: number | undefined, exitReason: TerminalExitReason): Promise<void> {
614 > // Release any cached terminal links and cancel in-flight link providers for this terminal extHostTerminalService.ts
615 > this._terminalLinkCache.delete(id);
616 > const cancellationSource = this._terminalLinkCancellationSource.get(id);
617 > if (cancellationSource) {
618 > this._terminalLinkCancellationSource.delete(id);
619 > cancellationSource.dispose(true);
620 > }
621 >
622 > const index = this._getTerminalObjectIndexById(this._terminals, id);
623 > if (index !== null) {
624 > const terminal = this._terminals.splice(index, 1)[0];
625 > terminal.setExitStatus(exitCode, exitReason);
626 > this._onDidCloseTerminal.fire(terminal.value);
627 > }
628 > }
629
630 public $acceptTerminalOpened(id: number, extHostTerminalId: string | undefined, name: string, shellLaunchConfigDto: IShellLaunchConfigDto): void {
631 > if (extHostTerminalId) { extHostTerminalService.ts
632 // Resolve with the renderer generated id
633 const index = this._getTerminalObjectIndexById(this._terminals, extHostTerminalId);
640 }
641 }
643 > const creationOptions: vscode.TerminalOptions = {
644 > name: shellLaunchConfigDto.name,
645 > shellPath: shellLaunchConfigDto.executable,
646 > shellArgs: shellLaunchConfigDto.args,
647 > cwd: typeof shellLaunchConfigDto.cwd === 'string' ? shellLaunchConfigDto.cwd : URI.revive(shellLaunchConfigDto.cwd),
648 > env: shellLaunchConfigDto.env,
649 > hideFromUser: shellLaunchConfigDto.hideFromUser,
650 > titleTemplate: shellLaunchConfigDto.titleTemplate
651 > };
652 > const terminal = new ExtHostTerminal(this._proxy, id, creationOptions, name);
653 > this._terminals.push(terminal);
654 > this._onDidOpenTerminal.fire(terminal.value);
655 > terminal.isOpen = true;
656 > }
657
658 public async $acceptTerminalProcessId(id: number, processId: number): Promise<void> {
895
896 public registerLinkProvider(provider: vscode.TerminalLinkProvider): vscode.Disposable {
897 > this._linkProviders.add(provider); extHostTerminalService.ts
898 > if (this._linkProviders.size === 1) {
899 > this._proxy.$startLinkProvider();
900 > }
901 > return new VSCodeDisposable(() => {
902 > this._linkProviders.delete(provider);
903 > if (this._linkProviders.size === 0) {
904 > this._proxy.$stopLinkProvider();
905 > }
906 > });
907 > }
908
909 public async $provideLinks(terminalId: number, line: string): Promise<ITerminalLinkDto[]> {
910 > const terminal = this.getTerminalById(terminalId); extHostTerminalService.ts
911 > if (!terminal) {
912 > return [];
913 > }
914 >
915 > // Discard any cached links the terminal has been holding, currently all links are released
916 > // when new links are provided.
917 > this._terminalLinkCache.delete(terminalId);
918 >
919 > const oldToken = this._terminalLinkCancellationSource.get(terminalId);
920 > oldToken?.dispose(true);
921 > const cancellationSource = new CancellationTokenSource();
922 > this._terminalLinkCancellationSource.set(terminalId, cancellationSource);
923 >
924 > const result: ITerminalLinkDto[] = [];
925 > const context: vscode.TerminalLinkContext = { terminal: terminal.value, line };
926 > const promises: vscode.ProviderResult<{ provider: vscode.TerminalLinkProvider; links: vscode.TerminalLink[] }>[] = [];
927 >
928 > for (const provider of this._linkProviders) {
929 > promises.push(Promises.withAsyncBody(async r => {
930 > const cancelSubscription = cancellationSource.token.onCancellationRequested(() => r({ provider, links: [] }));
931 > try {
932 > const links = (await provider.provideTerminalLinks(context, cancellationSource.token)) || [];
933 > if (!cancellationSource.token.isCancellationRequested) {
934 r({ provider, links });
935 }
936 > } finally { extHostTerminalService.ts
937 > cancelSubscription.dispose();
938 > }
939 > }));
940 > }
941 >
942 > const provideResults = await Promise.all(promises);
943 >
944 > if (cancellationSource.token.isCancellationRequested) {
945 > return [];
946 > }
947
948 const cacheLinkMap = new Map<number, ICachedLinkEntry>();
968
969 return result;
971
972 $activateLink(terminalId: number, linkId: number): void {
973 > const cachedLink = this._terminalLinkCache.get(terminalId)?.get(linkId); extHostTerminalService.ts
974 > if (!cachedLink) {
975 > return;
976 > }
977 cachedLink.provider.handleTerminalLink(cachedLink.link);
979
980 private _onProcessExit(id: number, exitCode: number | undefined): void {
996
997 public getTerminalById(id: number): ExtHostTerminal | null {
998 > return this._getTerminalObjectById(this._terminals, id); extHostTerminalService.ts
999 > }
1000
1001 public getTerminalIdByApiObject(terminal: vscode.Terminal): number | null {
1007
1008 private _getTerminalObjectById<T extends ExtHostTerminal>(array: T[], id: number): T | null {
1009 > const index = this._getTerminalObjectIndexById(array, id); extHostTerminalService.ts
1010 > return index !== null ? array[index] : null;
1011 > }
1012
1013 private _getTerminalObjectIndexById<T extends ExtHostTerminal>(array: T[], id: ExtHostTerminalIdentifier): number | null {
1014 > const index = array.findIndex(item => { extHostTerminalService.ts
1015 > return item._id === id;
1016 > });
1017 > return index >= 0 ? index : null;
1018 > }
1019
1020 public getEnvironmentVariableCollection(extension: IExtensionDescription): IEnvironmentVariableCollection {
1286
1287 constructor(
1288 > @IExtHostCommands extHostCommands: IExtHostCommands, extHostTerminalService.ts
1289 > @IExtHostRpcService extHostRpc: IExtHostRpcService,
1290 > @IExtHostInitDataService initData: IExtHostInitDataService
1291 > ) {
1292 > super(false, extHostCommands, extHostRpc);
1293 > this._hasRemoteAuthority = !!initData.remote.authority;
1294 > }
1295
1296 public createTerminal(name?: string, shellPath?: string, shellArgs?: string[] | string): vscode.Terminal {
src/vs/workbench/api/common/extHostTypes.ts 7 introduced LOC · 2 ranges

Open complete file

81
82 constructor(callOnDispose: () => any) {
83 > this.#callOnDispose = callOnDispose; extHostTypes.ts
84 > }
85
86 dispose(): any {
87 > if (typeof this.#callOnDispose === 'function') { extHostTypes.ts
88 > this.#callOnDispose();
89 > this.#callOnDispose = undefined;
90 > }
91 > }
92 }
93
src/vs/base/common/uri.ts 1 introduced LOC · 1 range

Open complete file

408 static revive(data: UriComponents | URI | undefined | null): URI | undefined | null {
409 if (!data) {
410 > return data; uri.ts
411 } else if (data instanceof URI) {
412 return data;