mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-26 01:25:38 -05:00
Merge from vscode 2cd495805cf99b31b6926f08ff4348124b2cf73d
This commit is contained in:
committed by
AzureDataStudio
parent
a8a7559229
commit
1388493cc1
@@ -18,7 +18,7 @@ import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common
|
||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||
import { fromNow } from 'vs/base/common/date';
|
||||
|
||||
const VSO_ALLOWED_EXTENSIONS = ['github.vscode-pull-request-github', 'github.vscode-pull-request-github-insiders', 'vscode.git', 'ms-vsonline.vsonline'];
|
||||
const VSO_ALLOWED_EXTENSIONS = ['github.vscode-pull-request-github', 'github.vscode-pull-request-github-insiders', 'vscode.git', 'ms-vsonline.vsonline', 'vscode.github-browser'];
|
||||
|
||||
interface IAccountUsage {
|
||||
extensionId: string;
|
||||
@@ -104,7 +104,7 @@ export class MainThreadAuthenticationProvider extends Disposable {
|
||||
return {
|
||||
label: extension.name,
|
||||
description: usage
|
||||
? nls.localize('accountLastUsedDate', "Last used this account {0}", fromNow(usage.lastUsed, true))
|
||||
? nls.localize({ key: 'accountLastUsedDate', comment: ['The placeholder {0} is a string with time information, such as "3 days ago"'] }, "Last used this account {0}", fromNow(usage.lastUsed, true))
|
||||
: nls.localize('notUsed', "Has not used this account"),
|
||||
extension
|
||||
};
|
||||
@@ -336,7 +336,14 @@ export class MainThreadAuthentication extends Disposable implements MainThreadAu
|
||||
});
|
||||
|
||||
quickPick.items = items;
|
||||
quickPick.title = nls.localize('selectAccount', "The extension '{0}' wants to access a {1} account", extensionName, providerName);
|
||||
quickPick.title = nls.localize(
|
||||
{
|
||||
key: 'selectAccount',
|
||||
comment: ['The placeholder {0} is the name of an extension. {1} is the name of the type of account, such as Microsoft or GitHub.']
|
||||
},
|
||||
"The extension '{0}' wants to access a {1} account",
|
||||
extensionName,
|
||||
providerName);
|
||||
quickPick.placeholder = nls.localize('getSessionPlateholder', "Select an account for '{0}' to use or Esc to cancel", extensionName);
|
||||
|
||||
quickPick.onDidAccept(async _ => {
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable, DisposableStore, dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { keys } from 'vs/base/common/map';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
@@ -284,7 +283,7 @@ export class MainThreadCommentController {
|
||||
|
||||
async getDocumentComments(resource: URI, token: CancellationToken) {
|
||||
let ret: modes.CommentThread[] = [];
|
||||
for (let thread of keys(this._threads)) {
|
||||
for (let thread of [...this._threads.keys()]) {
|
||||
const commentThread = this._threads.get(thread)!;
|
||||
if (commentThread.resource === resource.toString()) {
|
||||
ret.push(commentThread);
|
||||
@@ -315,7 +314,7 @@ export class MainThreadCommentController {
|
||||
|
||||
getAllComments(): MainThreadCommentThread[] {
|
||||
let ret: MainThreadCommentThread[] = [];
|
||||
for (let thread of keys(this._threads)) {
|
||||
for (let thread of [...this._threads.keys()]) {
|
||||
ret.push(this._threads.get(thread)!);
|
||||
}
|
||||
|
||||
@@ -486,7 +485,7 @@ export class MainThreadComments extends Disposable implements MainThreadComments
|
||||
if (!commentsPanelAlreadyConstructed && !this._openViewListener) {
|
||||
this._openViewListener = this._viewsService.onDidChangeViewVisibility(e => {
|
||||
if (e.id === COMMENTS_VIEW_ID && e.visible) {
|
||||
keys(this._commentControllers).forEach(handle => {
|
||||
[...this._commentControllers.keys()].forEach(handle => {
|
||||
let threads = this._commentControllers.get(handle)!.getAllComments();
|
||||
|
||||
if (threads.length) {
|
||||
|
||||
@@ -231,7 +231,8 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape, IDeb
|
||||
const debugOptions: IDebugSessionOptions = {
|
||||
noDebug: options.noDebug,
|
||||
parentSession: this.getSession(options.parentSessionID),
|
||||
repl: options.repl
|
||||
repl: options.repl,
|
||||
noCompact: options.noCompact
|
||||
};
|
||||
return this.debugService.startDebugging(launch, nameOrConfig, debugOptions).then(success => {
|
||||
return success;
|
||||
|
||||
@@ -9,33 +9,33 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { ExtHostContext, MainContext, IExtHostContext, MainThreadDecorationsShape, ExtHostDecorationsShape, DecorationData, DecorationRequest } from '../common/extHost.protocol';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { IDecorationsService, IDecorationData } from 'vs/workbench/services/decorations/browser/decorations';
|
||||
import { values } from 'vs/base/common/collections';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
|
||||
class DecorationRequestsQueue {
|
||||
|
||||
private _idPool = 0;
|
||||
private _requests: { [id: number]: DecorationRequest } = Object.create(null);
|
||||
private _resolver: { [id: number]: (data: DecorationData) => any } = Object.create(null);
|
||||
private _requests = new Map<number, DecorationRequest>();
|
||||
private _resolver = new Map<number, (data: DecorationData) => any>();
|
||||
|
||||
private _timer: any;
|
||||
|
||||
constructor(
|
||||
private readonly _proxy: ExtHostDecorationsShape
|
||||
private readonly _proxy: ExtHostDecorationsShape,
|
||||
private readonly _handle: number
|
||||
) {
|
||||
//
|
||||
}
|
||||
|
||||
enqueue(handle: number, uri: URI, token: CancellationToken): Promise<DecorationData> {
|
||||
enqueue(uri: URI, token: CancellationToken): Promise<DecorationData> {
|
||||
const id = ++this._idPool;
|
||||
const result = new Promise<DecorationData>(resolve => {
|
||||
this._requests[id] = { id, handle, uri };
|
||||
this._resolver[id] = resolve;
|
||||
this._requests.set(id, { id, uri });
|
||||
this._resolver.set(id, resolve);
|
||||
this._processQueue();
|
||||
});
|
||||
token.onCancellationRequested(() => {
|
||||
delete this._requests[id];
|
||||
delete this._resolver[id];
|
||||
this._requests.delete(id);
|
||||
this._resolver.delete(id);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
@@ -49,15 +49,15 @@ class DecorationRequestsQueue {
|
||||
// make request
|
||||
const requests = this._requests;
|
||||
const resolver = this._resolver;
|
||||
this._proxy.$provideDecorations(values(requests), CancellationToken.None).then(data => {
|
||||
for (const id in resolver) {
|
||||
resolver[id](data[id]);
|
||||
this._proxy.$provideDecorations(this._handle, [...requests.values()], CancellationToken.None).then(data => {
|
||||
for (let [id, resolve] of resolver) {
|
||||
resolve(data[id]);
|
||||
}
|
||||
});
|
||||
|
||||
// reset
|
||||
this._requests = [];
|
||||
this._resolver = [];
|
||||
this._requests = new Map();
|
||||
this._resolver = new Map();
|
||||
this._timer = undefined;
|
||||
}, 0);
|
||||
}
|
||||
@@ -68,14 +68,12 @@ export class MainThreadDecorations implements MainThreadDecorationsShape {
|
||||
|
||||
private readonly _provider = new Map<number, [Emitter<URI[]>, IDisposable]>();
|
||||
private readonly _proxy: ExtHostDecorationsShape;
|
||||
private readonly _requestQueue: DecorationRequestsQueue;
|
||||
|
||||
constructor(
|
||||
context: IExtHostContext,
|
||||
@IDecorationsService private readonly _decorationsService: IDecorationsService
|
||||
) {
|
||||
this._proxy = context.getProxy(ExtHostContext.ExtHostDecorations);
|
||||
this._requestQueue = new DecorationRequestsQueue(this._proxy);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
@@ -85,23 +83,23 @@ export class MainThreadDecorations implements MainThreadDecorationsShape {
|
||||
|
||||
$registerDecorationProvider(handle: number, label: string): void {
|
||||
const emitter = new Emitter<URI[]>();
|
||||
const queue = new DecorationRequestsQueue(this._proxy, handle);
|
||||
const registration = this._decorationsService.registerDecorationsProvider({
|
||||
label,
|
||||
onDidChange: emitter.event,
|
||||
provideDecorations: (uri, token) => {
|
||||
return this._requestQueue.enqueue(handle, uri, token).then(data => {
|
||||
if (!data) {
|
||||
return undefined;
|
||||
}
|
||||
const [weight, bubble, tooltip, letter, themeColor] = data;
|
||||
return <IDecorationData>{
|
||||
weight: weight || 0,
|
||||
bubble: bubble || false,
|
||||
color: themeColor && themeColor.id,
|
||||
tooltip,
|
||||
letter
|
||||
};
|
||||
});
|
||||
provideDecorations: async (uri, token) => {
|
||||
const data = await queue.enqueue(uri, token);
|
||||
if (!data) {
|
||||
return undefined;
|
||||
}
|
||||
const [weight, bubble, tooltip, letter, themeColor] = data;
|
||||
return <IDecorationData>{
|
||||
weight: weight ?? 0,
|
||||
bubble: bubble ?? false,
|
||||
color: themeColor?.id,
|
||||
tooltip,
|
||||
letter
|
||||
};
|
||||
}
|
||||
});
|
||||
this._provider.set(handle, [emitter, registration]);
|
||||
|
||||
@@ -126,8 +126,12 @@ export class MainThreadDocuments implements MainThreadDocumentsShape {
|
||||
}));
|
||||
|
||||
this._toDispose.add(workingCopyFileService.onDidRunWorkingCopyFileOperation(e => {
|
||||
if (e.source && (e.operation === FileOperation.MOVE || e.operation === FileOperation.DELETE)) {
|
||||
this._modelReferenceCollection.remove(e.source);
|
||||
if (e.operation === FileOperation.MOVE || e.operation === FileOperation.DELETE) {
|
||||
for (const { source } of e.files) {
|
||||
if (source) {
|
||||
this._modelReferenceCollection.remove(source);
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
@@ -24,9 +24,9 @@ import { ExtHostContext, ExtHostEditorsShape, IApplyEditsOptions, IExtHostContex
|
||||
import { EditorViewColumn, editorGroupToViewColumn, viewColumnToEditorGroup } from 'vs/workbench/api/common/shared/editor';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { openEditorWith } from 'vs/workbench/contrib/files/common/openWith';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { openEditorWith } from 'vs/workbench/services/editor/common/editorOpenWith';
|
||||
|
||||
export class MainThreadTextEditors implements MainThreadTextEditorsShape {
|
||||
|
||||
|
||||
@@ -4,10 +4,9 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { FileChangeType, IFileService, FileOperation } from 'vs/platform/files/common/files';
|
||||
import { FileChangeType, IFileService } from 'vs/platform/files/common/files';
|
||||
import { extHostCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { ExtHostContext, FileSystemEvents, IExtHostContext } from '../common/extHost.protocol';
|
||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { localize } from 'vs/nls';
|
||||
import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
@@ -21,7 +20,6 @@ export class MainThreadFileSystemEventService {
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@IFileService fileService: IFileService,
|
||||
@ITextFileService textFileService: ITextFileService,
|
||||
@IWorkingCopyFileService workingCopyFileService: IWorkingCopyFileService
|
||||
) {
|
||||
|
||||
@@ -57,14 +55,13 @@ export class MainThreadFileSystemEventService {
|
||||
|
||||
// BEFORE file operation
|
||||
workingCopyFileService.addFileOperationParticipant({
|
||||
participate: (target, source, operation, progress, timeout, token) => {
|
||||
return proxy.$onWillRunFileOperation(operation, target, source, timeout, token);
|
||||
participate: (files, operation, progress, timeout, token) => {
|
||||
return proxy.$onWillRunFileOperation(operation, files, timeout, token);
|
||||
}
|
||||
});
|
||||
|
||||
// AFTER file operation
|
||||
this._listener.add(textFileService.onDidCreateTextFile(e => proxy.$onDidRunFileOperation(FileOperation.CREATE, e.resource, undefined)));
|
||||
this._listener.add(workingCopyFileService.onDidRunWorkingCopyFileOperation(e => proxy.$onDidRunFileOperation(e.operation, e.target, e.source)));
|
||||
this._listener.add(workingCopyFileService.onDidRunWorkingCopyFileOperation(e => proxy.$onDidRunFileOperation(e.operation, e.files)));
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { MainContext, MainThreadNotebookShape, NotebookExtensionDescription, IExtHostContext, ExtHostNotebookShape, ExtHostContext, INotebookDocumentsAndEditorsDelta, INotebookModelAddedData } from '../common/extHost.protocol';
|
||||
import { Disposable, IDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
|
||||
@@ -40,7 +41,7 @@ export class MainThreadNotebookDocument extends Disposable {
|
||||
) {
|
||||
super();
|
||||
|
||||
this._textModel = new NotebookTextModel(handle, viewType, supportBackup, uri);
|
||||
this._textModel = new NotebookTextModel(handle, viewType, supportBackup, uri, undoRedoService);
|
||||
this._register(this._textModel.onDidModelChangeProxy(e => {
|
||||
this._proxy.$acceptModelChanged(this.uri, e);
|
||||
this._proxy.$acceptEditorPropertiesChanged(uri, { selections: { selections: this._textModel.selections }, metadata: null });
|
||||
@@ -51,9 +52,18 @@ export class MainThreadNotebookDocument extends Disposable {
|
||||
}));
|
||||
}
|
||||
|
||||
async applyEdit(modelVersionId: number, edits: ICellEditOperation[], emitToExtHost: boolean): Promise<boolean> {
|
||||
async applyEdit(modelVersionId: number, edits: ICellEditOperation[], emitToExtHost: boolean, synchronous: boolean): Promise<boolean> {
|
||||
await this.notebookService.transformEditsOutputs(this.textModel, edits);
|
||||
return this._textModel.$applyEdit(modelVersionId, edits);
|
||||
if (synchronous) {
|
||||
return this._textModel.$applyEdit(modelVersionId, edits, emitToExtHost, synchronous);
|
||||
} else {
|
||||
return new Promise(resolve => {
|
||||
this._register(DOM.scheduleAtNextAnimationFrame(() => {
|
||||
const ret = this._textModel.$applyEdit(modelVersionId, edits, emitToExtHost, true);
|
||||
resolve(ret);
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async spliceNotebookCellOutputs(cellHandle: number, splices: NotebookCellOutputsSplice[]) {
|
||||
@@ -250,10 +260,10 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
|
||||
|
||||
private _emitDelta(delta: INotebookDocumentsAndEditorsDelta) {
|
||||
if (this._isDeltaEmpty(delta)) {
|
||||
return;
|
||||
return undefined; // {{SQL CARBON EDIT}} strict-null-checks
|
||||
}
|
||||
|
||||
this._proxy.$acceptDocumentAndEditorsDelta(delta);
|
||||
return this._proxy.$acceptDocumentAndEditorsDelta(delta);
|
||||
}
|
||||
|
||||
registerListeners() {
|
||||
@@ -476,16 +486,11 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
|
||||
return this._proxy.$executeNotebook(viewType, uri, undefined, useAttachedKernel, token);
|
||||
}
|
||||
|
||||
async $postMessage(handle: number, value: any): Promise<boolean> {
|
||||
|
||||
const activeEditorPane = this.editorService.activeEditorPane as any | undefined;
|
||||
if (activeEditorPane?.isNotebookEditor) {
|
||||
const notebookEditor = (activeEditorPane.getControl() as INotebookEditor);
|
||||
|
||||
if (notebookEditor.viewModel?.handle === handle) {
|
||||
notebookEditor.postMessage(value);
|
||||
return true;
|
||||
}
|
||||
async $postMessage(editorId: string, forRendererId: string | undefined, value: any): Promise<boolean> {
|
||||
const editor = this._notebookService.getNotebookEditor(editorId) as INotebookEditor | undefined;
|
||||
if (editor?.isNotebookEditor) {
|
||||
editor.postMessage(forRendererId, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -533,7 +538,7 @@ export class MainThreadNotebookController implements IMainNotebookController {
|
||||
await mainthreadNotebook.applyEdit(mainthreadNotebook.textModel.versionId, [
|
||||
{ editType: CellEditType.Delete, count: mainthreadNotebook.textModel.cells.length, index: 0 },
|
||||
{ editType: CellEditType.Insert, index: 0, cells: data.cells }
|
||||
], true);
|
||||
], true, false);
|
||||
}
|
||||
return mainthreadNotebook.textModel;
|
||||
}
|
||||
@@ -553,7 +558,7 @@ export class MainThreadNotebookController implements IMainNotebookController {
|
||||
index: 0,
|
||||
cells: backup.cells || []
|
||||
}
|
||||
], false);
|
||||
], false, true);
|
||||
|
||||
// create document in ext host with cells data
|
||||
await this._mainThreadNotebook.addNotebookDocument({
|
||||
@@ -630,7 +635,7 @@ export class MainThreadNotebookController implements IMainNotebookController {
|
||||
let mainthreadNotebook = this._mapping.get(URI.from(resource).toString());
|
||||
|
||||
if (mainthreadNotebook) {
|
||||
return await mainthreadNotebook.applyEdit(modelVersionId, edits, true);
|
||||
return await mainthreadNotebook.applyEdit(modelVersionId, edits, true, true);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -645,8 +650,8 @@ export class MainThreadNotebookController implements IMainNotebookController {
|
||||
return this._mainThreadNotebook.executeNotebook(viewType, uri, useAttachedKernel, token);
|
||||
}
|
||||
|
||||
onDidReceiveMessage(editorId: string, message: any): void {
|
||||
this._proxy.$onDidReceiveMessage(editorId, message);
|
||||
onDidReceiveMessage(editorId: string, rendererType: string | undefined, message: unknown): void {
|
||||
this._proxy.$onDidReceiveMessage(editorId, rendererType, message);
|
||||
}
|
||||
|
||||
async removeNotebookDocument(notebook: INotebookTextModel): Promise<void> {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IDisposable, DisposableStore, combinedDisposable } from 'vs/base/common/lifecycle';
|
||||
import { ISCMService, ISCMRepository, ISCMProvider, ISCMResource, ISCMResourceGroup, ISCMResourceDecorations, IInputValidation } from 'vs/workbench/contrib/scm/common/scm';
|
||||
import { ExtHostContext, MainThreadSCMShape, ExtHostSCMShape, SCMProviderFeatures, SCMRawResourceSplices, SCMGroupFeatures, MainContext, IExtHostContext } from '../common/extHost.protocol';
|
||||
import { Command } from 'vs/editor/common/modes';
|
||||
@@ -264,7 +264,7 @@ export class MainThreadSCM implements MainThreadSCMShape {
|
||||
|
||||
private readonly _proxy: ExtHostSCMShape;
|
||||
private _repositories = new Map<number, ISCMRepository>();
|
||||
private _inputDisposables = new Map<number, IDisposable>();
|
||||
private _repositoryDisposables = new Map<number, IDisposable>();
|
||||
private readonly _disposables = new DisposableStore();
|
||||
|
||||
constructor(
|
||||
@@ -272,17 +272,14 @@ export class MainThreadSCM implements MainThreadSCMShape {
|
||||
@ISCMService private readonly scmService: ISCMService
|
||||
) {
|
||||
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostSCM);
|
||||
|
||||
Event.debounce(scmService.onDidChangeSelectedRepositories, (_, e) => e, 100)
|
||||
(this.onDidChangeSelectedRepositories, this, this._disposables);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._repositories.forEach(r => r.dispose());
|
||||
this._repositories.clear();
|
||||
|
||||
this._inputDisposables.forEach(d => d.dispose());
|
||||
this._inputDisposables.clear();
|
||||
this._repositoryDisposables.forEach(d => d.dispose());
|
||||
this._repositoryDisposables.clear();
|
||||
|
||||
this._disposables.dispose();
|
||||
}
|
||||
@@ -292,8 +289,16 @@ export class MainThreadSCM implements MainThreadSCMShape {
|
||||
const repository = this.scmService.registerSCMProvider(provider);
|
||||
this._repositories.set(handle, repository);
|
||||
|
||||
const inputDisposable = repository.input.onDidChange(value => this._proxy.$onInputBoxValueChange(handle, value));
|
||||
this._inputDisposables.set(handle, inputDisposable);
|
||||
const disposable = combinedDisposable(
|
||||
Event.filter(repository.onDidChangeSelection, selected => selected)(_ => this._proxy.$setSelectedSourceControl(handle)),
|
||||
repository.input.onDidChange(value => this._proxy.$onInputBoxValueChange(handle, value))
|
||||
);
|
||||
|
||||
if (repository.selected) {
|
||||
setTimeout(() => this._proxy.$setSelectedSourceControl(handle), 0);
|
||||
}
|
||||
|
||||
this._repositoryDisposables.set(handle, disposable);
|
||||
}
|
||||
|
||||
$updateSourceControl(handle: number, features: SCMProviderFeatures): void {
|
||||
@@ -314,8 +319,8 @@ export class MainThreadSCM implements MainThreadSCMShape {
|
||||
return;
|
||||
}
|
||||
|
||||
this._inputDisposables.get(handle)!.dispose();
|
||||
this._inputDisposables.delete(handle);
|
||||
this._repositoryDisposables.get(handle)!.dispose();
|
||||
this._repositoryDisposables.delete(handle);
|
||||
|
||||
repository.dispose();
|
||||
this._repositories.delete(handle);
|
||||
@@ -422,12 +427,4 @@ export class MainThreadSCM implements MainThreadSCMShape {
|
||||
repository.input.validateInput = async () => undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private onDidChangeSelectedRepositories(repositories: ISCMRepository[]): void {
|
||||
const handles = repositories
|
||||
.filter(r => r.provider instanceof MainThreadSCMProvider)
|
||||
.map(r => (r.provider as MainThreadSCMProvider).handle);
|
||||
|
||||
this._proxy.$setSelectedSourceControls(handles);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import { IAccessibilityInformation } from 'vs/platform/accessibility/common/acce
|
||||
export class MainThreadStatusBar implements MainThreadStatusBarShape {
|
||||
|
||||
private readonly entries: Map<number, { accessor: IStatusbarEntryAccessor, alignment: MainThreadStatusBarAlignment, priority: number }> = new Map();
|
||||
static readonly CODICON_REGEXP = /\$\((.*?)\)/g;
|
||||
|
||||
constructor(
|
||||
_extHostContext: IExtHostContext,
|
||||
@@ -32,7 +33,7 @@ export class MainThreadStatusBar implements MainThreadStatusBarShape {
|
||||
if (accessibilityInformation) {
|
||||
ariaLabel = accessibilityInformation.label;
|
||||
} else {
|
||||
ariaLabel = text && text.indexOf('$(') === -1 ? text : tooltip || text;
|
||||
ariaLabel = text ? text.replace(MainThreadStatusBar.CODICON_REGEXP, (_match, codiconName) => codiconName) : '';
|
||||
}
|
||||
const entry: IStatusbarEntry = { text, tooltip, command, color, ariaLabel };
|
||||
|
||||
|
||||
@@ -328,10 +328,10 @@ namespace TaskDTO {
|
||||
result.detail = task.configurationProperties.detail;
|
||||
}
|
||||
if (!ConfiguringTask.is(task) && task.command) {
|
||||
if (task.command.runtime === RuntimeType.Process) {
|
||||
result.execution = ProcessExecutionDTO.from(task.command);
|
||||
} else if (task.command.runtime === RuntimeType.Shell) {
|
||||
result.execution = ShellExecutionDTO.from(task.command);
|
||||
switch (task.command.runtime) {
|
||||
case RuntimeType.Process: result.execution = ProcessExecutionDTO.from(task.command); break;
|
||||
case RuntimeType.Shell: result.execution = ShellExecutionDTO.from(task.command); break;
|
||||
case RuntimeType.CustomExecution: result.execution = CustomExecutionDTO.from(task.command); break;
|
||||
}
|
||||
}
|
||||
if (task.configurationProperties.problemMatchers) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import { ExtHostContext, ExtHostTerminalServiceShape, MainThreadTerminalServiceS
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { StopWatch } from 'vs/base/common/stopwatch';
|
||||
import { ITerminalInstanceService, ITerminalService, ITerminalInstance, ITerminalBeforeHandleLinkEvent } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { ITerminalInstanceService, ITerminalService, ITerminalInstance, ITerminalBeforeHandleLinkEvent, ITerminalExternalLinkProvider, ITerminalLink } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { TerminalDataBufferer } from 'vs/workbench/contrib/terminal/common/terminalDataBuffering';
|
||||
@@ -25,6 +25,13 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
|
||||
private readonly _terminalProcessProxies = new Map<number, ITerminalProcessExtHostProxy>();
|
||||
private _dataEventTracker: TerminalDataEventTracker | undefined;
|
||||
private _linkHandler: IDisposable | undefined;
|
||||
/**
|
||||
* A single shared terminal link provider for the exthost. When an ext registers a link
|
||||
* provider, this is registered with the terminal on the renderer side and all links are
|
||||
* provided through this, even from multiple ext link providers. Xterm should remove lower
|
||||
* priority intersecting links itself.
|
||||
*/
|
||||
private _linkProvider: IDisposable | undefined;
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@@ -81,11 +88,13 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
|
||||
this._proxy.$initEnvironmentVariableCollections(serializedCollections);
|
||||
}
|
||||
|
||||
this._terminalService.extHostReady(extHostContext.remoteAuthority);
|
||||
this._terminalService.extHostReady(extHostContext.remoteAuthority!); // TODO@Tyriar: remove null assertion
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._toDispose.dispose();
|
||||
this._linkHandler?.dispose();
|
||||
this._linkProvider?.dispose();
|
||||
|
||||
// TODO@Daniel: Should all the previously created terminals be disposed
|
||||
// when the extension host process goes down ?
|
||||
@@ -162,6 +171,17 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
|
||||
|
||||
public $stopHandlingLinks(): void {
|
||||
this._linkHandler?.dispose();
|
||||
this._linkHandler = undefined;
|
||||
}
|
||||
|
||||
public $startLinkProvider(): void {
|
||||
this._linkProvider?.dispose();
|
||||
this._linkProvider = this._terminalService.registerLinkProvider(new ExtensionTerminalLinkProvider(this._proxy));
|
||||
}
|
||||
|
||||
public $stopLinkProvider(): void {
|
||||
this._linkProvider?.dispose();
|
||||
this._linkProvider = undefined;
|
||||
}
|
||||
|
||||
private async _handleLink(e: ITerminalBeforeHandleLinkEvent): Promise<boolean> {
|
||||
@@ -395,3 +415,22 @@ class TerminalDataEventTracker extends Disposable {
|
||||
this._register(this._bufferer.startBuffering(instance.id, instance.onData));
|
||||
}
|
||||
}
|
||||
|
||||
class ExtensionTerminalLinkProvider implements ITerminalExternalLinkProvider {
|
||||
constructor(
|
||||
private readonly _proxy: ExtHostTerminalServiceShape
|
||||
) {
|
||||
}
|
||||
|
||||
async provideLinks(instance: ITerminalInstance, line: string): Promise<ITerminalLink[] | undefined> {
|
||||
const proxy = this._proxy;
|
||||
const extHostLinks = await proxy.$provideLinks(instance.id, line);
|
||||
return extHostLinks.map(dto => ({
|
||||
id: dto.id,
|
||||
startIndex: dto.startIndex,
|
||||
length: dto.length,
|
||||
label: dto.label,
|
||||
activate: () => proxy.$activateLink(instance.id, dto.id)
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { ExtHostContext, MainThreadTreeViewsShape, ExtHostTreeViewsShape, MainContext, IExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { ITreeViewDataProvider, ITreeItem, IViewsService, ITreeView, IViewsRegistry, ITreeViewDescriptor, IRevealOptions, Extensions } from 'vs/workbench/common/views';
|
||||
import { ITreeViewDataProvider, ITreeItem, IViewsService, ITreeView, IViewsRegistry, ITreeViewDescriptor, IRevealOptions, Extensions, ResolvableTreeItem } from 'vs/workbench/common/views';
|
||||
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
|
||||
import { distinct } from 'vs/base/common/arrays';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
@@ -165,12 +165,14 @@ export type TreeItemHandle = string;
|
||||
export class TreeViewDataProvider implements ITreeViewDataProvider {
|
||||
|
||||
private readonly itemsMap: Map<TreeItemHandle, ITreeItem> = new Map<TreeItemHandle, ITreeItem>();
|
||||
private hasResolve: Promise<boolean>;
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
constructor(protected readonly treeViewId: string,
|
||||
protected readonly _proxy: ExtHostTreeViewsShape,
|
||||
private readonly notificationService: INotificationService
|
||||
) {
|
||||
this.hasResolve = this._proxy.$hasResolve(this.treeViewId);
|
||||
}
|
||||
|
||||
getChildren(treeItem?: ITreeItem): Promise<ITreeItem[]> {
|
||||
@@ -217,12 +219,16 @@ export class TreeViewDataProvider implements ITreeViewDataProvider {
|
||||
return this.itemsMap.size === 0;
|
||||
}
|
||||
|
||||
private postGetChildren(elements: ITreeItem[]): ITreeItem[] {
|
||||
const result: ITreeItem[] = [];
|
||||
private async postGetChildren(elements: ITreeItem[]): Promise<ResolvableTreeItem[]> {
|
||||
const result: ResolvableTreeItem[] = [];
|
||||
const hasResolve = await this.hasResolve;
|
||||
if (elements) {
|
||||
for (const element of elements) {
|
||||
const resolvable = new ResolvableTreeItem(element, hasResolve ? () => {
|
||||
return this._proxy.$resolve(this.treeViewId, element.handle);
|
||||
} : undefined);
|
||||
this.itemsMap.set(element.handle, element);
|
||||
result.push(element);
|
||||
result.push(resolvable);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -141,7 +141,7 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
|
||||
|
||||
this._register(_editorService.onDidActiveEditorChange(() => {
|
||||
const activeInput = this._editorService.activeEditor;
|
||||
if (activeInput instanceof DiffEditorInput && activeInput.master instanceof WebviewInput && activeInput.details instanceof WebviewInput) {
|
||||
if (activeInput instanceof DiffEditorInput && activeInput.primary instanceof WebviewInput && activeInput.secondary instanceof WebviewInput) {
|
||||
this.registerWebviewFromDiffEditorListeners(activeInput);
|
||||
}
|
||||
|
||||
@@ -185,6 +185,15 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
|
||||
});
|
||||
}
|
||||
|
||||
dispose() {
|
||||
super.dispose();
|
||||
|
||||
for (const disposable of this._editorProviders.values()) {
|
||||
disposable.dispose();
|
||||
}
|
||||
this._editorProviders.clear();
|
||||
}
|
||||
|
||||
public $createWebviewPanel(
|
||||
extensionData: extHostProtocol.WebviewExtensionDescription,
|
||||
handle: extHostProtocol.WebviewPanelHandle,
|
||||
@@ -320,7 +329,7 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
|
||||
options: modes.IWebviewPanelOptions,
|
||||
capabilities: extHostProtocol.CustomTextEditorCapabilities,
|
||||
supportsMultipleEditorsPerDocument: boolean,
|
||||
): DisposableStore {
|
||||
): void {
|
||||
if (this._editorProviders.has(viewType)) {
|
||||
throw new Error(`Provider for ${viewType} already registered`);
|
||||
}
|
||||
@@ -396,8 +405,6 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
|
||||
}));
|
||||
|
||||
this._editorProviders.set(viewType, disposables);
|
||||
|
||||
return disposables;
|
||||
}
|
||||
|
||||
public $unregisterEditorProvider(viewType: string): void {
|
||||
@@ -468,22 +475,22 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
|
||||
}
|
||||
|
||||
private registerWebviewFromDiffEditorListeners(diffEditorInput: DiffEditorInput): void {
|
||||
const master = diffEditorInput.master as WebviewInput;
|
||||
const details = diffEditorInput.details as WebviewInput;
|
||||
const primary = diffEditorInput.primary as WebviewInput;
|
||||
const secondary = diffEditorInput.secondary as WebviewInput;
|
||||
|
||||
if (this._webviewFromDiffEditorHandles.has(master.id) || this._webviewFromDiffEditorHandles.has(details.id)) {
|
||||
if (this._webviewFromDiffEditorHandles.has(primary.id) || this._webviewFromDiffEditorHandles.has(secondary.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._webviewFromDiffEditorHandles.add(master.id);
|
||||
this._webviewFromDiffEditorHandles.add(details.id);
|
||||
this._webviewFromDiffEditorHandles.add(primary.id);
|
||||
this._webviewFromDiffEditorHandles.add(secondary.id);
|
||||
|
||||
const disposables = new DisposableStore();
|
||||
disposables.add(master.webview.onDidFocus(() => this.updateWebviewViewStates(master)));
|
||||
disposables.add(details.webview.onDidFocus(() => this.updateWebviewViewStates(details)));
|
||||
disposables.add(primary.webview.onDidFocus(() => this.updateWebviewViewStates(primary)));
|
||||
disposables.add(secondary.webview.onDidFocus(() => this.updateWebviewViewStates(secondary)));
|
||||
disposables.add(diffEditorInput.onDispose(() => {
|
||||
this._webviewFromDiffEditorHandles.delete(master.id);
|
||||
this._webviewFromDiffEditorHandles.delete(details.id);
|
||||
this._webviewFromDiffEditorHandles.delete(primary.id);
|
||||
this._webviewFromDiffEditorHandles.delete(secondary.id);
|
||||
dispose(disposables);
|
||||
}));
|
||||
}
|
||||
@@ -515,8 +522,8 @@ export class MainThreadWebviews extends Disposable implements extHostProtocol.Ma
|
||||
for (const group of this._editorGroupService.groups) {
|
||||
for (const input of group.editors) {
|
||||
if (input instanceof DiffEditorInput) {
|
||||
updateViewStatesForInput(group, input, input.master);
|
||||
updateViewStatesForInput(group, input, input.details);
|
||||
updateViewStatesForInput(group, input, input.primary);
|
||||
updateViewStatesForInput(group, input, input.secondary);
|
||||
} else {
|
||||
updateViewStatesForInput(group, input, input);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { IJSONSchema } from 'vs/base/common/jsonSchema';
|
||||
import * as resources from 'vs/base/common/resources';
|
||||
import { ExtensionMessageCollector, ExtensionsRegistry, IExtensionPoint, IExtensionPointUser } from 'vs/workbench/services/extensions/common/extensionsRegistry';
|
||||
import { ViewContainer, IViewsRegistry, ITreeViewDescriptor, IViewContainersRegistry, Extensions as ViewContainerExtensions, TEST_VIEW_CONTAINER_ID, IViewDescriptor, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
import { TreeViewPane, CustomTreeView } from 'vs/workbench/browser/parts/views/treeView';
|
||||
import { TreeViewPane } from 'vs/workbench/browser/parts/views/treeView';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { coalesce, } from 'vs/base/common/arrays';
|
||||
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
@@ -32,6 +32,7 @@ import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||
import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { CustomTreeView } from 'vs/workbench/contrib/views/browser/treeView';
|
||||
|
||||
export interface IUserFriendlyViewsContainerDescriptor {
|
||||
id: string;
|
||||
|
||||
@@ -46,7 +46,7 @@ import * as typeConverters from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
|
||||
import { ExtHostUrls } from 'vs/workbench/api/common/extHostUrls';
|
||||
import { ExtHostWebviews } from 'vs/workbench/api/common/extHostWebview';
|
||||
import { ExtHostWindow } from 'vs/workbench/api/common/extHostWindow';
|
||||
import { IExtHostWindow } from 'vs/workbench/api/common/extHostWindow';
|
||||
import { IExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
|
||||
import { throwProposedApiError, checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { ProxyIdentifier } from 'vs/workbench/services/extensions/common/proxyIdentifier';
|
||||
@@ -98,6 +98,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
const extHostLogService = accessor.get(ILogService);
|
||||
const extHostTunnelService = accessor.get(IExtHostTunnelService);
|
||||
const extHostApiDeprecation = accessor.get(IExtHostApiDeprecationService);
|
||||
const extHostWindow = accessor.get(IExtHostWindow);
|
||||
|
||||
// register addressable instances
|
||||
rpcProtocol.set(ExtHostContext.ExtHostLogService, <ExtHostLogServiceShape><any>extHostLogService);
|
||||
@@ -106,6 +107,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
rpcProtocol.set(ExtHostContext.ExtHostExtensionService, extensionService);
|
||||
rpcProtocol.set(ExtHostContext.ExtHostStorage, extHostStorage);
|
||||
rpcProtocol.set(ExtHostContext.ExtHostTunnelService, extHostTunnelService);
|
||||
rpcProtocol.set(ExtHostContext.ExtHostWindow, extHostWindow);
|
||||
|
||||
// automatically create and register addressable instances
|
||||
const extHostDecorations = rpcProtocol.set(ExtHostContext.ExtHostDecorations, accessor.get(IExtHostDecorations));
|
||||
@@ -132,10 +134,9 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
const extHostQuickOpen = rpcProtocol.set(ExtHostContext.ExtHostQuickOpen, new ExtHostQuickOpen(rpcProtocol, extHostWorkspace, extHostCommands));
|
||||
const extHostSCM = rpcProtocol.set(ExtHostContext.ExtHostSCM, new ExtHostSCM(rpcProtocol, extHostCommands, extHostLogService));
|
||||
const extHostComment = rpcProtocol.set(ExtHostContext.ExtHostComments, new ExtHostComments(rpcProtocol, extHostCommands, extHostDocuments));
|
||||
const extHostWindow = rpcProtocol.set(ExtHostContext.ExtHostWindow, new ExtHostWindow(rpcProtocol));
|
||||
const extHostProgress = rpcProtocol.set(ExtHostContext.ExtHostProgress, new ExtHostProgress(rpcProtocol.getProxy(MainContext.MainThreadProgress)));
|
||||
const extHostLabelService = rpcProtocol.set(ExtHostContext.ExtHosLabelService, new ExtHostLabelService(rpcProtocol));
|
||||
const extHostNotebook = rpcProtocol.set(ExtHostContext.ExtHostNotebook, new ExtHostNotebookController(rpcProtocol, extHostCommands, extHostDocumentsAndEditors, initData.environment, extensionStoragePaths));
|
||||
const extHostNotebook = rpcProtocol.set(ExtHostContext.ExtHostNotebook, initData.uiKind === UIKind.Web ? new ExtHostNotebookController(rpcProtocol, extHostCommands, extHostDocumentsAndEditors, initData.environment) : new ExtHostNotebookController(rpcProtocol, extHostCommands, extHostDocumentsAndEditors, initData.environment, extensionStoragePaths));
|
||||
const extHostTheming = rpcProtocol.set(ExtHostContext.ExtHostTheming, new ExtHostTheming(rpcProtocol));
|
||||
const extHostAuthentication = rpcProtocol.set(ExtHostContext.ExtHostAuthentication, new ExtHostAuthentication(rpcProtocol));
|
||||
const extHostTimeline = rpcProtocol.set(ExtHostContext.ExtHostTimeline, new ExtHostTimeline(rpcProtocol, extHostCommands));
|
||||
@@ -208,12 +209,6 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
getSession(providerId: string, scopes: string[], options: vscode.AuthenticationGetSessionOptions) {
|
||||
return extHostAuthentication.getSession(extension, providerId, scopes, options as any);
|
||||
},
|
||||
getSessions(providerId: string, scopes: string[]): Thenable<readonly vscode.AuthenticationSession[]> {
|
||||
return extHostAuthentication.getSessions(extension, providerId, scopes);
|
||||
},
|
||||
login(providerId: string, scopes: string[]): Thenable<vscode.AuthenticationSession> {
|
||||
return extHostAuthentication.login(extension, providerId, scopes);
|
||||
},
|
||||
logout(providerId: string, sessionId: string): Thenable<void> {
|
||||
return extHostAuthentication.logout(providerId, sessionId);
|
||||
},
|
||||
@@ -589,6 +584,10 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostTerminalService.registerLinkHandler(handler);
|
||||
},
|
||||
registerTerminalLinkProvider(handler: vscode.TerminalLinkProvider): vscode.Disposable {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostTerminalService.registerLinkProvider(handler);
|
||||
},
|
||||
registerTreeDataProvider(viewId: string, treeDataProvider: vscode.TreeDataProvider<any>): vscode.Disposable {
|
||||
return extHostTreeViews.registerTreeDataProvider(viewId, treeDataProvider, extension);
|
||||
},
|
||||
@@ -1119,7 +1118,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
CellKind: extHostTypes.CellKind,
|
||||
CellOutputKind: extHostTypes.CellOutputKind,
|
||||
NotebookCellRunState: extHostTypes.NotebookCellRunState,
|
||||
AuthenticationSession2: extHostTypes.AuthenticationSession
|
||||
AuthenticationSession: extHostTypes.AuthenticationSession
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ export interface IConfigurationInitData extends IConfigurationData {
|
||||
}
|
||||
|
||||
export interface IExtHostContext extends IRPCProtocol {
|
||||
remoteAuthority: string;
|
||||
remoteAuthority: string | null;
|
||||
}
|
||||
|
||||
export interface IMainContext extends IRPCProtocol {
|
||||
@@ -454,6 +454,8 @@ export interface MainThreadTerminalServiceShape extends IDisposable {
|
||||
$stopSendingDataEvents(): void;
|
||||
$startHandlingLinks(): void;
|
||||
$stopHandlingLinks(): void;
|
||||
$startLinkProvider(): void;
|
||||
$stopLinkProvider(): void;
|
||||
$setEnvironmentVariableCollection(extensionIdentifier: string, persistent: boolean, collection: ISerializableEnvironmentVariableCollection | undefined): void;
|
||||
|
||||
// Process
|
||||
@@ -713,7 +715,7 @@ export interface MainThreadNotebookShape extends IDisposable {
|
||||
$updateNotebookMetadata(viewType: string, resource: UriComponents, metadata: NotebookDocumentMetadata): Promise<void>;
|
||||
$updateNotebookCellMetadata(viewType: string, resource: UriComponents, handle: number, metadata: NotebookCellMetadata | undefined): Promise<void>;
|
||||
$spliceNotebookCellOutputs(viewType: string, resource: UriComponents, cellHandle: number, splices: NotebookCellOutputsSplice[], renderers: number[]): Promise<void>;
|
||||
$postMessage(handle: number, value: any): Promise<boolean>;
|
||||
$postMessage(editorId: string, forRendererId: string | undefined, value: any): Promise<boolean>;
|
||||
|
||||
$onDidEdit(resource: UriComponents, viewType: string, editId: number, label: string | undefined): void;
|
||||
$onContentChange(resource: UriComponents, viewType: string): void;
|
||||
@@ -860,6 +862,7 @@ export interface IStartDebuggingOptions {
|
||||
parentSessionID?: DebugSessionUUID;
|
||||
repl?: IDebugSessionReplMode;
|
||||
noDebug?: boolean;
|
||||
noCompact?: boolean;
|
||||
}
|
||||
|
||||
export interface MainThreadDebugServiceShape extends IDisposable {
|
||||
@@ -990,6 +993,8 @@ export interface ExtHostTreeViewsShape {
|
||||
$setExpanded(treeViewId: string, treeItemHandle: string, expanded: boolean): void;
|
||||
$setSelection(treeViewId: string, treeItemHandles: string[]): void;
|
||||
$setVisible(treeViewId: string, visible: boolean): void;
|
||||
$hasResolve(treeViewId: string): Promise<boolean>;
|
||||
$resolve(treeViewId: string, treeItemHandle: string): Promise<ITreeItem | undefined>;
|
||||
}
|
||||
|
||||
export interface ExtHostWorkspaceShape {
|
||||
@@ -1071,10 +1076,15 @@ export interface FileSystemEvents {
|
||||
deleted: UriComponents[];
|
||||
}
|
||||
|
||||
export interface SourceTargetPair {
|
||||
source?: UriComponents;
|
||||
target: UriComponents;
|
||||
}
|
||||
|
||||
export interface ExtHostFileSystemEventServiceShape {
|
||||
$onFileEvent(events: FileSystemEvents): void;
|
||||
$onWillRunFileOperation(operation: files.FileOperation, target: UriComponents, source: UriComponents | undefined, timeout: number, token: CancellationToken): Promise<any>;
|
||||
$onDidRunFileOperation(operation: files.FileOperation, target: UriComponents, source: UriComponents | undefined): void;
|
||||
$onWillRunFileOperation(operation: files.FileOperation, files: SourceTargetPair[], timeout: number, token: CancellationToken): Promise<any>;
|
||||
$onDidRunFileOperation(operation: files.FileOperation, files: SourceTargetPair[]): void;
|
||||
}
|
||||
|
||||
export interface ObjectIdentifier {
|
||||
@@ -1385,6 +1395,17 @@ export interface IShellAndArgsDto {
|
||||
args: string[] | string | undefined;
|
||||
}
|
||||
|
||||
export interface ITerminalLinkDto {
|
||||
/** The ID of the link to enable activation and disposal. */
|
||||
id: number;
|
||||
/** The startIndex of the link in the line. */
|
||||
startIndex: number;
|
||||
/** The length of the link in the line. */
|
||||
length: number;
|
||||
/** The descriptive label for what the link does when activated. */
|
||||
label?: string;
|
||||
}
|
||||
|
||||
export interface ITerminalDimensionsDto {
|
||||
columns: number;
|
||||
rows: number;
|
||||
@@ -1411,6 +1432,8 @@ export interface ExtHostTerminalServiceShape {
|
||||
$getAvailableShells(): Promise<IShellDefinitionDto[]>;
|
||||
$getDefaultShellAndArgs(useAutomationShell: boolean): Promise<IShellAndArgsDto>;
|
||||
$handleLink(id: number, link: string): Promise<boolean>;
|
||||
$provideLinks(id: number, line: string): Promise<ITerminalLinkDto[]>;
|
||||
$activateLink(id: number, linkId: number): void;
|
||||
$initEnvironmentVariableCollections(collections: [string, ISerializableEnvironmentVariableCollection][]): void;
|
||||
}
|
||||
|
||||
@@ -1419,7 +1442,7 @@ export interface ExtHostSCMShape {
|
||||
$onInputBoxValueChange(sourceControlHandle: number, value: string): void;
|
||||
$executeResourceCommand(sourceControlHandle: number, groupHandle: number, handle: number, preserveFocus: boolean): Promise<void>;
|
||||
$validateInput(sourceControlHandle: number, value: string, cursorPosition: number): Promise<[string, number] | undefined>;
|
||||
$setSelectedSourceControls(selectedSourceControlHandles: number[]): Promise<void>;
|
||||
$setSelectedSourceControl(selectedSourceControlHandle: number | undefined): Promise<void>;
|
||||
}
|
||||
|
||||
export interface ExtHostTaskShape {
|
||||
@@ -1514,7 +1537,6 @@ export interface ExtHostDebugServiceShape {
|
||||
|
||||
export interface DecorationRequest {
|
||||
readonly id: number;
|
||||
readonly handle: number;
|
||||
readonly uri: UriComponents;
|
||||
}
|
||||
|
||||
@@ -1522,7 +1544,7 @@ export type DecorationData = [number, boolean, string, string, ThemeColor];
|
||||
export type DecorationReply = { [id: number]: DecorationData; };
|
||||
|
||||
export interface ExtHostDecorationsShape {
|
||||
$provideDecorations(requests: DecorationRequest[], token: CancellationToken): Promise<DecorationReply>;
|
||||
$provideDecorations(handle: number, requests: DecorationRequest[], token: CancellationToken): Promise<DecorationReply>;
|
||||
}
|
||||
|
||||
export interface ExtHostWindowShape {
|
||||
@@ -1599,7 +1621,7 @@ export interface ExtHostNotebookShape {
|
||||
$acceptDisplayOrder(displayOrder: INotebookDisplayOrder): void;
|
||||
$renderOutputs(uriComponents: UriComponents, id: string, request: IOutputRenderRequest<UriComponents>): Promise<IOutputRenderResponse<UriComponents> | undefined>;
|
||||
$renderOutputs2<T>(uriComponents: UriComponents, id: string, request: IOutputRenderRequest<T>): Promise<IOutputRenderResponse<T> | undefined>;
|
||||
$onDidReceiveMessage(editorId: string, message: any): void;
|
||||
$onDidReceiveMessage(editorId: string, rendererId: string | undefined, message: unknown): void;
|
||||
$acceptModelChanged(uriComponents: UriComponents, event: NotebookCellsChangedEvent): void;
|
||||
$acceptEditorPropertiesChanged(uriComponents: UriComponents, data: INotebookEditorPropertiesChangeData): void;
|
||||
$acceptDocumentAndEditorsDelta(delta: INotebookDocumentsAndEditorsDelta): Promise<void>;
|
||||
|
||||
@@ -56,8 +56,8 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
||||
return !!(sessions.filter(session => session.scopes.sort().join(' ') === orderedScopes).length);
|
||||
}
|
||||
|
||||
async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: string[], options: vscode.AuthenticationGetSessionOptions & { createIfNone: true }): Promise<vscode.AuthenticationSession2>;
|
||||
async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: string[], options: vscode.AuthenticationGetSessionOptions): Promise<vscode.AuthenticationSession2 | undefined> {
|
||||
async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: string[], options: vscode.AuthenticationGetSessionOptions & { createIfNone: true }): Promise<vscode.AuthenticationSession>;
|
||||
async getSession(requestingExtension: IExtensionDescription, providerId: string, scopes: string[], options: vscode.AuthenticationGetSessionOptions): Promise<vscode.AuthenticationSession | undefined> {
|
||||
const provider = this._authenticationProviders.get(providerId);
|
||||
const extensionName = requestingExtension.displayName || requestingExtension.name;
|
||||
const extensionId = ExtensionIdentifier.toKey(requestingExtension.identifier);
|
||||
@@ -100,71 +100,6 @@ export class ExtHostAuthentication implements ExtHostAuthenticationShape {
|
||||
}
|
||||
}
|
||||
|
||||
async getSessions(requestingExtension: IExtensionDescription, providerId: string, scopes: string[]): Promise<readonly vscode.AuthenticationSession[]> {
|
||||
const extensionId = ExtensionIdentifier.toKey(requestingExtension.identifier);
|
||||
const orderedScopes = scopes.sort().join(' ');
|
||||
const sessions = await this.resolveSessions(providerId);
|
||||
return sessions
|
||||
.filter(session => session.scopes.sort().join(' ') === orderedScopes)
|
||||
.map(session => {
|
||||
return {
|
||||
id: session.id,
|
||||
account: session.account,
|
||||
scopes: session.scopes,
|
||||
getAccessToken: async () => {
|
||||
const isAllowed = await this._proxy.$getSessionsPrompt(
|
||||
providerId,
|
||||
session.account.displayName,
|
||||
'', // TODO
|
||||
// provider.displayName,
|
||||
extensionId,
|
||||
requestingExtension.displayName || requestingExtension.name);
|
||||
|
||||
if (!isAllowed) {
|
||||
throw new Error('User did not consent to token access.');
|
||||
}
|
||||
|
||||
return session.accessToken;
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async login(requestingExtension: IExtensionDescription, providerId: string, scopes: string[]): Promise<vscode.AuthenticationSession> {
|
||||
const provider = this._authenticationProviders.get(providerId);
|
||||
if (!provider) {
|
||||
throw new Error(`No authentication provider with id '${providerId}' is currently registered.`);
|
||||
}
|
||||
|
||||
const extensionName = requestingExtension.displayName || requestingExtension.name;
|
||||
const isAllowed = await this._proxy.$loginPrompt(provider.displayName, extensionName);
|
||||
if (!isAllowed) {
|
||||
throw new Error('User did not consent to login.');
|
||||
}
|
||||
|
||||
const session = await provider.login(scopes);
|
||||
await this._proxy.$setTrustedExtension(provider.id, session.account.displayName, ExtensionIdentifier.toKey(requestingExtension.identifier), extensionName);
|
||||
return {
|
||||
id: session.id,
|
||||
account: session.account,
|
||||
scopes: session.scopes,
|
||||
getAccessToken: async () => {
|
||||
const isAllowed = await this._proxy.$getSessionsPrompt(
|
||||
provider.id,
|
||||
session.account.displayName,
|
||||
provider.displayName,
|
||||
ExtensionIdentifier.toKey(requestingExtension.identifier),
|
||||
requestingExtension.displayName || requestingExtension.name);
|
||||
|
||||
if (!isAllowed) {
|
||||
throw new Error('User did not consent to token access.');
|
||||
}
|
||||
|
||||
return session.accessToken;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async logout(providerId: string, sessionId: string): Promise<void> {
|
||||
const provider = this._authenticationProviders.get(providerId);
|
||||
if (!provider) {
|
||||
|
||||
@@ -296,7 +296,8 @@ export abstract class ExtHostDebugServiceBase implements IExtHostDebugService, E
|
||||
return this._debugServiceProxy.$startDebugging(folder ? folder.uri : undefined, nameOrConfig, {
|
||||
parentSessionID: options.parentSession ? options.parentSession.id : undefined,
|
||||
repl: options.consoleMode === DebugConsoleMode.MergeWithParent ? 'mergeWithParent' : 'separate',
|
||||
noDebug: options.noDebug
|
||||
noDebug: options.noDebug,
|
||||
noCompact: options.noCompact
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -52,17 +52,20 @@ export class ExtHostDecorations implements IExtHostDecorations {
|
||||
});
|
||||
}
|
||||
|
||||
$provideDecorations(requests: DecorationRequest[], token: CancellationToken): Promise<DecorationReply> {
|
||||
async $provideDecorations(handle: number, requests: DecorationRequest[], token: CancellationToken): Promise<DecorationReply> {
|
||||
|
||||
if (!this._provider.has(handle)) {
|
||||
// might have been unregistered in the meantime
|
||||
return Object.create(null);
|
||||
}
|
||||
|
||||
const result: DecorationReply = Object.create(null);
|
||||
return Promise.all(requests.map(request => {
|
||||
const { handle, uri, id } = request;
|
||||
const entry = this._provider.get(handle);
|
||||
if (!entry) {
|
||||
// might have been unregistered in the meantime
|
||||
return undefined;
|
||||
}
|
||||
const { provider, extensionId } = entry;
|
||||
return Promise.resolve(provider.provideDecoration(URI.revive(uri), token)).then(data => {
|
||||
const { provider, extensionId } = this._provider.get(handle)!;
|
||||
|
||||
await Promise.all(requests.map(async request => {
|
||||
try {
|
||||
const { uri, id } = request;
|
||||
const data = await Promise.resolve(provider.provideDecoration(URI.revive(uri), token));
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
@@ -72,13 +75,12 @@ export class ExtHostDecorations implements IExtHostDecorations {
|
||||
} catch (e) {
|
||||
this._logService.warn(`INVALID decoration from extension '${extensionId.value}': ${e}`);
|
||||
}
|
||||
}, err => {
|
||||
} catch (err) {
|
||||
this._logService.error(err);
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
})).then(() => {
|
||||
return result;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
import { AsyncEmitter, Emitter, Event, IWaitUntil } from 'vs/base/common/event';
|
||||
import { IRelativePattern, parse } from 'vs/base/common/glob';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ExtHostDocumentsAndEditors } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
|
||||
import type * as vscode from 'vscode';
|
||||
import { ExtHostFileSystemEventServiceShape, FileSystemEvents, IMainContext, MainContext, MainThreadTextEditorsShape, IWorkspaceFileEditDto, IWorkspaceTextEditDto } from './extHost.protocol';
|
||||
import { ExtHostFileSystemEventServiceShape, FileSystemEvents, IMainContext, MainContext, MainThreadTextEditorsShape, IWorkspaceFileEditDto, IWorkspaceTextEditDto, SourceTargetPair } from './extHost.protocol';
|
||||
import * as typeConverter from './extHostTypeConverters';
|
||||
import { Disposable, WorkspaceEdit } from './extHostTypes';
|
||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
@@ -142,16 +142,16 @@ export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServ
|
||||
|
||||
//--- file operations
|
||||
|
||||
$onDidRunFileOperation(operation: FileOperation, target: UriComponents, source: UriComponents | undefined): void {
|
||||
$onDidRunFileOperation(operation: FileOperation, files: SourceTargetPair[]): void {
|
||||
switch (operation) {
|
||||
case FileOperation.MOVE:
|
||||
this._onDidRenameFile.fire(Object.freeze({ files: [{ oldUri: URI.revive(source!), newUri: URI.revive(target) }] }));
|
||||
this._onDidRenameFile.fire(Object.freeze({ files: files.map(f => ({ oldUri: URI.revive(f.source!), newUri: URI.revive(f.target) })) }));
|
||||
break;
|
||||
case FileOperation.DELETE:
|
||||
this._onDidDeleteFile.fire(Object.freeze({ files: [URI.revive(target)] }));
|
||||
this._onDidDeleteFile.fire(Object.freeze({ files: files.map(f => URI.revive(f.target)) }));
|
||||
break;
|
||||
case FileOperation.CREATE:
|
||||
this._onDidCreateFile.fire(Object.freeze({ files: [URI.revive(target)] }));
|
||||
this._onDidCreateFile.fire(Object.freeze({ files: files.map(f => URI.revive(f.target)) }));
|
||||
break;
|
||||
default:
|
||||
//ignore, dont send
|
||||
@@ -179,16 +179,16 @@ export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServ
|
||||
};
|
||||
}
|
||||
|
||||
async $onWillRunFileOperation(operation: FileOperation, target: UriComponents, source: UriComponents | undefined, timeout: number, token: CancellationToken): Promise<any> {
|
||||
async $onWillRunFileOperation(operation: FileOperation, files: SourceTargetPair[], timeout: number, token: CancellationToken): Promise<any> {
|
||||
switch (operation) {
|
||||
case FileOperation.MOVE:
|
||||
await this._fireWillEvent(this._onWillRenameFile, { files: [{ oldUri: URI.revive(source!), newUri: URI.revive(target) }] }, timeout, token);
|
||||
await this._fireWillEvent(this._onWillRenameFile, { files: files.map(f => ({ oldUri: URI.revive(f.source!), newUri: URI.revive(f.target) })) }, timeout, token);
|
||||
break;
|
||||
case FileOperation.DELETE:
|
||||
await this._fireWillEvent(this._onWillDeleteFile, { files: [URI.revive(target)] }, timeout, token);
|
||||
await this._fireWillEvent(this._onWillDeleteFile, { files: files.map(f => URI.revive(f.target)) }, timeout, token);
|
||||
break;
|
||||
case FileOperation.CREATE:
|
||||
await this._fireWillEvent(this._onWillCreateFile, { files: [URI.revive(target)] }, timeout, token);
|
||||
await this._fireWillEvent(this._onWillCreateFile, { files: files.map(f => URI.revive(f.target)) }, timeout, token);
|
||||
break;
|
||||
default:
|
||||
//ignore, dont send
|
||||
|
||||
@@ -73,7 +73,7 @@ class DocumentSymbolAdapter {
|
||||
const element: modes.DocumentSymbol = {
|
||||
name: info.name || '!!MISSING: name!!',
|
||||
kind: typeConvert.SymbolKind.from(info.kind),
|
||||
tags: info.tags ? info.tags.map(typeConvert.SymbolTag.from) : [],
|
||||
tags: info.tags?.map(typeConvert.SymbolTag.from) || [],
|
||||
detail: '',
|
||||
containerName: info.containerName,
|
||||
range: typeConvert.Range.from(info.location.range),
|
||||
@@ -1287,6 +1287,7 @@ class CallHierarchyAdapter {
|
||||
uri: item.uri,
|
||||
range: typeConvert.Range.from(item.range),
|
||||
selectionRange: typeConvert.Range.from(item.selectionRange),
|
||||
tags: item.tags?.map(typeConvert.SymbolTag.from)
|
||||
};
|
||||
map.set(dto._itemId, item);
|
||||
return dto;
|
||||
|
||||
@@ -553,27 +553,48 @@ export class NotebookEditorCellEditBuilder implements vscode.NotebookEditorCellE
|
||||
}
|
||||
}
|
||||
|
||||
class ExtHostWebviewComm extends Disposable {
|
||||
|
||||
onDidReceiveMessage: vscode.Event<any> = this._onDidReceiveMessage.event;
|
||||
class ExtHostWebviewCommWrapper extends Disposable {
|
||||
private readonly _onDidReceiveDocumentMessage = new Emitter<any>();
|
||||
private readonly _rendererIdToEmitters = new Map<string, Emitter<any>>();
|
||||
|
||||
constructor(
|
||||
readonly id: string,
|
||||
private _editorId: string,
|
||||
public uri: URI,
|
||||
private _proxy: MainThreadNotebookShape,
|
||||
private _onDidReceiveMessage: Emitter<any>,
|
||||
private _webviewInitData: WebviewInitData,
|
||||
public document: ExtHostNotebookDocument,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async postMessage(message: any): Promise<boolean> {
|
||||
return this._proxy.$postMessage(this.document.handle, message);
|
||||
public onDidReceiveMessage(forRendererId: string | undefined, message: any) {
|
||||
this._onDidReceiveDocumentMessage.fire(message);
|
||||
if (forRendererId !== undefined) {
|
||||
this._rendererIdToEmitters.get(forRendererId)?.fire(message);
|
||||
}
|
||||
}
|
||||
|
||||
asWebviewUri(localResource: vscode.Uri): vscode.Uri {
|
||||
return asWebviewUri(this._webviewInitData, this.id, localResource);
|
||||
public readonly contentProviderComm: vscode.NotebookCommunication = {
|
||||
editorId: this._editorId,
|
||||
onDidReceiveMessage: this._onDidReceiveDocumentMessage.event,
|
||||
postMessage: (message: any) => this._proxy.$postMessage(this._editorId, undefined, message),
|
||||
asWebviewUri: (uri: vscode.Uri) => this._asWebviewUri(uri),
|
||||
};
|
||||
|
||||
public getRendererComm(rendererId: string): vscode.NotebookCommunication {
|
||||
const emitter = new Emitter<any>();
|
||||
this._rendererIdToEmitters.set(rendererId, emitter);
|
||||
return {
|
||||
editorId: this._editorId,
|
||||
onDidReceiveMessage: emitter.event,
|
||||
postMessage: (message: any) => this._proxy.$postMessage(this._editorId, rendererId, message),
|
||||
asWebviewUri: (uri: vscode.Uri) => this._asWebviewUri(uri),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private _asWebviewUri(localResource: vscode.Uri): vscode.Uri {
|
||||
return asWebviewUri(this._webviewInitData, this._editorId, localResource);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -618,7 +639,7 @@ export class ExtHostNotebookEditor extends Disposable implements vscode.Notebook
|
||||
readonly id: string,
|
||||
public uri: URI,
|
||||
private _proxy: MainThreadNotebookShape,
|
||||
private _webComm: ExtHostWebviewComm,
|
||||
private _webComm: vscode.NotebookCommunication,
|
||||
public document: ExtHostNotebookDocument,
|
||||
private _documentsAndEditors: ExtHostDocumentsAndEditors
|
||||
) {
|
||||
@@ -721,6 +742,7 @@ export class ExtHostNotebookEditor extends Disposable implements vscode.Notebook
|
||||
|
||||
export class ExtHostNotebookOutputRenderer {
|
||||
private static _handlePool: number = 0;
|
||||
private resolvedComms = new WeakSet<ExtHostWebviewCommWrapper>();
|
||||
readonly handle = ExtHostNotebookOutputRenderer._handlePool++;
|
||||
|
||||
constructor(
|
||||
@@ -740,13 +762,19 @@ export class ExtHostNotebookOutputRenderer {
|
||||
return false;
|
||||
}
|
||||
|
||||
resolveNotebook(document: ExtHostNotebookDocument, comm: ExtHostWebviewCommWrapper) {
|
||||
if (!this.resolvedComms.has(comm) && this.renderer.resolveNotebook) {
|
||||
this.renderer.resolveNotebook(document, comm.getRendererComm(this.type));
|
||||
this.resolvedComms.add(comm);
|
||||
}
|
||||
}
|
||||
|
||||
render(document: ExtHostNotebookDocument, output: vscode.CellDisplayOutput, outputId: string, mimeType: string): string {
|
||||
let html = this.renderer.render(document, { output, outputId, mimeType });
|
||||
|
||||
return html;
|
||||
}
|
||||
}
|
||||
|
||||
export interface ExtHostNotebookOutputRenderingHandler {
|
||||
outputDisplayOrder: INotebookDisplayOrder | undefined;
|
||||
findBestMatchedRenderer(mimeType: string): ExtHostNotebookOutputRenderer[];
|
||||
@@ -759,8 +787,9 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
private readonly _documents = new Map<string, ExtHostNotebookDocument>();
|
||||
private readonly _unInitializedDocuments = new Map<string, ExtHostNotebookDocument>();
|
||||
private readonly _editors = new Map<string, { editor: ExtHostNotebookEditor }>();
|
||||
private readonly _webviewComm = new Map<string, { comm: ExtHostWebviewComm, onDidReceiveMessage: Emitter<any> }>();
|
||||
private readonly _webviewComm = new Map<string, ExtHostWebviewCommWrapper>();
|
||||
private readonly _notebookOutputRenderers = new Map<string, ExtHostNotebookOutputRenderer>();
|
||||
private readonly _renderersUsedInNotebooks = new WeakMap<ExtHostNotebookDocument, Set<ExtHostNotebookOutputRenderer>>();
|
||||
private readonly _onDidChangeNotebookCells = new Emitter<vscode.NotebookCellsChangeEvent>();
|
||||
readonly onDidChangeNotebookCells = this._onDidChangeNotebookCells.event;
|
||||
private readonly _onDidChangeCellOutputs = new Emitter<vscode.NotebookCellOutputsChangeEvent>();
|
||||
@@ -854,6 +883,8 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
}
|
||||
|
||||
const renderer = this._notebookOutputRenderers.get(id)!;
|
||||
this.provideCommToNotebookRenderers(document, renderer);
|
||||
|
||||
const cellsResponse: IOutputRenderResponseCellInfo<UriComponents>[] = request.items.map(cellInfo => {
|
||||
const cell = document.getCell2(cellInfo.key)!;
|
||||
const outputResponse: IOutputRenderResponseOutputInfo[] = cellInfo.outputs.map(output => {
|
||||
@@ -890,6 +921,8 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
}
|
||||
|
||||
const renderer = this._notebookOutputRenderers.get(id)!;
|
||||
this.provideCommToNotebookRenderers(document, renderer);
|
||||
|
||||
const cellsResponse: IOutputRenderResponseCellInfo<T>[] = request.items.map(cellInfo => {
|
||||
const outputResponse: IOutputRenderResponseOutputInfo[] = cellInfo.outputs.map(output => {
|
||||
return {
|
||||
@@ -1035,19 +1068,36 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
return;
|
||||
}
|
||||
|
||||
let webComm = this._webviewComm.get(editorId);
|
||||
if (!webComm) {
|
||||
webComm = new ExtHostWebviewCommWrapper(editorId, revivedUri, this._proxy, this._webviewInitData, document);
|
||||
this._webviewComm.set(editorId, webComm);
|
||||
}
|
||||
|
||||
if (!provider.provider.resolveNotebook) {
|
||||
return;
|
||||
}
|
||||
|
||||
let webComm = this._webviewComm.get(editorId)?.comm;
|
||||
await provider.provider.resolveNotebook(document, webComm.contentProviderComm);
|
||||
}
|
||||
|
||||
if (webComm) {
|
||||
await provider.provider.resolveNotebook(document, webComm);
|
||||
} else {
|
||||
const onDidReceiveMessage = new Emitter<any>();
|
||||
webComm = new ExtHostWebviewComm(editorId, revivedUri, this._proxy, onDidReceiveMessage, this._webviewInitData, document);
|
||||
this._webviewComm.set(editorId, { comm: webComm, onDidReceiveMessage });
|
||||
await provider.provider.resolveNotebook(document, webComm);
|
||||
private provideCommToNotebookRenderers(document: ExtHostNotebookDocument, renderer: ExtHostNotebookOutputRenderer) {
|
||||
let alreadyRegistered = this._renderersUsedInNotebooks.get(document);
|
||||
if (!alreadyRegistered) {
|
||||
alreadyRegistered = new Set();
|
||||
this._renderersUsedInNotebooks.set(document, alreadyRegistered);
|
||||
}
|
||||
|
||||
if (alreadyRegistered.has(renderer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
alreadyRegistered.add(renderer);
|
||||
for (const editorId of this._editors.keys()) {
|
||||
const comm = this._webviewComm.get(editorId);
|
||||
if (comm) {
|
||||
renderer.resolveNotebook(document, comm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1101,12 +1151,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
}
|
||||
|
||||
if (this._notebookContentProviders.has(viewType)) {
|
||||
try {
|
||||
await this._notebookContentProviders.get(viewType)!.provider.saveNotebook(document, token);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
await this._notebookContentProviders.get(viewType)!.provider.saveNotebook(document, token);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1120,12 +1165,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
}
|
||||
|
||||
if (this._notebookContentProviders.has(viewType)) {
|
||||
try {
|
||||
await this._notebookContentProviders.get(viewType)!.provider.saveNotebookAs(URI.revive(target), document, token);
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
await this._notebookContentProviders.get(viewType)!.provider.saveNotebookAs(URI.revive(target), document, token);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1182,12 +1222,8 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
return editor;
|
||||
}
|
||||
|
||||
$onDidReceiveMessage(editorId: string, message: any): void {
|
||||
let messageEmitter = this._webviewComm.get(editorId)?.onDidReceiveMessage;
|
||||
|
||||
if (messageEmitter) {
|
||||
messageEmitter.fire(message);
|
||||
}
|
||||
$onDidReceiveMessage(editorId: string, forRendererType: string | undefined, message: any): void {
|
||||
this._webviewComm.get(editorId)?.onDidReceiveMessage(forRendererType, message);
|
||||
}
|
||||
|
||||
$acceptModelChanged(uriComponents: UriComponents, event: NotebookCellsChangedEvent): void {
|
||||
@@ -1226,12 +1262,11 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
|
||||
private _createExtHostEditor(document: ExtHostNotebookDocument, editorId: string, selections: number[]) {
|
||||
const revivedUri = document.uri;
|
||||
let webComm = this._webviewComm.get(editorId)?.comm;
|
||||
let webComm = this._webviewComm.get(editorId);
|
||||
|
||||
if (!webComm) {
|
||||
const onDidReceiveMessage = new Emitter<any>();
|
||||
webComm = new ExtHostWebviewComm(editorId, revivedUri, this._proxy, onDidReceiveMessage, this._webviewInitData, document);
|
||||
this._webviewComm.set(editorId, { comm: webComm!, onDidReceiveMessage });
|
||||
webComm = new ExtHostWebviewCommWrapper(editorId, revivedUri, this._proxy, this._webviewInitData, document);
|
||||
this._webviewComm.set(editorId, webComm);
|
||||
}
|
||||
|
||||
let editor = new ExtHostNotebookEditor(
|
||||
@@ -1239,7 +1274,7 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
editorId,
|
||||
revivedUri,
|
||||
this._proxy,
|
||||
webComm,
|
||||
webComm.contentProviderComm,
|
||||
document,
|
||||
this._documentsAndEditors
|
||||
);
|
||||
@@ -1255,6 +1290,10 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
||||
|
||||
this._editors.get(editorId)?.editor.dispose();
|
||||
|
||||
for (const renderer of this._renderersUsedInNotebooks.get(document) ?? []) {
|
||||
renderer.resolveNotebook(document, webComm);
|
||||
}
|
||||
|
||||
this._editors.set(editorId, { editor });
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import { PrefixSumComputer } from 'vs/editor/common/viewModel/prefixSumComputer'
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { score } from 'vs/editor/common/modes/languageSelector';
|
||||
import { CellKind } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { isEqual } from 'vs/base/common/resources';
|
||||
import { ResourceMap } from 'vs/base/common/map';
|
||||
|
||||
export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextDocument {
|
||||
|
||||
@@ -20,6 +20,7 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
|
||||
private _isClosed = false;
|
||||
|
||||
private _cells!: ExtHostCell[];
|
||||
private _cellUris!: ResourceMap<number>;
|
||||
private _cellLengths!: PrefixSumComputer;
|
||||
private _cellLines!: PrefixSumComputer;
|
||||
private _versionId = 0;
|
||||
@@ -36,8 +37,8 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
|
||||
this._init();
|
||||
|
||||
this._disposables.add(extHostDocuments.onDidChangeDocument(e => {
|
||||
let cellIdx = this._cells.findIndex(cell => isEqual(cell.uri, e.document.uri));
|
||||
if (cellIdx >= 0) {
|
||||
let cellIdx = this._cellUris.get(e.document.uri);
|
||||
if (cellIdx !== undefined) {
|
||||
this._cellLengths.changeValue(cellIdx, this._cells[cellIdx].document.getText().length + 1);
|
||||
this._cellLines.changeValue(cellIdx, this._cells[cellIdx].document.lineCount);
|
||||
this._versionId += 1;
|
||||
@@ -53,7 +54,6 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
|
||||
};
|
||||
|
||||
this._disposables.add(extHostNotebooks.onDidChangeCellLanguage(e => documentChange(e.document)));
|
||||
this._disposables.add(extHostNotebooks.onDidChangeCellOutputs(e => documentChange(e.document)));
|
||||
this._disposables.add(extHostNotebooks.onDidChangeNotebookCells(e => documentChange(e.document)));
|
||||
}
|
||||
|
||||
@@ -68,10 +68,12 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
|
||||
|
||||
private _init() {
|
||||
this._cells = [];
|
||||
this._cellUris = new ResourceMap();
|
||||
const cellLengths: number[] = [];
|
||||
const cellLineCounts: number[] = [];
|
||||
for (let cell of this._notebook.cells) {
|
||||
if (cell.cellKind === CellKind.Code && (!this._selector || score(this._selector, cell.uri, cell.language, true))) {
|
||||
this._cellUris.set(cell.uri, this._cells.length);
|
||||
this._cells.push(<ExtHostCell>cell);
|
||||
cellLengths.push(cell.document.getText().length + 1);
|
||||
cellLineCounts.push(cell.document.lineCount);
|
||||
@@ -103,8 +105,8 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
|
||||
// get start and end locations and create substrings
|
||||
const start = this.locationAt(range.start);
|
||||
const end = this.locationAt(range.end);
|
||||
const startCell = this._cells.find(cell => isEqual(cell.uri, start.uri));
|
||||
const endCell = this._cells.find(cell => isEqual(cell.uri, end.uri));
|
||||
const startCell = this._cells[this._cellUris.get(start.uri) ?? -1];
|
||||
const endCell = this._cells[this._cellUris.get(end.uri) ?? -1];
|
||||
|
||||
if (!startCell || !endCell) {
|
||||
return '';
|
||||
@@ -131,8 +133,8 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
|
||||
return this._cells[idx.index].document.positionAt(idx.remainder).translate(lineCount);
|
||||
}
|
||||
|
||||
const idx = this._cells.findIndex(cell => isEqual(cell.uri, locationOrOffset.uri));
|
||||
if (idx >= 0) {
|
||||
const idx = this._cellUris.get(locationOrOffset.uri);
|
||||
if (idx !== undefined) {
|
||||
let line = this._cellLines.getAccumulatedValue(idx - 1);
|
||||
return new types.Position(line + locationOrOffset.range.start.line, locationOrOffset.range.start.character);
|
||||
}
|
||||
@@ -159,4 +161,24 @@ export class ExtHostNotebookConcatDocument implements vscode.NotebookConcatTextD
|
||||
const startCell = this._cells[startIdx.index];
|
||||
return new types.Location(startCell.uri, <types.Range>startCell.document.validateRange(range));
|
||||
}
|
||||
|
||||
contains(uri: vscode.Uri): boolean {
|
||||
return this._cellUris.has(uri);
|
||||
}
|
||||
|
||||
validateRange(range: vscode.Range): vscode.Range {
|
||||
const start = this.validatePosition(range.start);
|
||||
const end = this.validatePosition(range.end);
|
||||
return range.with(start, end);
|
||||
}
|
||||
|
||||
validatePosition(position: vscode.Position): vscode.Position {
|
||||
const startIdx = this._cellLines.getIndexOf(position.line);
|
||||
|
||||
const cellPosition = new types.Position(startIdx.remainder, position.character);
|
||||
const validCellPosition = this._cells[startIdx.index].document.validatePosition(cellPosition);
|
||||
|
||||
const line = this._cellLines.getAccumulatedValue(startIdx.index - 1);
|
||||
return new types.Position(line + validCellPosition.line, validCellPosition.character);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,7 +536,7 @@ export class ExtHostSCM implements ExtHostSCMShape {
|
||||
private readonly _onDidChangeActiveProvider = new Emitter<vscode.SourceControl>();
|
||||
get onDidChangeActiveProvider(): Event<vscode.SourceControl> { return this._onDidChangeActiveProvider.event; }
|
||||
|
||||
private _selectedSourceControlHandles = new Set<number>();
|
||||
private _selectedSourceControlHandle: number | undefined;
|
||||
|
||||
constructor(
|
||||
mainContext: IMainContext,
|
||||
@@ -681,40 +681,18 @@ export class ExtHostSCM implements ExtHostSCMShape {
|
||||
});
|
||||
}
|
||||
|
||||
$setSelectedSourceControls(selectedSourceControlHandles: number[]): Promise<void> {
|
||||
this.logService.trace('ExtHostSCM#$setSelectedSourceControls', selectedSourceControlHandles);
|
||||
$setSelectedSourceControl(selectedSourceControlHandle: number | undefined): Promise<void> {
|
||||
this.logService.trace('ExtHostSCM#$setSelectedSourceControl', selectedSourceControlHandle);
|
||||
|
||||
const set = new Set<number>();
|
||||
|
||||
for (const handle of selectedSourceControlHandles) {
|
||||
set.add(handle);
|
||||
if (selectedSourceControlHandle !== undefined) {
|
||||
this._sourceControls.get(selectedSourceControlHandle)?.setSelectionState(true);
|
||||
}
|
||||
|
||||
set.forEach(handle => {
|
||||
if (!this._selectedSourceControlHandles.has(handle)) {
|
||||
const sourceControl = this._sourceControls.get(handle);
|
||||
if (this._selectedSourceControlHandle !== undefined) {
|
||||
this._sourceControls.get(this._selectedSourceControlHandle)?.setSelectionState(false);
|
||||
}
|
||||
|
||||
if (!sourceControl) {
|
||||
return;
|
||||
}
|
||||
|
||||
sourceControl.setSelectionState(true);
|
||||
}
|
||||
});
|
||||
|
||||
this._selectedSourceControlHandles.forEach(handle => {
|
||||
if (!set.has(handle)) {
|
||||
const sourceControl = this._sourceControls.get(handle);
|
||||
|
||||
if (!sourceControl) {
|
||||
return;
|
||||
}
|
||||
|
||||
sourceControl.setSelectionState(false);
|
||||
}
|
||||
});
|
||||
|
||||
this._selectedSourceControlHandles = set;
|
||||
this._selectedSourceControlHandle = selectedSourceControlHandle;
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import type * as vscode from 'vscode';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IShellLaunchConfigDto, IShellDefinitionDto, IShellAndArgsDto, ITerminalDimensionsDto } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { ExtHostTerminalServiceShape, MainContext, MainThreadTerminalServiceShape, IShellLaunchConfigDto, IShellDefinitionDto, IShellAndArgsDto, ITerminalDimensionsDto, ITerminalLinkDto } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { ExtHostConfigProvider } from 'vs/workbench/api/common/extHostConfiguration';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
@@ -39,6 +39,7 @@ export interface IExtHostTerminalService extends ExtHostTerminalServiceShape {
|
||||
getDefaultShell(useAutomationShell: boolean, configProvider: ExtHostConfigProvider): string;
|
||||
getDefaultShellArgs(useAutomationShell: boolean, configProvider: ExtHostConfigProvider): string[] | string;
|
||||
registerLinkHandler(handler: vscode.TerminalLinkHandler): vscode.Disposable;
|
||||
registerLinkProvider(provider: vscode.TerminalLinkProvider): vscode.Disposable;
|
||||
getEnvironmentVariableCollection(extension: IExtensionDescription, persistent?: boolean): vscode.EnvironmentVariableCollection;
|
||||
}
|
||||
|
||||
@@ -293,6 +294,13 @@ export class ExtHostPseudoterminal implements ITerminalChildProcess {
|
||||
}
|
||||
}
|
||||
|
||||
let nextLinkId = 1;
|
||||
|
||||
interface ICachedLinkEntry {
|
||||
provider: vscode.TerminalLinkProvider;
|
||||
link: vscode.TerminalLink;
|
||||
}
|
||||
|
||||
export abstract class BaseExtHostTerminalService implements IExtHostTerminalService, ExtHostTerminalServiceShape {
|
||||
|
||||
readonly _serviceBrand: undefined;
|
||||
@@ -307,6 +315,8 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
|
||||
|
||||
private readonly _bufferer: TerminalDataBufferer;
|
||||
private readonly _linkHandlers: Set<vscode.TerminalLinkHandler> = new Set();
|
||||
private readonly _linkProviders: Set<vscode.TerminalLinkProvider> = new Set();
|
||||
private readonly _terminalLinkCache: Map<number, Map<number, ICachedLinkEntry>> = new Map();
|
||||
|
||||
public get activeTerminal(): ExtHostTerminal | undefined { return this._activeTerminal; }
|
||||
public get terminals(): ExtHostTerminal[] { return this._terminals; }
|
||||
@@ -547,17 +557,30 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
|
||||
|
||||
public registerLinkHandler(handler: vscode.TerminalLinkHandler): vscode.Disposable {
|
||||
this._linkHandlers.add(handler);
|
||||
if (this._linkHandlers.size === 1) {
|
||||
if (this._linkHandlers.size === 1 && this._linkProviders.size === 0) {
|
||||
this._proxy.$startHandlingLinks();
|
||||
}
|
||||
return new VSCodeDisposable(() => {
|
||||
this._linkHandlers.delete(handler);
|
||||
if (this._linkHandlers.size === 0) {
|
||||
if (this._linkHandlers.size === 0 && this._linkProviders.size === 0) {
|
||||
this._proxy.$stopHandlingLinks();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public registerLinkProvider(provider: vscode.TerminalLinkProvider): vscode.Disposable {
|
||||
this._linkProviders.add(provider);
|
||||
if (this._linkProviders.size === 1) {
|
||||
this._proxy.$startLinkProvider();
|
||||
}
|
||||
return new VSCodeDisposable(() => {
|
||||
this._linkProviders.delete(provider);
|
||||
if (this._linkProviders.size === 0) {
|
||||
this._proxy.$stopLinkProvider();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public async $handleLink(id: number, link: string): Promise<boolean> {
|
||||
const terminal = this._getTerminalById(id);
|
||||
if (!terminal) {
|
||||
@@ -577,6 +600,60 @@ export abstract class BaseExtHostTerminalService implements IExtHostTerminalServ
|
||||
return false;
|
||||
}
|
||||
|
||||
public async $provideLinks(terminalId: number, line: string): Promise<ITerminalLinkDto[]> {
|
||||
const terminal = this._getTerminalById(terminalId);
|
||||
if (!terminal) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Discard any cached links the terminal has been holding, currently all links are released
|
||||
// when new links are provided.
|
||||
this._terminalLinkCache.delete(terminalId);
|
||||
|
||||
const result: ITerminalLinkDto[] = [];
|
||||
const context: vscode.TerminalLinkContext = { terminal, line };
|
||||
const promises: vscode.ProviderResult<{ provider: vscode.TerminalLinkProvider, links: vscode.TerminalLink[] }>[] = [];
|
||||
for (const provider of this._linkProviders) {
|
||||
promises.push(new Promise(async r => {
|
||||
const links = (await provider.provideTerminalLinks(context)) || [];
|
||||
r({ provider, links });
|
||||
}));
|
||||
}
|
||||
|
||||
const provideResults = await Promise.all(promises);
|
||||
const cacheLinkMap = new Map<number, ICachedLinkEntry>();
|
||||
for (const provideResult of provideResults) {
|
||||
if (provideResult && provideResult.links.length > 0) {
|
||||
result.push(...provideResult.links.map(providerLink => {
|
||||
const endIndex = Math.max(providerLink.endIndex, providerLink.startIndex + 1);
|
||||
const link = {
|
||||
id: nextLinkId++,
|
||||
startIndex: providerLink.startIndex,
|
||||
length: endIndex - providerLink.startIndex,
|
||||
label: providerLink.tooltip
|
||||
};
|
||||
cacheLinkMap.set(link.id, {
|
||||
provider: provideResult.provider,
|
||||
link: providerLink
|
||||
});
|
||||
return link;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
this._terminalLinkCache.set(terminalId, cacheLinkMap);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
$activateLink(terminalId: number, linkId: number): void {
|
||||
const cachedLink = this._terminalLinkCache.get(terminalId)?.get(linkId);
|
||||
if (!cachedLink) {
|
||||
return;
|
||||
}
|
||||
cachedLink.provider.handleTerminalLink(cachedLink.link);
|
||||
}
|
||||
|
||||
private _onProcessExit(id: number, exitCode: number | undefined): void {
|
||||
this._bufferer.stopBuffering(id);
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ import { equals, coalesce } from 'vs/base/common/arrays';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { MarkdownString } from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import { IMarkdownString } from 'vs/base/common/htmlContent';
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
import * as azdata from 'azdata';
|
||||
@@ -119,6 +121,22 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape {
|
||||
return treeView.getChildren(treeItemHandle);
|
||||
}
|
||||
|
||||
async $hasResolve(treeViewId: string): Promise<boolean> {
|
||||
const treeView = this.treeViews.get(treeViewId);
|
||||
if (!treeView) {
|
||||
throw new Error(localize('treeView.notRegistered', 'No tree view with id \'{0}\' registered.', treeViewId));
|
||||
}
|
||||
return treeView.hasResolve;
|
||||
}
|
||||
|
||||
$resolve(treeViewId: string, treeItemHandle: string): Promise<ITreeItem | undefined> {
|
||||
const treeView = this.treeViews.get(treeViewId);
|
||||
if (!treeView) {
|
||||
throw new Error(localize('treeView.notRegistered', 'No tree view with id \'{0}\' registered.', treeViewId));
|
||||
}
|
||||
return treeView.resolveTreeItem(treeItemHandle);
|
||||
}
|
||||
|
||||
$setExpanded(treeViewId: string, treeItemHandle: string, expanded: boolean): void {
|
||||
const treeView = this.treeViews.get(treeViewId);
|
||||
if (!treeView) {
|
||||
@@ -160,6 +178,7 @@ type TreeData<T> = { message: boolean, element: T | Root | false };
|
||||
|
||||
export interface TreeNode extends IDisposable { // {{SQL CARBON EDIT}} export interface
|
||||
item: ITreeItem;
|
||||
extensionItem: vscode.TreeItem2;
|
||||
parent: TreeNode | Root;
|
||||
children?: TreeNode[];
|
||||
}
|
||||
@@ -334,8 +353,28 @@ export class ExtHostTreeView<T> extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
protected resolveUnknownParentChain(element: T): Promise<TreeNode[]> {
|
||||
get hasResolve(): boolean {
|
||||
return !!this.dataProvider.resolveTreeItem;
|
||||
}
|
||||
|
||||
async resolveTreeItem(treeItemHandle: string): Promise<ITreeItem | undefined> {
|
||||
if (!this.dataProvider.resolveTreeItem) {
|
||||
return undefined; // {{SQL CARBON EDIT}} strict-null-checks
|
||||
}
|
||||
const element = this.elements.get(treeItemHandle);
|
||||
if (element) {
|
||||
const node = this.nodes.get(element);
|
||||
if (node) {
|
||||
const resolve = await this.dataProvider.resolveTreeItem(element, node.extensionItem);
|
||||
// Resolvable elements. Currently only tooltip.
|
||||
node.item.tooltip = resolve.tooltip;
|
||||
return node.item;
|
||||
}
|
||||
}
|
||||
return undefined; // {{SQL CARBON EDIT}} strict-null-checks
|
||||
}
|
||||
|
||||
protected resolveUnknownParentChain(element: T): Promise<TreeNode[]> { // {{SQL CARBON EDIT}}
|
||||
return this.resolveParent(element)
|
||||
.then((parent) => {
|
||||
if (!parent) {
|
||||
@@ -498,7 +537,18 @@ export class ExtHostTreeView<T> extends Disposable {
|
||||
return node;
|
||||
}
|
||||
|
||||
protected createTreeNode(element: T, extensionTreeItem: azdata.TreeItem2, parent: TreeNode | Root): TreeNode { // {{SQL CARBON EDIT}} change to protected, change to azdata.TreeItem
|
||||
private getTooltip(tooltip?: string | vscode.MarkdownString): string | IMarkdownString | undefined {
|
||||
if (typeof tooltip === 'string') {
|
||||
return tooltip;
|
||||
} else if (tooltip === undefined) {
|
||||
return undefined;
|
||||
} else {
|
||||
checkProposedApiEnabled(this.extension);
|
||||
return MarkdownString.from(tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
protected createTreeNode(element: T, extensionTreeItem: azdata.TreeItem2, parent: TreeNode | Root): TreeNode { // {{SQL CARBON EDIT}} change to protected, change to azdata.TreeItem
|
||||
const disposable = new DisposableStore();
|
||||
const handle = this.createHandle(element, extensionTreeItem, parent);
|
||||
const icon = this.getLightIconPath(extensionTreeItem);
|
||||
@@ -508,7 +558,7 @@ export class ExtHostTreeView<T> extends Disposable {
|
||||
label: toTreeItemLabel(extensionTreeItem.label, this.extension),
|
||||
description: extensionTreeItem.description,
|
||||
resourceUri: extensionTreeItem.resourceUri,
|
||||
tooltip: typeof extensionTreeItem.tooltip === 'string' ? extensionTreeItem.tooltip : undefined,
|
||||
tooltip: this.getTooltip(extensionTreeItem.tooltip),
|
||||
command: extensionTreeItem.command ? this.commands.toInternal(extensionTreeItem.command, disposable) : undefined,
|
||||
contextValue: extensionTreeItem.contextValue,
|
||||
icon,
|
||||
@@ -523,6 +573,7 @@ export class ExtHostTreeView<T> extends Disposable {
|
||||
|
||||
return {
|
||||
item,
|
||||
extensionItem: extensionTreeItem,
|
||||
parent,
|
||||
children: undefined,
|
||||
dispose(): void { disposable.dispose(); }
|
||||
|
||||
@@ -646,7 +646,7 @@ export namespace DocumentSymbol {
|
||||
range: Range.from(info.range),
|
||||
selectionRange: Range.from(info.selectionRange),
|
||||
kind: SymbolKind.from(info.kind),
|
||||
tags: info.tags ? info.tags.map(SymbolTag.from) : []
|
||||
tags: info.tags?.map(SymbolTag.from) ?? []
|
||||
};
|
||||
if (info.children) {
|
||||
result.children = info.children.map(from);
|
||||
@@ -911,7 +911,7 @@ export namespace CompletionItem {
|
||||
|
||||
result.insertText = suggestion.insertText;
|
||||
result.kind = CompletionItemKind.to(suggestion.kind);
|
||||
result.tags = suggestion.tags && suggestion.tags.map(CompletionItemTag.to);
|
||||
result.tags = suggestion.tags?.map(CompletionItemTag.to);
|
||||
result.detail = suggestion.detail;
|
||||
result.documentation = htmlContent.isMarkdownString(suggestion.documentation) ? MarkdownString.to(suggestion.documentation) : suggestion.documentation;
|
||||
result.sortText = suggestion.sortText;
|
||||
|
||||
@@ -1252,7 +1252,7 @@ export class MarkdownString {
|
||||
// escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash
|
||||
this.value += (this.supportThemeIcons ? escapeCodicons(value) : value)
|
||||
.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&')
|
||||
.replace('\n', '\n\n');
|
||||
.replace(/\n/, '\n\n');
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -2101,7 +2101,7 @@ export class TreeItem {
|
||||
iconPath?: string | URI | { light: string | URI; dark: string | URI; };
|
||||
command?: vscode.Command;
|
||||
contextValue?: string;
|
||||
tooltip?: string;
|
||||
tooltip?: string | vscode.MarkdownString;
|
||||
|
||||
constructor(label: string | vscode.TreeItemLabel, collapsibleState?: vscode.TreeItemCollapsibleState);
|
||||
constructor(resourceUri: URI, collapsibleState?: vscode.TreeItemCollapsibleState);
|
||||
@@ -2769,7 +2769,7 @@ export enum ExtensionMode {
|
||||
|
||||
|
||||
//#region Authentication
|
||||
export class AuthenticationSession implements vscode.AuthenticationSession2 {
|
||||
export class AuthenticationSession implements vscode.AuthenticationSession {
|
||||
constructor(public id: string, public accessToken: string, public account: { displayName: string, id: string }, public scopes: string[]) { }
|
||||
}
|
||||
|
||||
|
||||
@@ -4,13 +4,15 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { ExtHostWindowShape, MainContext, MainThreadWindowShape, IMainContext, IOpenUriOptions } from './extHost.protocol';
|
||||
import { ExtHostWindowShape, MainContext, MainThreadWindowShape, IOpenUriOptions } from './extHost.protocol';
|
||||
import { WindowState } from 'vscode';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { isFalsyOrWhitespace } from 'vs/base/common/strings';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||
|
||||
export class ExtHostWindow implements ExtHostWindowShape {
|
||||
export class ExtHostWindow implements IExtHostWindow {
|
||||
|
||||
private static InitialState: WindowState = {
|
||||
focused: true
|
||||
@@ -24,8 +26,8 @@ export class ExtHostWindow implements ExtHostWindowShape {
|
||||
private _state = ExtHostWindow.InitialState;
|
||||
get state(): WindowState { return this._state; }
|
||||
|
||||
constructor(mainContext: IMainContext) {
|
||||
this._proxy = mainContext.getProxy(MainContext.MainThreadWindow);
|
||||
constructor(@IExtHostRpcService extHostRpc: IExtHostRpcService) {
|
||||
this._proxy = extHostRpc.getProxy(MainContext.MainThreadWindow);
|
||||
this._proxy.$getWindowVisibility().then(isFocused => this.$onDidChangeWindowFocus(isFocused));
|
||||
}
|
||||
|
||||
@@ -67,3 +69,6 @@ export class ExtHostWindow implements ExtHostWindowShape {
|
||||
return URI.from(result);
|
||||
}
|
||||
}
|
||||
|
||||
export const IExtHostWindow = createDecorator<IExtHostWindow>('IExtHostWindow');
|
||||
export interface IExtHostWindow extends ExtHostWindow, ExtHostWindowShape { }
|
||||
|
||||
@@ -29,12 +29,14 @@ import { ExtHostLogService } from 'vs/workbench/api/node/extHostLogService';
|
||||
import { IExtHostTunnelService } from 'vs/workbench/api/common/extHostTunnelService';
|
||||
import { ExtHostTunnelService } from 'vs/workbench/api/node/extHostTunnelService';
|
||||
import { IExtHostApiDeprecationService, ExtHostApiDeprecationService } from 'vs/workbench/api/common/extHostApiDeprecationService';
|
||||
import { IExtHostWindow, ExtHostWindow } from 'vs/workbench/api/common/extHostWindow';
|
||||
|
||||
// register singleton services
|
||||
registerSingleton(ILogService, ExtHostLogService);
|
||||
registerSingleton(IExtHostApiDeprecationService, ExtHostApiDeprecationService);
|
||||
registerSingleton(IExtHostOutputService, ExtHostOutputService2);
|
||||
registerSingleton(IExtHostWorkspace, ExtHostWorkspace);
|
||||
registerSingleton(IExtHostWindow, ExtHostWindow);
|
||||
registerSingleton(IExtHostDecorations, ExtHostDecorations);
|
||||
registerSingleton(IExtHostConfiguration, ExtHostConfiguration);
|
||||
registerSingleton(IExtHostCommands, ExtHostCommands);
|
||||
|
||||
@@ -121,6 +121,6 @@ export class ExtHostDebugService extends ExtHostDebugServiceBase {
|
||||
}
|
||||
|
||||
protected createVariableResolver(folders: vscode.WorkspaceFolder[], editorService: ExtHostDocumentsAndEditors, configurationService: ExtHostConfigProvider): AbstractVariableResolverService {
|
||||
return new ExtHostVariableResolverService(folders, undefined, configurationService, process.env as env.IProcessEnvironment);
|
||||
return new ExtHostVariableResolverService(folders, editorService, configurationService, process.env as env.IProcessEnvironment);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ export class ExtHostTask extends ExtHostTaskBase {
|
||||
throw new Error('Task from execution DTO is undefined');
|
||||
}
|
||||
const execution = await this.getTaskExecution(executionDTO, task);
|
||||
this._proxy.$executeTask(executionDTO.task).catch(error => { throw new Error(error); });
|
||||
this._proxy.$executeTask(executionDTO.task).catch(() => { /* The error here isn't actionable. */ });
|
||||
return execution;
|
||||
} else {
|
||||
const dto = TaskDTO.from(task, extension);
|
||||
@@ -75,7 +75,7 @@ export class ExtHostTask extends ExtHostTaskBase {
|
||||
}
|
||||
// Always get the task execution first to prevent timing issues when retrieving it later
|
||||
const execution = await this.getTaskExecution(await this._proxy.$getTaskExecution(dto), task);
|
||||
this._proxy.$executeTask(dto).catch(error => { throw new Error(error); });
|
||||
this._proxy.$executeTask(dto).catch(() => { /* The error here isn't actionable. */ });
|
||||
return execution;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService {
|
||||
|
||||
// fetch JS sources as text and create a new function around it
|
||||
const source = await response.text();
|
||||
const initFn = new Function('module', 'exports', 'require', 'window', `${source}\n//# sourceURL=${module.toString(true)}`);
|
||||
const initFn = new Function('module', 'exports', 'require', `${source}\n//# sourceURL=${module.toString(true)}`);
|
||||
|
||||
// define commonjs globals: `module`, `exports`, and `require`
|
||||
const _exports = {};
|
||||
@@ -66,7 +66,7 @@ export class ExtHostExtensionService extends AbstractExtHostExtensionService {
|
||||
|
||||
try {
|
||||
activationTimesBuilder.codeLoadingStart();
|
||||
initFn(_module, _exports, _require, self);
|
||||
initFn(_module, _exports, _require);
|
||||
return <T>(_module.exports !== _exports ? _module.exports : _exports);
|
||||
} finally {
|
||||
activationTimesBuilder.codeLoadingStop();
|
||||
|
||||
Reference in New Issue
Block a user