UNPKG

@codingame/monaco-vscode-extensions-service-override

Version:

VSCode public API plugged on the monaco editor - extensions service-override

558 lines (555 loc) 25.3 kB
import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js'; import { Barrier } from 'vscode/vscode/vs/base/common/async'; import { URI } from 'vscode/vscode/vs/base/common/uri'; import { Emitter, Event } from 'vscode/vscode/vs/base/common/event'; import { observableValue } from 'vscode/vscode/vs/base/common/observableInternal/base'; import { derived } from 'vscode/vscode/vs/base/common/observableInternal/derived'; import 'vscode/vscode/vs/base/common/observableInternal/autorun'; import 'vscode/vscode/vs/base/common/observableInternal/utils'; import { CancellationToken } from 'vscode/vscode/vs/base/common/cancellation'; import 'vscode/vscode/vs/base/common/arrays'; import { observableValueOpts } from 'vscode/vscode/vs/base/common/observableInternal/api'; import { Disposable, DisposableStore, dispose, combinedDisposable } from 'vscode/vscode/vs/base/common/lifecycle'; import { ISCMService, ISCMViewService } from 'vscode/vscode/vs/workbench/contrib/scm/common/scm.service'; import { ExtHostContext, MainContext } from 'vscode/vscode/vs/workbench/api/common/extHost.protocol'; import { extHostNamedCustomer } from '../../services/extensions/common/extHostCustomers.js'; import { MarshalledId } from 'vscode/vscode/vs/base/common/marshallingIds'; import { ThemeIcon } from 'vscode/vscode/vs/base/common/themables'; import { IQuickDiffService } from 'vscode/vscode/vs/workbench/contrib/scm/common/quickDiff.service'; import { ResourceTree } from 'vscode/vscode/vs/base/common/resourceTree'; import { IUriIdentityService } from 'vscode/vscode/vs/platform/uriIdentity/common/uriIdentity.service'; import { IWorkspaceContextService } from 'vscode/vscode/vs/platform/workspace/common/workspace.service'; import { basename } from 'vscode/vscode/vs/base/common/resources'; import { ILanguageService } from 'vscode/vscode/vs/editor/common/languages/language'; import { IModelService } from 'vscode/vscode/vs/editor/common/services/model'; import { ITextModelService } from 'vscode/vscode/vs/editor/common/services/resolverService'; import { Schemas } from 'vscode/vscode/vs/base/common/network'; function getIconFromIconDto(iconDto) { if (iconDto === undefined) { return undefined; } else if (URI.isUri(iconDto)) { return URI.revive(iconDto); } else if (ThemeIcon.isThemeIcon(iconDto)) { return iconDto; } else { const icon = iconDto; return { light: URI.revive(icon.light), dark: URI.revive(icon.dark) }; } } function toISCMHistoryItem(historyItemDto) { const icon = getIconFromIconDto(historyItemDto.icon); const labels = historyItemDto.labels?.map(l => ({ title: l.title, icon: getIconFromIconDto(l.icon) })); return { ...historyItemDto, icon, labels }; } class SCMInputBoxContentProvider extends Disposable { constructor(textModelService, modelService, languageService) { super(); this.modelService = modelService; this.languageService = languageService; this._register(textModelService.registerTextModelContentProvider(Schemas.vscodeSourceControl, this)); } async provideTextContent(resource) { const existing = this.modelService.getModel(resource); if (existing) { return existing; } return this.modelService.createModel('', this.languageService.createById('scminput'), resource); } } class MainThreadSCMResourceGroup { get resourceTree() { if (!this._resourceTree) { const rootUri = this.provider.rootUri ?? URI.file('/'); this._resourceTree = ( new ResourceTree(this, rootUri, this._uriIdentService.extUri)); for (const resource of this.resources) { this._resourceTree.add(resource.sourceUri, resource); } } return this._resourceTree; } get hideWhenEmpty() { return !!this.features.hideWhenEmpty; } constructor(sourceControlHandle, handle, provider, features, label, id, multiDiffEditorEnableViewChanges, _uriIdentService) { this.sourceControlHandle = sourceControlHandle; this.handle = handle; this.provider = provider; this.features = features; this.label = label; this.id = id; this.multiDiffEditorEnableViewChanges = multiDiffEditorEnableViewChanges; this._uriIdentService = _uriIdentService; this.resources = []; this._onDidChange = ( new Emitter()); this.onDidChange = this._onDidChange.event; this._onDidChangeResources = ( new Emitter()); this.onDidChangeResources = this._onDidChangeResources.event; } toJSON() { return { $mid: MarshalledId.ScmResourceGroup, sourceControlHandle: this.sourceControlHandle, groupHandle: this.handle }; } splice(start, deleteCount, toInsert) { this.resources.splice(start, deleteCount, ...toInsert); this._resourceTree = undefined; this._onDidChangeResources.fire(); } $updateGroup(features) { this.features = { ...this.features, ...features }; this._onDidChange.fire(); } $updateGroupLabel(label) { this.label = label; this._onDidChange.fire(); } } class MainThreadSCMResource { constructor(proxy, sourceControlHandle, groupHandle, handle, sourceUri, resourceGroup, decorations, contextValue, command, multiDiffEditorOriginalUri, multiDiffEditorModifiedUri) { this.proxy = proxy; this.sourceControlHandle = sourceControlHandle; this.groupHandle = groupHandle; this.handle = handle; this.sourceUri = sourceUri; this.resourceGroup = resourceGroup; this.decorations = decorations; this.contextValue = contextValue; this.command = command; this.multiDiffEditorOriginalUri = multiDiffEditorOriginalUri; this.multiDiffEditorModifiedUri = multiDiffEditorModifiedUri; } open(preserveFocus) { return this.proxy.$executeResourceCommand(this.sourceControlHandle, this.groupHandle, this.handle, preserveFocus); } toJSON() { return { $mid: MarshalledId.ScmResource, sourceControlHandle: this.sourceControlHandle, groupHandle: this.groupHandle, handle: this.handle }; } } class MainThreadSCMHistoryProvider { get currentHistoryItemGroup() { return this._currentHistoryItemGroup; } constructor(proxy, handle) { this.proxy = proxy; this.handle = handle; this.currentHistoryItemGroupId = derived(this, reader => this.currentHistoryItemGroup.read(reader)?.id); this.currentHistoryItemGroupName = derived(this, reader => this.currentHistoryItemGroup.read(reader)?.name); this._currentHistoryItemGroup = observableValueOpts({ owner: this, equalsFn: () => false }, undefined); } async resolveHistoryItemGroupCommonAncestor(historyItemGroupId1, historyItemGroupId2) { return this.proxy.$resolveHistoryItemGroupCommonAncestor(this.handle, historyItemGroupId1, historyItemGroupId2, CancellationToken.None); } async resolveHistoryItemGroupCommonAncestor2(historyItemGroupIds) { return this.proxy.$resolveHistoryItemGroupCommonAncestor2(this.handle, historyItemGroupIds, CancellationToken.None); } async provideHistoryItems(historyItemGroupId, options) { const historyItems = await this.proxy.$provideHistoryItems(this.handle, historyItemGroupId, options, CancellationToken.None); return historyItems?.map(historyItem => toISCMHistoryItem(historyItem)); } async provideHistoryItems2(options) { const historyItems = await this.proxy.$provideHistoryItems2(this.handle, options, CancellationToken.None); return historyItems?.map(historyItem => toISCMHistoryItem(historyItem)); } async provideHistoryItemSummary(historyItemId, historyItemParentId) { const historyItem = await this.proxy.$provideHistoryItemSummary(this.handle, historyItemId, historyItemParentId, CancellationToken.None); return historyItem ? toISCMHistoryItem(historyItem) : undefined; } async provideHistoryItemChanges(historyItemId, historyItemParentId) { const changes = await this.proxy.$provideHistoryItemChanges(this.handle, historyItemId, historyItemParentId, CancellationToken.None); return changes?.map(change => ({ uri: URI.revive(change.uri), originalUri: change.originalUri && URI.revive(change.originalUri), modifiedUri: change.modifiedUri && URI.revive(change.modifiedUri), renameUri: change.renameUri && URI.revive(change.renameUri) })); } $onDidChangeCurrentHistoryItemGroup(historyItemGroup) { this._currentHistoryItemGroup.set(historyItemGroup, undefined); } } class MainThreadSCMProvider { static { this.ID_HANDLE = 0; } get id() { return this._id; } get handle() { return this._handle; } get label() { return this._label; } get rootUri() { return this._rootUri; } get inputBoxTextModel() { return this._inputBoxTextModel; } get contextValue() { return this._providerId; } get acceptInputCommand() { return this.features.acceptInputCommand; } get actionButton() { return this.features.actionButton ?? undefined; } get count() { return this._count; } get statusBarCommands() { return this._statusBarCommands; } get name() { return this._name ?? this._label; } get commitTemplate() { return this._commitTemplate; } get historyProvider() { return this._historyProvider; } constructor(proxy, _handle, _providerId, _label, _rootUri, _inputBoxTextModel, _quickDiffService, _uriIdentService, _workspaceContextService) { this.proxy = proxy; this._handle = _handle; this._providerId = _providerId; this._label = _label; this._rootUri = _rootUri; this._inputBoxTextModel = _inputBoxTextModel; this._quickDiffService = _quickDiffService; this._uriIdentService = _uriIdentService; this._workspaceContextService = _workspaceContextService; this._id = `scm${MainThreadSCMProvider.ID_HANDLE++}`; this.groups = []; this._onDidChangeResourceGroups = ( new Emitter()); this.onDidChangeResourceGroups = this._onDidChangeResourceGroups.event; this._onDidChangeResources = ( new Emitter()); this.onDidChangeResources = this._onDidChangeResources.event; this._groupsByHandle = Object.create(null); this.features = {}; this._count = observableValue(this, undefined); this._statusBarCommands = observableValue(this, undefined); this._commitTemplate = observableValue(this, ''); this._onDidChange = ( new Emitter()); this.onDidChange = this._onDidChange.event; this.isSCM = true; this._historyProvider = observableValue(this, undefined); if (_rootUri) { const folder = this._workspaceContextService.getWorkspaceFolder(_rootUri); if (folder?.uri.toString() === ( _rootUri.toString())) { this._name = folder.name; } else if (_rootUri.path !== '/') { this._name = basename(_rootUri); } } } $updateSourceControl(features) { this.features = { ...this.features, ...features }; this._onDidChange.fire(); if (typeof features.commitTemplate !== 'undefined') { this._commitTemplate.set(features.commitTemplate, undefined); } if (typeof features.count !== 'undefined') { this._count.set(features.count, undefined); } if (typeof features.statusBarCommands !== 'undefined') { this._statusBarCommands.set(features.statusBarCommands, undefined); } if (features.hasQuickDiffProvider && !this._quickDiff) { this._quickDiff = this._quickDiffService.addQuickDiffProvider({ label: features.quickDiffLabel ?? this.label, rootUri: this.rootUri, isSCM: this.isSCM, getOriginalResource: (uri) => this.getOriginalResource(uri) }); } else if (features.hasQuickDiffProvider === false && this._quickDiff) { this._quickDiff.dispose(); this._quickDiff = undefined; } if (features.hasHistoryProvider && !this.historyProvider.get()) { const historyProvider = ( new MainThreadSCMHistoryProvider(this.proxy, this.handle)); this._historyProvider.set(historyProvider, undefined); } else if (features.hasHistoryProvider === false && this.historyProvider.get()) { this._historyProvider.set(undefined, undefined); } } $registerGroups(_groups) { const groups = ( _groups.map(([handle, id, label, features, multiDiffEditorEnableViewChanges]) => { const group = ( new MainThreadSCMResourceGroup( this.handle, handle, this, features, label, id, multiDiffEditorEnableViewChanges, this._uriIdentService )); this._groupsByHandle[handle] = group; return group; })); this.groups.splice(this.groups.length, 0, ...groups); this._onDidChangeResourceGroups.fire(); } $updateGroup(handle, features) { const group = this._groupsByHandle[handle]; if (!group) { return; } group.$updateGroup(features); } $updateGroupLabel(handle, label) { const group = this._groupsByHandle[handle]; if (!group) { return; } group.$updateGroupLabel(label); } $spliceGroupResourceStates(splices) { for (const [groupHandle, groupSlices] of splices) { const group = this._groupsByHandle[groupHandle]; if (!group) { console.warn(`SCM group ${groupHandle} not found in provider ${this.label}`); continue; } groupSlices.reverse(); for (const [start, deleteCount, rawResources] of groupSlices) { const resources = ( rawResources.map(rawResource => { const [handle, sourceUri, icons, tooltip, strikeThrough, faded, contextValue, command, multiDiffEditorOriginalUri, multiDiffEditorModifiedUri] = rawResource; const [light, dark] = icons; const icon = ThemeIcon.isThemeIcon(light) ? light : URI.revive(light); const iconDark = (ThemeIcon.isThemeIcon(dark) ? dark : URI.revive(dark)) || icon; const decorations = { icon: icon, iconDark: iconDark, tooltip, strikeThrough, faded }; return ( new MainThreadSCMResource( this.proxy, this.handle, groupHandle, handle, URI.revive(sourceUri), group, decorations, contextValue || undefined, command, URI.revive(multiDiffEditorOriginalUri), URI.revive(multiDiffEditorModifiedUri) )); })); group.splice(start, deleteCount, resources); } } this._onDidChangeResources.fire(); } $unregisterGroup(handle) { const group = this._groupsByHandle[handle]; if (!group) { return; } delete this._groupsByHandle[handle]; this.groups.splice(this.groups.indexOf(group), 1); this._onDidChangeResourceGroups.fire(); } async getOriginalResource(uri) { if (!this.features.hasQuickDiffProvider) { return null; } const result = await this.proxy.$provideOriginalResource(this.handle, uri, CancellationToken.None); return result && URI.revive(result); } $onDidChangeHistoryProviderCurrentHistoryItemGroup(currentHistoryItemGroup) { if (!this.historyProvider.get()) { return; } this._historyProvider.get()?.$onDidChangeCurrentHistoryItemGroup(currentHistoryItemGroup); } toJSON() { return { $mid: MarshalledId.ScmProvider, handle: this.handle }; } dispose() { this._quickDiff?.dispose(); } } let MainThreadSCM = class MainThreadSCM { constructor(extHostContext, scmService, scmViewService, languageService, modelService, textModelService, quickDiffService, _uriIdentService, workspaceContextService) { this.scmService = scmService; this.scmViewService = scmViewService; this.languageService = languageService; this.modelService = modelService; this.textModelService = textModelService; this.quickDiffService = quickDiffService; this._uriIdentService = _uriIdentService; this.workspaceContextService = workspaceContextService; this._repositories = ( new Map()); this._repositoryBarriers = ( new Map()); this._repositoryDisposables = ( new Map()); this._disposables = ( new DisposableStore()); this._proxy = ( extHostContext.getProxy(ExtHostContext.ExtHostSCM)); this._disposables.add(( new SCMInputBoxContentProvider(this.textModelService, this.modelService, this.languageService))); } dispose() { dispose(( this._repositories.values())); this._repositories.clear(); dispose(( this._repositoryDisposables.values())); this._repositoryDisposables.clear(); this._disposables.dispose(); } async $registerSourceControl(handle, id, label, rootUri, inputBoxDocumentUri) { this._repositoryBarriers.set(handle, ( new Barrier())); const inputBoxTextModelRef = await this.textModelService.createModelReference(URI.revive(inputBoxDocumentUri)); const provider = ( new MainThreadSCMProvider( this._proxy, handle, id, label, rootUri ? URI.revive(rootUri) : undefined, inputBoxTextModelRef.object.textEditorModel, this.quickDiffService, this._uriIdentService, this.workspaceContextService )); const repository = this.scmService.registerSCMProvider(provider); this._repositories.set(handle, repository); const disposable = combinedDisposable(inputBoxTextModelRef, Event.filter(this.scmViewService.onDidFocusRepository, r => r === repository)(_ => this._proxy.$setSelectedSourceControl(handle)), repository.input.onDidChange(({ value }) => this._proxy.$onInputBoxValueChange(handle, value))); this._repositoryDisposables.set(handle, disposable); if (this.scmViewService.focusedRepository === repository) { setTimeout(() => this._proxy.$setSelectedSourceControl(handle), 0); } if (repository.input.value) { setTimeout(() => this._proxy.$onInputBoxValueChange(handle, repository.input.value), 0); } this._repositoryBarriers.get(handle)?.open(); } async $updateSourceControl(handle, features) { await this._repositoryBarriers.get(handle)?.wait(); const repository = this._repositories.get(handle); if (!repository) { return; } const provider = repository.provider; provider.$updateSourceControl(features); } async $unregisterSourceControl(handle) { await this._repositoryBarriers.get(handle)?.wait(); const repository = this._repositories.get(handle); if (!repository) { return; } this._repositoryDisposables.get(handle).dispose(); this._repositoryDisposables.delete(handle); repository.dispose(); this._repositories.delete(handle); } async $registerGroups(sourceControlHandle, groups, splices) { await this._repositoryBarriers.get(sourceControlHandle)?.wait(); const repository = this._repositories.get(sourceControlHandle); if (!repository) { return; } const provider = repository.provider; provider.$registerGroups(groups); provider.$spliceGroupResourceStates(splices); } async $updateGroup(sourceControlHandle, groupHandle, features) { await this._repositoryBarriers.get(sourceControlHandle)?.wait(); const repository = this._repositories.get(sourceControlHandle); if (!repository) { return; } const provider = repository.provider; provider.$updateGroup(groupHandle, features); } async $updateGroupLabel(sourceControlHandle, groupHandle, label) { await this._repositoryBarriers.get(sourceControlHandle)?.wait(); const repository = this._repositories.get(sourceControlHandle); if (!repository) { return; } const provider = repository.provider; provider.$updateGroupLabel(groupHandle, label); } async $spliceResourceStates(sourceControlHandle, splices) { await this._repositoryBarriers.get(sourceControlHandle)?.wait(); const repository = this._repositories.get(sourceControlHandle); if (!repository) { return; } const provider = repository.provider; provider.$spliceGroupResourceStates(splices); } async $unregisterGroup(sourceControlHandle, handle) { await this._repositoryBarriers.get(sourceControlHandle)?.wait(); const repository = this._repositories.get(sourceControlHandle); if (!repository) { return; } const provider = repository.provider; provider.$unregisterGroup(handle); } async $setInputBoxValue(sourceControlHandle, value) { await this._repositoryBarriers.get(sourceControlHandle)?.wait(); const repository = this._repositories.get(sourceControlHandle); if (!repository) { return; } repository.input.setValue(value, false); } async $setInputBoxPlaceholder(sourceControlHandle, placeholder) { await this._repositoryBarriers.get(sourceControlHandle)?.wait(); const repository = this._repositories.get(sourceControlHandle); if (!repository) { return; } repository.input.placeholder = placeholder; } async $setInputBoxEnablement(sourceControlHandle, enabled) { await this._repositoryBarriers.get(sourceControlHandle)?.wait(); const repository = this._repositories.get(sourceControlHandle); if (!repository) { return; } repository.input.enabled = enabled; } async $setInputBoxVisibility(sourceControlHandle, visible) { await this._repositoryBarriers.get(sourceControlHandle)?.wait(); const repository = this._repositories.get(sourceControlHandle); if (!repository) { return; } repository.input.visible = visible; } async $showValidationMessage(sourceControlHandle, message, type) { await this._repositoryBarriers.get(sourceControlHandle)?.wait(); const repository = this._repositories.get(sourceControlHandle); if (!repository) { return; } repository.input.showValidationMessage(message, type); } async $setValidationProviderIsEnabled(sourceControlHandle, enabled) { await this._repositoryBarriers.get(sourceControlHandle)?.wait(); const repository = this._repositories.get(sourceControlHandle); if (!repository) { return; } if (enabled) { repository.input.validateInput = async (value, pos) => { const result = await this._proxy.$validateInput(sourceControlHandle, value, pos); return result && { message: result[0], type: result[1] }; }; } else { repository.input.validateInput = async () => undefined; } } async $onDidChangeHistoryProviderCurrentHistoryItemGroup(sourceControlHandle, historyItemGroup) { await this._repositoryBarriers.get(sourceControlHandle)?.wait(); const repository = this._repositories.get(sourceControlHandle); if (!repository) { return; } const provider = repository.provider; provider.$onDidChangeHistoryProviderCurrentHistoryItemGroup(historyItemGroup); } }; MainThreadSCM = __decorate([ extHostNamedCustomer(MainContext.MainThreadSCM), ( __param(1, ISCMService)), ( __param(2, ISCMViewService)), ( __param(3, ILanguageService)), ( __param(4, IModelService)), ( __param(5, ITextModelService)), ( __param(6, IQuickDiffService)), ( __param(7, IUriIdentityService)), ( __param(8, IWorkspaceContextService)) ], MainThreadSCM); export { MainThreadSCM };