Merge from vscode 93309f060778f6480a7d2a13913e6e7c624e9bc7

This commit is contained in:
ADS Merger
2020-03-26 07:08:23 +00:00
parent 685e0ccf7e
commit f5134198e2
87 changed files with 942 additions and 631 deletions

View File

@@ -34,7 +34,8 @@ const BUILT_IN_AUTH_DEPENDENTS: AuthDependent[] = [
export class MainThreadAuthenticationProvider extends Disposable {
private _sessionMenuItems = new Map<string, IDisposable[]>();
private _sessionIds: string[] = [];
private _accounts = new Map<string, string[]>(); // Map account name to session ids
private _sessions = new Map<string, string>(); // Map account id to name
constructor(
private readonly _proxy: ExtHostAuthenticationShape,
@@ -44,10 +45,6 @@ export class MainThreadAuthenticationProvider extends Disposable {
) {
super();
if (!dependents.length) {
return;
}
this.registerCommandsAndContextMenuItems();
}
@@ -86,21 +83,23 @@ export class MainThreadAuthenticationProvider extends Disposable {
}
private registerCommandsAndContextMenuItems(): void {
this._register(CommandsRegistry.registerCommand({
id: `signIn${this.id}`,
handler: (accessor, args) => {
this.setPermissionsForAccount(accessor.get(IQuickInputService), true);
},
}));
this._register(MenuRegistry.appendMenuItem(MenuId.AccountsContext, {
group: '2_providers',
command: {
if (this.dependents.length) {
this._register(CommandsRegistry.registerCommand({
id: `signIn${this.id}`,
title: nls.localize('addAccount', "Sign in to {0}", this.displayName)
},
order: 3
}));
handler: (accessor, args) => {
this.setPermissionsForAccount(accessor.get(IQuickInputService), true);
},
}));
this._register(MenuRegistry.appendMenuItem(MenuId.AccountsContext, {
group: '2_providers',
command: {
id: `signIn${this.id}`,
title: nls.localize('addAccount', "Sign in to {0}", this.displayName)
},
order: 3
}));
}
this._proxy.$getSessions(this.id).then(sessions => {
sessions.forEach(session => this.registerSession(session));
@@ -108,7 +107,16 @@ export class MainThreadAuthenticationProvider extends Disposable {
}
private registerSession(session: modes.AuthenticationSession) {
this._sessionIds.push(session.id);
this._sessions.set(session.id, session.accountName);
const existingSessionsForAccount = this._accounts.get(session.accountName);
if (existingSessionsForAccount) {
this._accounts.set(session.accountName, existingSessionsForAccount.concat(session.id));
return;
} else {
this._accounts.set(session.accountName, [session.id]);
}
const menuItem = MenuRegistry.appendMenuItem(MenuId.AccountsContext, {
group: '1_accounts',
command: {
@@ -131,7 +139,8 @@ export class MainThreadAuthenticationProvider extends Disposable {
quickPick.onDidAccept(e => {
const selected = quickPick.selectedItems[0];
if (selected.label === 'Sign Out') {
this.logout(session.id);
const sessionsForAccount = this._accounts.get(session.accountName);
sessionsForAccount?.forEach(sessionId => this.logout(sessionId));
}
quickPick.dispose();
@@ -145,7 +154,7 @@ export class MainThreadAuthenticationProvider extends Disposable {
},
});
this._sessionMenuItems.set(session.id, [menuItem, manageCommand]);
this._sessionMenuItems.set(session.accountName, [menuItem, manageCommand]);
}
async getSessions(): Promise<ReadonlyArray<modes.AuthenticationSession>> {
@@ -158,22 +167,29 @@ export class MainThreadAuthenticationProvider extends Disposable {
});
}
async updateSessionItems(): Promise<void> {
const currentSessions = await this._proxy.$getSessions(this.id);
const removedSessionIds = this._sessionIds.filter(id => !currentSessions.some(session => session.id === id));
const addedSessions = currentSessions.filter(session => !this._sessionIds.some(id => id === session.id));
async updateSessionItems(event: modes.AuthenticationSessionsChangeEvent): Promise<void> {
const { added, removed } = event;
const session = await this._proxy.$getSessions(this.id);
const addedSessions = session.filter(session => added.some(id => id === session.id));
removedSessionIds.forEach(id => {
const disposeables = this._sessionMenuItems.get(id);
if (disposeables) {
disposeables.forEach(disposeable => disposeable.dispose());
this._sessionMenuItems.delete(id);
removed.forEach(sessionId => {
const accountName = this._sessions.get(sessionId);
if (accountName) {
let sessionsForAccount = this._accounts.get(accountName) || [];
const sessionIndex = sessionsForAccount.indexOf(sessionId);
sessionsForAccount.splice(sessionIndex);
if (!sessionsForAccount.length) {
const disposeables = this._sessionMenuItems.get(accountName);
if (disposeables) {
disposeables.forEach(disposeable => disposeable.dispose());
this._sessionMenuItems.delete(accountName);
}
}
}
});
addedSessions.forEach(session => this.registerSession(session));
this._sessionIds = currentSessions.map(session => session.id);
}
login(scopes: string[]): Promise<modes.AuthenticationSession> {

View File

@@ -752,18 +752,23 @@ class MainThreadCustomEditorModel extends Disposable implements ICustomEditorMod
});
}
public async save(_options?: ISaveOptions): Promise<boolean> {
public async save(options?: ISaveOptions): Promise<boolean> {
return !!await this.saveCustomEditor(options);
}
public async saveCustomEditor(_options?: ISaveOptions): Promise<URI | undefined> {
if (!this._editable) {
return false;
return undefined;
}
// TODO: handle save untitled case
await createCancelablePromise(token => this._proxy.$onSave(this._editorResource, this.viewType, token));
this.change(() => {
this._savePoint = this._currentEditIndex;
});
return true;
return this._editorResource;
}
public async saveAs(resource: URI, targetResource: URI, _options?: ISaveOptions): Promise<boolean> {
public async saveCustomEditorAs(resource: URI, targetResource: URI, _options?: ISaveOptions): Promise<boolean> {
if (this._editable) {
await this._proxy.$onSaveAs(this._editorResource, this.viewType, targetResource);
this.change(() => {

View File

@@ -3,18 +3,39 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { ExtHostNotebookShape, IMainContext, MainThreadNotebookShape, MainContext, ICellDto, NotebookCellsSplice, NotebookCellOutputsSplice, CellKind, CellOutputKind } from 'vs/workbench/api/common/extHost.protocol';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { Disposable as VSCodeDisposable } from './extHostTypes';
import { URI, UriComponents } from 'vs/base/common/uri';
import { DisposableStore, Disposable } from 'vs/base/common/lifecycle';
import { readonly } from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
import { INotebookDisplayOrder, ITransformedDisplayOutputDto, IOrderedMimeType, IStreamOutput, IErrorOutput, mimeTypeSupportedByCore, IOutput, sortMimeTypes, diff, CellUri } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
import { ISplice } from 'vs/base/common/sequence';
import { URI, UriComponents } from 'vs/base/common/uri';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { CellKind, CellOutputKind, ExtHostNotebookShape, ICellDto, IMainContext, MainContext, MainThreadNotebookShape, NotebookCellOutputsSplice, NotebookCellsSplice } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostCommands } from 'vs/workbench/api/common/extHostCommands';
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
import { CellUri, diff, IErrorOutput, INotebookDisplayOrder, IOrderedMimeType, IOutput, IStreamOutput, ITransformedDisplayOutputDto, mimeTypeSupportedByCore, sortMimeTypes } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import * as vscode from 'vscode';
import { Disposable as VSCodeDisposable } from './extHostTypes';
interface IObservable<T> {
proxy: T;
onDidChange: Event<void>;
}
function getObservable<T extends Object>(obj: T): IObservable<T> {
const onDidChange = new Emitter<void>();
const proxy = new Proxy(obj, {
set(target: T, p: PropertyKey, value: any, _receiver: any): boolean {
target[p as keyof T] = value;
onDidChange.fire();
return true;
}
});
return {
proxy,
onDidChange: onDidChange.event
};
}
const notebookDocumentMetadataDefaults: vscode.NotebookDocumentMetadata = {
editable: true,
@@ -22,8 +43,7 @@ const notebookDocumentMetadataDefaults: vscode.NotebookDocumentMetadata = {
cellRunnable: true
};
export class ExtHostCell implements vscode.NotebookCell {
export class ExtHostCell extends Disposable implements vscode.NotebookCell {
public source: string[];
private _outputs: any[];
private _onDidChangeOutputs = new Emitter<ISplice<vscode.CellOutput>[]>();
@@ -31,6 +51,9 @@ export class ExtHostCell implements vscode.NotebookCell {
private _textDocument: vscode.TextDocument | undefined;
private _initalVersion: number = -1;
private _outputMapping = new Set<vscode.CellOutput>();
private _metadata: vscode.NotebookCellMetadata;
private _metadataChangeListener: IDisposable;
constructor(
private viewType: string,
@@ -41,11 +64,19 @@ export class ExtHostCell implements vscode.NotebookCell {
public cellKind: CellKind,
public language: string,
outputs: any[],
private _metadata: vscode.NotebookCellMetadata | undefined,
_metadata: vscode.NotebookCellMetadata | undefined,
private _proxy: MainThreadNotebookShape
) {
super();
this.source = this._content.split(/\r|\n|\r\n/g);
this._outputs = outputs;
const observableMetadata = getObservable(_metadata || {} as any);
this._metadata = observableMetadata.proxy;
this._metadataChangeListener = this._register(observableMetadata.onDidChange(() => {
this.updateMetadata();
}));
}
get outputs() {
@@ -76,13 +107,18 @@ export class ExtHostCell implements vscode.NotebookCell {
}
set metadata(newMetadata: vscode.NotebookCellMetadata | undefined) {
const newMetadataWithDefaults: vscode.NotebookCellMetadata | undefined = newMetadata ? {
editable: newMetadata.editable,
runnable: newMetadata.runnable
} : undefined;
this._metadataChangeListener.dispose();
const observableMetadata = getObservable(newMetadata || {} as any); // TODO defaults
this._metadata = observableMetadata.proxy;
this._metadataChangeListener = this._register(observableMetadata.onDidChange(() => {
this.updateMetadata();
}));
this._metadata = newMetadataWithDefaults;
this._proxy.$updateNotebookCellMetadata(this.viewType, this.documentUri, this.handle, newMetadataWithDefaults);
this.updateMetadata();
}
private updateMetadata(): Promise<void> {
return this._proxy.$updateNotebookCellMetadata(this.viewType, this.documentUri, this.handle, this._metadata);
}
getContent(): string {

View File

@@ -1362,7 +1362,7 @@ export enum CompletionItemTag {
export interface CompletionItemLabel {
name: string;
signature?: string;
parameters?: string;
qualifier?: string;
type?: string;
}