mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-25 01:25:36 -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;
|
||||
|
||||
Reference in New Issue
Block a user