Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions src/vs/workbench/contrib/terminal/browser/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,8 @@ export interface ITerminalInstanceService {
* Create a new terminal instance.
* @param launchConfig The shell launch config.
* @param target The target of the terminal.
* @param resource The URI for the terminal. Note that this is the unique identifier for the
* terminal, not the cwd.
*/
createInstance(launchConfig: IShellLaunchConfig, target: TerminalLocation, resource?: URI): ITerminalInstance;
createInstance(launchConfig: IShellLaunchConfig, target: TerminalLocation): ITerminalInstance;

/**
* Gets the registered backend for a remote authority (undefined = local). This is a convenience
Expand Down Expand Up @@ -243,7 +241,7 @@ export interface ITerminalEditorService extends ITerminalInstanceHost {
detachInstance(instance: ITerminalInstance): void;
splitInstance(instanceToSplit: ITerminalInstance, shellLaunchConfig?: IShellLaunchConfig): ITerminalInstance;
revealActiveEditor(preserveFocus?: boolean): Promise<void>;
resolveResource(instance: ITerminalInstance | URI): URI;
resolveResource(instance: ITerminalInstance): URI;
reviveInput(deserializedInput: IDeserializedTerminalEditorInput): EditorInput;
getInputFromResource(resource: URI): EditorInput;
}
Expand All @@ -267,11 +265,9 @@ interface ITerminalEditorInputObject {
}

export interface ISerializedTerminalEditorInput extends ITerminalEditorInputObject {
readonly resource: string;
}

export interface IDeserializedTerminalEditorInput extends ITerminalEditorInputObject {
readonly resource: URI;
}

export type ITerminalLocationOptions = TerminalLocation | TerminalEditorLocation | { parentTerminal: ITerminalInstance } | { splitActiveTerminal: boolean };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { URI } from 'vs/base/common/uri';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IEditorSerializer } from 'vs/workbench/common/editor';
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
Expand All @@ -29,7 +28,6 @@ export class TerminalInputSerializer implements IEditorSerializer {

public deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput | undefined {
const terminalInstance = JSON.parse(serializedEditorInput);
terminalInstance.resource = URI.parse(terminalInstance.resource);
return this._terminalEditorService.reviveInput(terminalInstance);
}

Expand All @@ -42,7 +40,6 @@ export class TerminalInputSerializer implements IEditorSerializer {
cwd: '',
icon: instance.icon,
color: instance.color,
resource: instance.resource.toString(),
hasChildProcesses: instance.hasChildProcesses,
isFeatureTerminal: instance.shellLaunchConfig.isFeatureTerminal,
hideFromUser: instance.shellLaunchConfig.hideFromUser,
Expand Down
47 changes: 9 additions & 38 deletions src/vs/workbench/contrib/terminal/browser/terminalEditorService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@ import { IEditorPane } from 'vs/workbench/common/editor';
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { IDeserializedTerminalEditorInput, ITerminalEditorService, ITerminalInstance, ITerminalInstanceService, TerminalEditorLocation } from 'vs/workbench/contrib/terminal/browser/terminal';
import { TerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorInput';
import { getInstanceFromResource, parseTerminalUri } from 'vs/workbench/contrib/terminal/browser/terminalUri';
import { getInstanceFromResource } from 'vs/workbench/contrib/terminal/browser/terminalUri';
import { TerminalContextKeys } from 'vs/workbench/contrib/terminal/common/terminalContextKey';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorService, ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle';

export class TerminalEditorService extends Disposable implements ITerminalEditorService {
Expand Down Expand Up @@ -51,7 +50,6 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor
@ITerminalInstanceService private readonly _terminalInstanceService: ITerminalInstanceService,
@IInstantiationService private readonly _instantiationService: IInstantiationService,
@ILifecycleService lifecycleService: ILifecycleService,
@IWorkbenchEnvironmentService private readonly _environmentService: IWorkbenchEnvironmentService,
@IContextKeyService contextKeyService: IContextKeyService
) {
super();
Expand Down Expand Up @@ -160,43 +158,19 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor
}
}

resolveResource(instanceOrUri: ITerminalInstance | URI, isFutureSplit: boolean = false): URI {
const resource: URI = URI.isUri(instanceOrUri) ? instanceOrUri : instanceOrUri.resource;
resolveResource(instance: ITerminalInstance): URI {
const resource = instance.resource;
const inputKey = resource.path;
const cachedEditor = this._editorInputs.get(inputKey);

if (cachedEditor) {
return cachedEditor.resource;
}

// Terminal from a different window
if (URI.isUri(instanceOrUri)) {
const terminalIdentifier = parseTerminalUri(instanceOrUri);
if (terminalIdentifier.instanceId) {
this._terminalInstanceService.getBackend(this._environmentService.remoteAuthority).then(primaryBackend => {
primaryBackend?.requestDetachInstance(terminalIdentifier.workspaceId, terminalIdentifier.instanceId!).then(attachPersistentProcess => {
const instance = this._terminalInstanceService.createInstance({ attachPersistentProcess }, TerminalLocation.Editor, resource);
input = this._instantiationService.createInstance(TerminalEditorInput, resource, instance);
this._editorService.openEditor(input, {
pinned: true,
forceReload: true
}, input.group);
this._registerInstance(inputKey, input, instance);
return instanceOrUri;
});
});
}
}

let input: TerminalEditorInput;
if ('instanceId' in instanceOrUri) {
instanceOrUri.target = TerminalLocation.Editor;
input = this._instantiationService.createInstance(TerminalEditorInput, resource, instanceOrUri);
this._registerInstance(inputKey, input, instanceOrUri);
return input.resource;
} else {
return instanceOrUri;
}
instance.target = TerminalLocation.Editor;
const input = this._instantiationService.createInstance(TerminalEditorInput, resource, instance);
this._registerInstance(inputKey, input, instance);
return input.resource;
}

getInputFromResource(resource: URI): TerminalEditorInput {
Expand Down Expand Up @@ -247,14 +221,11 @@ export class TerminalEditorService extends Disposable implements ITerminalEditor
}

reviveInput(deserializedInput: IDeserializedTerminalEditorInput): EditorInput {
const resource: URI = URI.isUri(deserializedInput) ? deserializedInput : deserializedInput.resource;
const inputKey = resource.path;

if ('pid' in deserializedInput) {
const newDeserializedInput = { ...deserializedInput, findRevivedId: true };
const instance = this._terminalInstanceService.createInstance({ attachPersistentProcess: newDeserializedInput }, TerminalLocation.Editor);
const input = this._instantiationService.createInstance(TerminalEditorInput, resource, instance);
this._registerInstance(inputKey, input, instance);
const input = this._instantiationService.createInstance(TerminalEditorInput, instance.resource, instance);
this._registerInstance(instance.resource.path, input, instance);
return input;
} else {
throw new Error(`Could not revive terminal editor input, ${deserializedInput}`);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,6 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
private readonly _terminalSuggestWidgetVisibleContextKey: IContextKey<boolean>,
private readonly _configHelper: TerminalConfigHelper,
private _shellLaunchConfig: IShellLaunchConfig,
resource: URI | undefined,
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
@IInstantiationService instantiationService: IInstantiationService,
@ITerminalProfileResolverService private readonly _terminalProfileResolverService: ITerminalProfileResolverService,
Expand Down Expand Up @@ -390,8 +389,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
this._fixedRows = _shellLaunchConfig.attachPersistentProcess?.fixedDimensions?.rows;
this._fixedCols = _shellLaunchConfig.attachPersistentProcess?.fixedDimensions?.cols;

// the resource is already set when it's been moved from another window
this._resource = resource || getTerminalUri(this._workspaceContextService.getWorkspace().id, this.instanceId, this.title);
this._resource = getTerminalUri(this._workspaceContextService.getWorkspace().id, this.instanceId, this.title);

if (this._shellLaunchConfig.attachPersistentProcess?.hideFromUser) {
this._shellLaunchConfig.hideFromUser = this._shellLaunchConfig.attachPersistentProcess.hideFromUser;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,16 @@ export class TerminalInstanceService extends Disposable implements ITerminalInst
}
}

createInstance(profile: ITerminalProfile, target: TerminalLocation, resource?: URI): ITerminalInstance;
createInstance(shellLaunchConfig: IShellLaunchConfig, target: TerminalLocation, resource?: URI): ITerminalInstance;
createInstance(config: IShellLaunchConfig | ITerminalProfile, target: TerminalLocation, resource?: URI): ITerminalInstance {
createInstance(profile: ITerminalProfile, target: TerminalLocation): ITerminalInstance;
createInstance(shellLaunchConfig: IShellLaunchConfig, target: TerminalLocation): ITerminalInstance;
createInstance(config: IShellLaunchConfig | ITerminalProfile, target: TerminalLocation): ITerminalInstance {
const shellLaunchConfig = this.convertProfileToShellLaunchConfig(config);
const instance = this._instantiationService.createInstance(TerminalInstance,
this._terminalShellTypeContextKey,
this._terminalInRunCommandPicker,
this._terminalSuggestWidgetVisibleContextKey,
this._configHelper,
shellLaunchConfig,
resource
shellLaunchConfig
);
instance.target = target;
this._onDidCreateInstance.fire(instance);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@

import { Disposable } from 'vs/base/common/lifecycle';
import { Schemas } from 'vs/base/common/network';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ILabelService } from 'vs/platform/label/common/label';
import { TerminalLocation } from 'vs/platform/terminal/common/terminal';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { ITerminalEditorService, ITerminalGroupService, ITerminalService, terminalEditorId } from 'vs/workbench/contrib/terminal/browser/terminal';
import { ITerminalEditorService, ITerminalGroupService, ITerminalInstanceService, ITerminalService, terminalEditorId } from 'vs/workbench/contrib/terminal/browser/terminal';
import { parseTerminalUri } from 'vs/workbench/contrib/terminal/browser/terminalUri';
import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings';
import { IEditorResolverService, RegisteredEditorPriority } from 'vs/workbench/services/editor/common/editorResolverService';

Expand All @@ -24,7 +25,7 @@ export class TerminalMainContribution extends Disposable implements IWorkbenchCo
@ITerminalService terminalService: ITerminalService,
@ITerminalEditorService terminalEditorService: ITerminalEditorService,
@ITerminalGroupService terminalGroupService: ITerminalGroupService,
@IConfigurationService configurationService: IConfigurationService
@ITerminalInstanceService terminalInstanceService: ITerminalInstanceService
) {
super();

Expand All @@ -41,14 +42,31 @@ export class TerminalMainContribution extends Disposable implements IWorkbenchCo
singlePerResource: true
},
{
createEditorInput: ({ resource, options }) => {
const instance = terminalService.getInstanceFromResource(resource);
createEditorInput: async ({ resource, options }) => {
let instance = terminalService.getInstanceFromResource(resource);
if (instance) {
const sourceGroup = terminalGroupService.getGroupForInstance(instance);
sourceGroup?.removeInstance(instance);
} else { // Terminal from a different window
const terminalIdentifier = parseTerminalUri(resource);
if (!terminalIdentifier.instanceId) {
throw new Error('Terminal identifier without instanceId');
}

const primaryBackend = terminalService.getPrimaryBackend();
if (!primaryBackend) {
throw new Error('No terminal primary backend');
}

const attachPersistentProcess = await primaryBackend.requestDetachInstance(terminalIdentifier.workspaceId, terminalIdentifier.instanceId);
if (!attachPersistentProcess) {
throw new Error('No terminal persistent process to attach');
}
instance = terminalInstanceService.createInstance({ attachPersistentProcess }, TerminalLocation.Editor);
}
const resolvedResource = terminalEditorService.resolveResource(instance || resource);
const editor = terminalEditorService.getInputFromResource(resolvedResource) || { editor: resolvedResource };

const resolvedResource = terminalEditorService.resolveResource(instance);
const editor = terminalEditorService.getInputFromResource(resolvedResource);
return {
editor,
options: {
Expand Down
4 changes: 2 additions & 2 deletions src/vs/workbench/contrib/terminal/browser/terminalService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -956,7 +956,7 @@ export class TerminalService implements ITerminalService {
throw new Error('Could not create terminal when process support is not registered');
}
if (shellLaunchConfig.hideFromUser) {
const instance = this._terminalInstanceService.createInstance(shellLaunchConfig, TerminalLocation.Panel, options?.resource);
const instance = this._terminalInstanceService.createInstance(shellLaunchConfig, TerminalLocation.Panel);
this._backgroundedTerminalInstances.push(instance);
this._backgroundedTerminalDisposables.set(instance.instanceId, [
instance.onDisposed(this._onDidDisposeInstance.fire, this._onDidDisposeInstance)
Expand Down Expand Up @@ -1032,7 +1032,7 @@ export class TerminalService implements ITerminalService {
let instance;
const editorOptions = this._getEditorOptions(options?.location);
if (location === TerminalLocation.Editor) {
instance = this._terminalInstanceService.createInstance(shellLaunchConfig, TerminalLocation.Editor, options?.resource);
instance = this._terminalInstanceService.createInstance(shellLaunchConfig, TerminalLocation.Editor);
this._terminalEditorService.openEditor(instance, editorOptions);
} else {
// TODO: pass resource?
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/test/browser/workbenchTestServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1805,7 +1805,7 @@ export class TestTerminalEditorService implements ITerminalEditorService {
detachInstance(instance: ITerminalInstance): void { throw new Error('Method not implemented.'); }
splitInstance(instanceToSplit: ITerminalInstance, shellLaunchConfig?: IShellLaunchConfig): ITerminalInstance { throw new Error('Method not implemented.'); }
revealActiveEditor(preserveFocus?: boolean): Promise<void> { throw new Error('Method not implemented.'); }
resolveResource(instance: ITerminalInstance | URI): URI { throw new Error('Method not implemented.'); }
resolveResource(instance: ITerminalInstance): URI { throw new Error('Method not implemented.'); }
reviveInput(deserializedInput: IDeserializedTerminalEditorInput): TerminalEditorInput { throw new Error('Method not implemented.'); }
getInputFromResource(resource: URI): TerminalEditorInput { throw new Error('Method not implemented.'); }
setActiveInstance(instance: ITerminalInstance): void { throw new Error('Method not implemented.'); }
Expand Down