Skip to content

Commit 7130434

Browse files
authored
Merge branch 'master' into joh/notebook-inputs
2 parents 9d5a45a + f1c7a1a commit 7130434

6 files changed

Lines changed: 108 additions & 43 deletions

File tree

src/vs/platform/workspaces/electron-main/workspacesMainService.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,8 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain
185185
};
186186
}
187187

188-
getWorkspaceIdentifier(configPath: URI): Promise<IWorkspaceIdentifier> {
189-
return Promise.resolve(getWorkspaceIdentifier(configPath));
188+
async getWorkspaceIdentifier(configPath: URI): Promise<IWorkspaceIdentifier> {
189+
return getWorkspaceIdentifier(configPath);
190190
}
191191

192192
isUntitledWorkspace(workspace: IWorkspaceIdentifier): boolean {
@@ -205,9 +205,8 @@ export class WorkspacesMainService extends Disposable implements IWorkspacesMain
205205
this._onUntitledWorkspaceDeleted.fire(workspace);
206206
}
207207

208-
deleteUntitledWorkspace(workspace: IWorkspaceIdentifier): Promise<void> {
208+
async deleteUntitledWorkspace(workspace: IWorkspaceIdentifier): Promise<void> {
209209
this.deleteUntitledWorkspaceSync(workspace);
210-
return Promise.resolve();
211210
}
212211

213212
private doDeleteUntitledWorkspaceSync(workspace: IWorkspaceIdentifier): void {

src/vs/workbench/api/node/extHostDebugService.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ export class ExtHostDebugService extends ExtHostDebugServiceBase {
8888

8989
const configProvider = await this._configurationService.getConfigProvider();
9090
const shell = this._terminalService.getDefaultShell(true, configProvider);
91+
let cwdForPrepareCommand: string | undefined;
9192

9293
if (needNewTerminal || !this._integratedTerminalInstance) {
9394

@@ -97,16 +98,17 @@ export class ExtHostDebugService extends ExtHostDebugServiceBase {
9798
cwd: args.cwd,
9899
name: args.title || nls.localize('debug.terminal.title', "debuggee"),
99100
};
100-
delete (args as any).cwd; // TODO: remove this any cast
101101
this._integratedTerminalInstance = this._terminalService.createTerminalFromOptions(options);
102+
} else {
103+
cwdForPrepareCommand = args.cwd;
102104
}
103105

104106
const terminal = this._integratedTerminalInstance;
105107

106108
terminal.show();
107109

108110
const shellProcessId = await this._integratedTerminalInstance.processId;
109-
const command = prepareCommand(args, shell);
111+
const command = prepareCommand(shell, args.args, cwdForPrepareCommand, args.env);
110112
terminal.sendText(command, true);
111113

112114
return shellProcessId;

src/vs/workbench/contrib/debug/node/terminals.ts

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import * as cp from 'child_process';
7-
import * as env from 'vs/base/common/platform';
7+
import * as platform from 'vs/base/common/platform';
88
import { WindowsExternalTerminalService, MacExternalTerminalService, LinuxExternalTerminalService } from 'vs/workbench/contrib/externalTerminal/node/externalTerminalService';
99
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
1010
import { IExternalTerminalService } from 'vs/workbench/contrib/externalTerminal/common/externalTerminal';
@@ -14,11 +14,11 @@ let externalTerminalService: IExternalTerminalService | undefined = undefined;
1414

1515
export function runInExternalTerminal(args: DebugProtocol.RunInTerminalRequestArguments, configProvider: ExtHostConfigProvider): Promise<number | undefined> {
1616
if (!externalTerminalService) {
17-
if (env.isWindows) {
17+
if (platform.isWindows) {
1818
externalTerminalService = new WindowsExternalTerminalService(<IConfigurationService><unknown>undefined);
19-
} else if (env.isMacintosh) {
19+
} else if (platform.isMacintosh) {
2020
externalTerminalService = new MacExternalTerminalService(<IConfigurationService><unknown>undefined);
21-
} else if (env.isLinux) {
21+
} else if (platform.isLinux) {
2222
externalTerminalService = new LinuxExternalTerminalService(<IConfigurationService><unknown>undefined);
2323
} else {
2424
throw new Error('external terminals not supported on this platform');
@@ -49,7 +49,7 @@ function spawnAsPromised(command: string, args: string[]): Promise<string> {
4949
export function hasChildProcesses(processId: number | undefined): Promise<boolean> {
5050
if (processId) {
5151
// if shell has at least one child process, assume that shell is busy
52-
if (env.isWindows) {
52+
if (platform.isWindows) {
5353
return spawnAsPromised('wmic', ['process', 'get', 'ParentProcessId']).then(stdout => {
5454
const pids = stdout.split('\r\n');
5555
return pids.some(p => parseInt(p) === processId);
@@ -75,7 +75,8 @@ export function hasChildProcesses(processId: number | undefined): Promise<boolea
7575

7676
const enum ShellType { cmd, powershell, bash }
7777

78-
export function prepareCommand(args: DebugProtocol.RunInTerminalRequestArguments, shell: string): string {
78+
79+
export function prepareCommand(shell: string, args: string[], cwd?: string, env?: { [key: string]: string | null; }): string {
7980

8081
shell = shell.trim().toLowerCase();
8182

@@ -87,7 +88,7 @@ export function prepareCommand(args: DebugProtocol.RunInTerminalRequestArguments
8788
shellType = ShellType.cmd;
8889
} else if (shell.indexOf('bash') >= 0) {
8990
shellType = ShellType.bash;
90-
} else if (env.isWindows) {
91+
} else if (platform.isWindows) {
9192
shellType = ShellType.cmd; // pick a good default for Windows
9293
} else {
9394
shellType = ShellType.bash; // pick a good default for anything else
@@ -109,23 +110,23 @@ export function prepareCommand(args: DebugProtocol.RunInTerminalRequestArguments
109110
return `'${s}'`;
110111
};
111112

112-
if (args.cwd) {
113-
command += `cd '${args.cwd}'; `;
113+
if (cwd) {
114+
command += `cd '${cwd}'; `;
114115
}
115-
if (args.env) {
116-
for (let key in args.env) {
117-
const value = args.env[key];
116+
if (env) {
117+
for (let key in env) {
118+
const value = env[key];
118119
if (value === null) {
119120
command += `Remove-Item env:${key}; `;
120121
} else {
121122
command += `\${env:${key}}='${value}'; `;
122123
}
123124
}
124125
}
125-
if (args.args && args.args.length > 0) {
126-
const cmd = quote(args.args.shift()!);
126+
if (args.length > 0) {
127+
const cmd = quote(args.shift()!);
127128
command += (cmd[0] === '\'') ? `& ${cmd} ` : `${cmd} `;
128-
for (let a of args.args) {
129+
for (let a of args) {
129130
command += `${quote(a)} `;
130131
}
131132
}
@@ -138,13 +139,13 @@ export function prepareCommand(args: DebugProtocol.RunInTerminalRequestArguments
138139
return (s.indexOf(' ') >= 0 || s.indexOf('"') >= 0 || s.length === 0) ? `"${s}"` : s;
139140
};
140141

141-
if (args.cwd) {
142-
command += `cd ${quote(args.cwd)} && `;
142+
if (cwd) {
143+
command += `cd ${quote(cwd)} && `;
143144
}
144-
if (args.env) {
145+
if (env) {
145146
command += 'cmd /C "';
146-
for (let key in args.env) {
147-
let value = args.env[key];
147+
for (let key in env) {
148+
let value = env[key];
148149
if (value === null) {
149150
command += `set "${key}=" && `;
150151
} else {
@@ -153,10 +154,10 @@ export function prepareCommand(args: DebugProtocol.RunInTerminalRequestArguments
153154
}
154155
}
155156
}
156-
for (let a of args.args) {
157+
for (let a of args) {
157158
command += `${quote(a)} `;
158159
}
159-
if (args.env) {
160+
if (env) {
160161
command += '"';
161162
}
162163
break;
@@ -172,13 +173,13 @@ export function prepareCommand(args: DebugProtocol.RunInTerminalRequestArguments
172173
return /[^\w@%\/+=,.:^-]/.test(s) ? `'${s.replace(/'/g, '\'\\\'\'')}'` : s;
173174
};
174175

175-
if (args.cwd) {
176-
command += `cd ${quote(args.cwd)} ; `;
176+
if (cwd) {
177+
command += `cd ${quote(cwd)} ; `;
177178
}
178-
if (args.env) {
179+
if (env) {
179180
command += 'env';
180-
for (let key in args.env) {
181-
const value = args.env[key];
181+
for (let key in env) {
182+
const value = env[key];
182183
if (value === null) {
183184
command += ` -u ${hardQuote(key)}`;
184185
} else {
@@ -187,7 +188,7 @@ export function prepareCommand(args: DebugProtocol.RunInTerminalRequestArguments
187188
}
188189
command += ' ';
189190
}
190-
for (let a of args.args) {
191+
for (let a of args) {
191192
command += `${quote(a)} `;
192193
}
193194
break;

src/vs/workbench/contrib/files/common/editors/fileEditorInput.ts

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,10 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements
236236
}
237237

238238
private async doResolveAsText(): Promise<ITextFileEditorModel | BinaryEditorModel> {
239-
240-
// Resolve as text
241239
try {
240+
241+
// Resolve resource via text file service and only allow
242+
// to open binary files if we are instructed so
242243
await this.textFileService.files.resolve(this.resource, {
243244
mode: this.preferredMode,
244245
encoding: this.preferredEncoding,
@@ -255,7 +256,16 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements
255256
this.cachedTextFileModelReference = await this.textModelResolverService.createModelReference(this.resource) as IReference<ITextFileEditorModel>;
256257
}
257258

258-
return this.cachedTextFileModelReference.object;
259+
const model = this.cachedTextFileModelReference.object;
260+
261+
// It is possible that this input was disposed before the model
262+
// finished resolving. As such, we need to make sure to dispose
263+
// the model reference to not leak it.
264+
if (this.isDisposed()) {
265+
this.disposeModelReference();
266+
}
267+
268+
return model;
259269
} catch (error) {
260270

261271
// In case of an error that indicates that the file is binary or too large, just return with the binary editor model
@@ -321,9 +331,13 @@ export class FileEditorInput extends AbstractTextResourceEditorInput implements
321331
this.model = undefined;
322332

323333
// Model reference
324-
dispose(this.cachedTextFileModelReference);
325-
this.cachedTextFileModelReference = undefined;
334+
this.disposeModelReference();
326335

327336
super.dispose();
328337
}
338+
339+
private disposeModelReference(): void {
340+
dispose(this.cachedTextFileModelReference);
341+
this.cachedTextFileModelReference = undefined;
342+
}
329343
}

src/vs/workbench/contrib/userDataSync/browser/userDataSyncViews.ts

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,12 +186,12 @@ export class UserDataSyncDataViews extends Disposable {
186186
registerAction2(class extends Action2 {
187187
constructor() {
188188
super({
189-
id: `workbench.actions.sync.editCurrentMachineName`,
190-
title: localize('workbench.actions.sync.editCurrentMachineName', "Edit Name"),
189+
id: `workbench.actions.sync.editMachineName`,
190+
title: localize('workbench.actions.sync.editMachineName', "Edit Name"),
191191
icon: Codicon.edit,
192192
menu: {
193193
id: MenuId.ViewItemContext,
194-
when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', id), ContextKeyEqualsExpr.create('viewItem', 'sync-machine')),
194+
when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', id)),
195195
group: 'inline',
196196
},
197197
});
@@ -203,6 +203,25 @@ export class UserDataSyncDataViews extends Disposable {
203203
}
204204
}
205205
});
206+
207+
registerAction2(class extends Action2 {
208+
constructor() {
209+
super({
210+
id: `workbench.actions.sync.turnOffSyncOnMachine`,
211+
title: localize('workbench.actions.sync.turnOffSyncOnMachine', "Turn off Preferences Sync"),
212+
menu: {
213+
id: MenuId.ViewItemContext,
214+
when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', id), ContextKeyEqualsExpr.create('viewItem', 'sync-machine')),
215+
},
216+
});
217+
}
218+
async run(accessor: ServicesAccessor, handle: TreeViewItemHandleArg): Promise<void> {
219+
if (await dataProvider.disable(handle.$treeItemHandle)) {
220+
await treeView.refresh();
221+
}
222+
}
223+
});
224+
206225
}
207226

208227
private registerDataViewActions(viewId: string) {
@@ -461,7 +480,10 @@ class UserDataSyncMachinesViewDataProvider implements ITreeViewDataProvider {
461480
@IUserDataSyncMachinesService private readonly userDataSyncMachinesService: IUserDataSyncMachinesService,
462481
@IQuickInputService private readonly quickInputService: IQuickInputService,
463482
@INotificationService private readonly notificationService: INotificationService,
464-
) { }
483+
@IDialogService private readonly dialogService: IDialogService,
484+
@IUserDataSyncWorkbenchService private readonly userDataSyncWorkbenchService: IUserDataSyncWorkbenchService,
485+
) {
486+
}
465487

466488
async getChildren(element?: ITreeItem): Promise<ITreeItem[]> {
467489
if (!element) {
@@ -492,6 +514,32 @@ class UserDataSyncMachinesViewDataProvider implements ITreeViewDataProvider {
492514
return this.machinesPromise;
493515
}
494516

517+
async disable(machineId: string): Promise<boolean> {
518+
const machines = await this.getMachines();
519+
const machine = machines.find(({ id }) => id === machineId);
520+
if (!machine) {
521+
throw new Error(localize('not found', "machine not found with id: {0}", machineId));
522+
}
523+
524+
const result = await this.dialogService.confirm({
525+
type: 'info',
526+
message: localize('turn off sync on machine', "Are you sure you want to turn off sync on {0}?", machine.name),
527+
primaryButton: localize('turn off', "Turn off"),
528+
});
529+
530+
if (!result.confirmed) {
531+
return false;
532+
}
533+
534+
if (machine.isCurrent) {
535+
await this.userDataSyncWorkbenchService.turnoff(false);
536+
} else {
537+
await this.userDataSyncMachinesService.disableMachine(machineId);
538+
}
539+
540+
return true;
541+
}
542+
495543
async rename(machineId: string): Promise<boolean> {
496544
const disposableStore = new DisposableStore();
497545
const inputBox = disposableStore.add(this.quickInputService.createInputBox());

src/vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ export abstract class AbstractWorkspaceEditingService implements IWorkspaceEditi
201201
const untitledWorkspace = await this.workspacesService.createUntitledWorkspace(folders, remoteAuthority);
202202
if (path) {
203203
await this.saveWorkspaceAs(untitledWorkspace, path);
204+
await this.workspacesService.deleteUntitledWorkspace(untitledWorkspace); // https://github.com/microsoft/vscode/issues/100276
204205
} else {
205206
path = untitledWorkspace.configPath;
206207
}

0 commit comments

Comments
 (0)