Merge remote-tracking branch 'origin/main' into alex/ghost-text

This commit is contained in:
Alex Dima
2021-05-21 19:57:53 +02:00
370 changed files with 10639 additions and 5701 deletions

View File

@@ -65,6 +65,7 @@ import './mainThreadComments';
import './mainThreadNotebook';
import './mainThreadNotebookKernels';
import './mainThreadNotebookDocumentsAndEditors';
import './mainThreadNotebookRenderers';
import './mainThreadTask';
import './mainThreadLabelService';
import './mainThreadTunnelService';

View File

@@ -16,7 +16,7 @@ import { isEqual, isEqualOrParent, toLocalResource } from 'vs/base/common/resour
import { URI, UriComponents } from 'vs/base/common/uri';
import { localize } from 'vs/nls';
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
import { FileSystemProviderCapabilities, IFileService } from 'vs/platform/files/common/files';
import { FileOperation, FileSystemProviderCapabilities, IFileService } from 'vs/platform/files/common/files';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ILabelService } from 'vs/platform/label/common/label';
import { IUndoRedoService, UndoRedoElementType } from 'vs/platform/undoRedo/common/undoRedo';
@@ -35,7 +35,7 @@ import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editor
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { IPathService } from 'vs/workbench/services/path/common/pathService';
import { IWorkingCopyFileService } from 'vs/workbench/services/workingCopy/common/workingCopyFileService';
import { IWorkingCopyFileService, WorkingCopyFileEvent } from 'vs/workbench/services/workingCopy/common/workingCopyFileService';
import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService';
import { IWorkingCopy, IWorkingCopyBackup, NO_TYPE_ID, WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopy';
import { ResourceWorkingCopy } from 'vs/workbench/services/workingCopy/common/resourceWorkingCopy';
@@ -51,6 +51,8 @@ export class MainThreadCustomEditors extends Disposable implements extHostProtoc
private readonly _editorProviders = new Map<string, IDisposable>();
private readonly _editorRenameBackups = new Map<string, CustomDocumentBackupData>();
constructor(
context: extHostProtocol.IExtHostContext,
private readonly mainThreadWebview: MainThreadWebviews,
@@ -61,7 +63,7 @@ export class MainThreadCustomEditors extends Disposable implements extHostProtoc
@ICustomEditorService private readonly _customEditorService: ICustomEditorService,
@IEditorGroupsService private readonly _editorGroupService: IEditorGroupsService,
@IWebviewWorkbenchService private readonly _webviewWorkbenchService: IWebviewWorkbenchService,
@IInstantiationService private readonly _instantiationService: IInstantiationService
@IInstantiationService private readonly _instantiationService: IInstantiationService,
) {
super();
@@ -90,6 +92,9 @@ export class MainThreadCustomEditors extends Disposable implements extHostProtoc
},
resolveWebview: () => { throw new Error('not implemented'); }
}));
// Working copy operations
this._register(workingCopyFileService.onWillRunWorkingCopyFileOperation(async e => this.onWillRunWorkingCopyFileOperation(e)));
}
override dispose() {
@@ -138,9 +143,18 @@ export class MainThreadCustomEditors extends Disposable implements extHostProtoc
webviewInput.webview.options = options;
webviewInput.webview.extension = extension;
// If there's an old resource this was a move and we must resolve the backup at the same time as the webview
// This is because the backup must be ready upon model creation, and the input resolve method comes after
let backupId = webviewInput.backupId;
if (webviewInput.oldResource && !webviewInput.backupId) {
const backup = this._editorRenameBackups.get(webviewInput.oldResource.toString());
backupId = backup?.backupId;
this._editorRenameBackups.delete(webviewInput.oldResource.toString());
}
let modelRef: IReference<ICustomEditorModel>;
try {
modelRef = await this.getOrCreateCustomEditorModel(modelType, resource, viewType, { backupId: webviewInput.backupId }, cancellation);
modelRef = await this.getOrCreateCustomEditorModel(modelType, resource, viewType, { backupId }, cancellation);
} catch (error) {
onUnexpectedError(error);
webviewInput.webview.html = this.mainThreadWebview.getWebviewResolvedFailedContent(viewType);
@@ -253,6 +267,31 @@ export class MainThreadCustomEditors extends Disposable implements extHostProtoc
}
return model;
}
//#region Working Copy
private async onWillRunWorkingCopyFileOperation(e: WorkingCopyFileEvent) {
if (e.operation !== FileOperation.MOVE) {
return;
}
e.waitUntil((async () => {
const models = [];
for (const file of e.files) {
if (file.source) {
models.push(...(await this._customEditorService.models.getAllModels(file.source)));
}
}
for (const model of models) {
if (model instanceof MainThreadCustomEditorModel && model.isDirty()) {
const workingCopy = await model.backup(CancellationToken.None);
if (workingCopy.meta) {
// This cast is safe because we do an instanceof check above and a custom document backup data is always returned
this._editorRenameBackups.set(model.editorResource.toString(), workingCopy.meta as CustomDocumentBackupData);
}
}
}
})());
}
//#endregion
}
namespace HotExitState {

View File

@@ -329,7 +329,8 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
type: session.configuration.type,
name: session.name,
folderUri: session.root ? session.root.uri : undefined,
configuration: session.configuration
configuration: session.configuration,
parent: session.parentSession?.getId(),
};
}
}

