@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
JavaScript
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 };