View File

@@ -9,13 +9,14 @@ import { URI, UriComponents } from 'vs/base/common/uri';
import { BoundModelReferenceCollection } from 'vs/workbench/api/browser/mainThreadDocuments';
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
import { IImmediateCellEditOperation, IMainCellDto, NotebookCellsChangeType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { IImmediateCellEditOperation, IMainCellDto, NotebookCellsChangeType, NotebookDataDto } from 'vs/workbench/contrib/notebook/common/notebookCommon';
import { INotebookEditorModelResolverService } from 'vs/workbench/contrib/notebook/common/notebookEditorModelResolverService';
import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
import { ExtHostContext, ExtHostNotebookShape, IExtHostContext, MainThreadNotebookDocumentsShape } from '../common/extHost.protocol';
import { MainThreadNotebooksAndEditors } from 'vs/workbench/api/browser/mainThreadNotebookDocumentsAndEditors';
import { onUnexpectedError } from 'vs/base/common/errors';
import { Schemas } from 'vs/base/common/network';
export class MainThreadNotebookDocuments implements MainThreadNotebookDocumentsShape {
@@ -47,7 +48,6 @@ export class MainThreadNotebookDocuments implements MainThreadNotebookDocumentsS
this._disposables.dispose();
this._modelReferenceCollection.dispose();
dispose(this._documentEventListenersMapping.values());
}
private _handleNotebooksAdded(notebooks: readonly NotebookTextModel[]): void {
@@ -119,14 +119,48 @@ export class MainThreadNotebookDocuments implements MainThreadNotebookDocumentsS
};
}
async $tryOpenDocument(uriComponents: UriComponents): Promise<URI> {
async $tryCreateNotebook(options: { viewType: string, content?: NotebookDataDto }): Promise<UriComponents> {
// find a free URI for the untitled case
let uri: URI;
for (let counter = 1; ; counter++) {
let candidate = URI.from({ scheme: Schemas.untitled, path: `Untitled-${counter}`, query: options.viewType });
if (!this._notebookService.getNotebookTextModel(candidate)) {
uri = candidate;
break;
}
}
const ref = await this._notebookEditorModelResolverService.resolve(uri, options.viewType);
// untitled notebooks are disposed when they get saved. we should not hold a reference
// to such a disposed notebook and therefore dispose the reference as well
ref.object.notebook.onWillDispose(() => {
ref.dispose();
});
// untitled notebooks are dirty by default
this._proxy.$acceptDirtyStateChanged(uri, true);
// apply content changes... slightly HACKY -> this triggers a change event
if (options.content) {
ref.object.notebook.reset(
options.content.cells,
options.content.metadata,
ref.object.notebook.transientOptions
);
}
return uri;
}
async $tryOpenNotebook(uriComponents: UriComponents): Promise<URI> {
const uri = URI.revive(uriComponents);
const ref = await this._notebookEditorModelResolverService.resolve(uri, undefined);
this._modelReferenceCollection.add(uri, ref);
return uri;
}
async $trySaveDocument(uriComponents: UriComponents) {
async $trySaveNotebook(uriComponents: UriComponents) {
const uri = URI.revive(uriComponents);
const ref = await this._notebookEditorModelResolverService.resolve(uri);

View File

@@ -0,0 +1,29 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Disposable } from 'vs/base/common/lifecycle';
import { ExtHostContext, ExtHostNotebookRenderersShape, IExtHostContext, MainContext, MainThreadNotebookRenderersShape } from 'vs/workbench/api/common/extHost.protocol';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { INotebookRendererMessagingService } from 'vs/workbench/contrib/notebook/common/notebookRendererMessagingService';
@extHostNamedCustomer(MainContext.MainThreadNotebookRenderers)
export class MainThreadNotebookRenderers extends Disposable implements MainThreadNotebookRenderersShape {
private readonly proxy: ExtHostNotebookRenderersShape;
constructor(
extHostContext: IExtHostContext,
@INotebookRendererMessagingService private readonly messaging: INotebookRendererMessagingService,
) {
super();
this.proxy = extHostContext.getProxy(ExtHostContext.ExtHostNotebookRenderers);
this._register(messaging.onShouldPostMessage(e => {
this.proxy.$postRendererMessage(e.editorId, e.rendererId, e.message);
}));
}
$postMessage(editorId: string, rendererId: string, message: unknown): void {
this.messaging.fireDidReceiveMessage(editorId, rendererId, message);
}
}

View File

@@ -27,7 +27,7 @@ export class MainThreadStatusBar implements MainThreadStatusBarShape {
this.entries.clear();
}
$setEntry(id: number, statusId: string, statusName: string, text: string, tooltip: string | undefined, command: Command | undefined, color: string | ThemeColor | undefined, backgroundColor: string | ThemeColor | undefined, alignment: MainThreadStatusBarAlignment, priority: number | undefined, accessibilityInformation: IAccessibilityInformation): void {
$setEntry(entryId: number, id: string, name: string, text: string, tooltip: string | undefined, command: Command | undefined, color: string | ThemeColor | undefined, backgroundColor: string | ThemeColor | undefined, alignment: MainThreadStatusBarAlignment, priority: number | undefined, accessibilityInformation: IAccessibilityInformation): void {
// if there are icons in the text use the tooltip for the aria label
let ariaLabel: string;
let role: string | undefined = undefined;
@@ -37,23 +37,23 @@ export class MainThreadStatusBar implements MainThreadStatusBarShape {
} else {
ariaLabel = getCodiconAriaLabel(text);
}
const entry: IStatusbarEntry = { text, tooltip, command, color, backgroundColor, ariaLabel, role };
const entry: IStatusbarEntry = { name, text, tooltip, command, color, backgroundColor, ariaLabel, role };
if (typeof priority === 'undefined') {
priority = 0;
}
// Reset existing entry if alignment or priority changed
let existingEntry = this.entries.get(id);
let existingEntry = this.entries.get(entryId);
if (existingEntry && (existingEntry.alignment !== alignment || existingEntry.priority !== priority)) {
dispose(existingEntry.accessor);
this.entries.delete(id);
this.entries.delete(entryId);
existingEntry = undefined;
}
// Create new entry if not existing
if (!existingEntry) {
this.entries.set(id, { accessor: this.statusbarService.addEntry(entry, statusId, statusName, alignment, priority), alignment, priority });
this.entries.set(entryId, { accessor: this.statusbarService.addEntry(entry, id, alignment, priority), alignment, priority });
}
// Otherwise update

View File

@@ -10,13 +10,13 @@ import { URI } from 'vs/base/common/uri';
import { StopWatch } from 'vs/base/common/stopwatch';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ILogService } from 'vs/platform/log/common/log';
import { IShellLaunchConfig, IShellLaunchConfigDto, ITerminalDimensions } from 'vs/platform/terminal/common/terminal';
import { IShellLaunchConfig, IShellLaunchConfigDto, ITerminalDimensions, TitleEventSource } from 'vs/platform/terminal/common/terminal';
import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering';
import { ITerminalExternalLinkProvider, ITerminalInstance, ITerminalInstanceService, ITerminalLink, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { TerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/browser/terminalProcessExtHostProxy';
import { IEnvironmentVariableService, ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable';
import { deserializeEnvironmentVariableCollection, serializeEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableShared';
import { IStartExtensionTerminalRequest, ITerminalProcessExtHostProxy, ITerminalProfileResolverService, TitleEventSource } from 'vs/workbench/contrib/terminal/common/terminal';
import { IStartExtensionTerminalRequest, ITerminalProcessExtHostProxy, ITerminalProfileResolverService } from 'vs/workbench/contrib/terminal/common/terminal';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { withNullAsUndefined } from 'vs/base/common/types';
import { OperatingSystem, OS } from 'vs/base/common/platform';

View File

@@ -60,8 +60,7 @@ export class MainThreadWindow implements MainThreadWindowShape {
}
async $asExternalUri(uriComponents: UriComponents, options: IOpenUriOptions): Promise<UriComponents> {
const uri = URI.revive(uriComponents);
const result = await this.openerService.resolveExternalUri(uri, options);
const result = await this.openerService.resolveExternalUri(URI.revive(uriComponents), options);
return result.resolved;
}
}