LabelService - custom formatter function (#155641)

This commit is contained in:
Ladislau Szomoru 2022-07-20 10:42:00 +02:00 committed by GitHub
parent 0a8e619cfe
commit 28c40a970f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 88 additions and 25 deletions

View file

@ -51,7 +51,7 @@ export interface ResourceLabelFormatter {
}
export interface ResourceLabelFormatting {
label: string; // myLabel:/${path}
label: string | ((resource: URI) => string); // myLabel:/${path}
separator: '/' | '\\' | '';
tildify?: boolean;
normalizeDriveLetter?: boolean;

View file

@ -19,6 +19,10 @@ import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'
import { stripIcons } from 'vs/base/common/iconLabels';
import { Schemas } from 'vs/base/common/network';
import { Iterable } from 'vs/base/common/iterator';
import { ILabelService } from 'vs/platform/label/common/label';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { URI } from 'vs/base/common/uri';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
function getCount(repository: ISCMRepository): number {
if (typeof repository.provider.count === 'number') {
@ -272,3 +276,46 @@ export class SCMActiveResourceContextKeyController implements IWorkbenchContribu
this.repositoryDisposables.clear();
}
}
class SCMInputTextDocumentLabelFormatter {
readonly separator = '/';
readonly label = (resource: URI) => {
const match = /git\/(?<repositoryId>scm[\d+])\/input/i.exec(resource.path);
if (match?.groups === undefined) {
return resource.toString();
}
const { repositoryId } = match.groups;
const repository = this.scmService.getRepository(repositoryId);
if (repository === undefined || repository.provider.rootUri === undefined) {
return resource.toString();
}
const folder = this.workspaceContextService.getWorkspaceFolder(repository.provider.rootUri);
const repositoryName = folder?.uri.toString() === repository.provider.rootUri.toString() ? folder.name : basename(repository.provider.rootUri);
return `${repositoryName} (${repository.provider.label})`;
};
constructor(
@ISCMService private readonly scmService: ISCMService,
@IWorkspaceContextService private workspaceContextService: IWorkspaceContextService,
) { }
}
export class SCMInputTextDocumentContribution implements IWorkbenchContribution {
constructor(
@IInstantiationService instantiationService: IInstantiationService,
@ILabelService labelService: ILabelService
) {
labelService.registerFormatter({
scheme: Schemas.vscode,
authority: 'scm',
formatting: instantiationService.createInstance(SCMInputTextDocumentLabelFormatter)
});
}
}

View file

@ -10,7 +10,7 @@ import { DirtyDiffWorkbenchController } from './dirtydiffDecorator';
import { VIEWLET_ID, ISCMService, VIEW_PANE_ID, ISCMProvider, ISCMViewService, REPOSITORIES_VIEW_PANE_ID } from 'vs/workbench/contrib/scm/common/scm';
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
import { SCMActiveResourceContextKeyController, SCMStatusController } from './activity';
import { SCMActiveResourceContextKeyController, SCMInputTextDocumentContribution, SCMStatusController } from './activity';
import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
import { IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
@ -115,6 +115,9 @@ Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench)
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench)
.registerWorkbenchContribution(SCMStatusController, LifecyclePhase.Restored);
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench)
.registerWorkbenchContribution(SCMInputTextDocumentContribution, LifecyclePhase.Restored);
Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).registerConfiguration({
id: 'scm',
order: 5,

View file

@ -402,32 +402,33 @@ export class LabelService extends Disposable implements ILabelService {
}
private formatUri(resource: URI, formatting: ResourceLabelFormatting, forceNoTildify?: boolean): string {
let label = formatting.label.replace(labelMatchingRegexp, (match, token, qsToken, qsValue) => {
switch (token) {
case 'scheme': return resource.scheme;
case 'authority': return resource.authority;
case 'authoritySuffix': {
const i = resource.authority.indexOf('+');
return i === -1 ? resource.authority : resource.authority.slice(i + 1);
}
case 'path':
return formatting.stripPathStartingSeparator
? resource.path.slice(resource.path[0] === formatting.separator ? 1 : 0)
: resource.path;
default: {
if (qsToken === 'query') {
const { query } = resource;
if (query && query[0] === '{' && query[query.length - 1] === '}') {
try {
return JSON.parse(query)[qsValue] || '';
} catch { }
}
let label = typeof formatting.label !== 'string' ? formatting.label(resource) :
formatting.label.replace(labelMatchingRegexp, (match, token, qsToken, qsValue) => {
switch (token) {
case 'scheme': return resource.scheme;
case 'authority': return resource.authority;
case 'authoritySuffix': {
const i = resource.authority.indexOf('+');
return i === -1 ? resource.authority : resource.authority.slice(i + 1);
}
case 'path':
return formatting.stripPathStartingSeparator
? resource.path.slice(resource.path[0] === formatting.separator ? 1 : 0)
: resource.path;
default: {
if (qsToken === 'query') {
const { query } = resource;
if (query && query[0] === '{' && query[query.length - 1] === '}') {
try {
return JSON.parse(query)[qsValue] || '';
} catch { }
}
}
return '';
return '';
}
}
}
});
});
// convert \c:\something => C:\something
if (formatting.normalizeDriveLetter && hasDriveLetterIgnorePlatform(label)) {

View file

@ -164,6 +164,18 @@ suite('URI Label', () => {
assert.strictEqual(labelService.getUriLabel(uri1, { relative: false }), 'LABEL: /END');
});
test('custom formatting function', function () {
labelService.registerFormatter({
scheme: 'vscode',
formatting: {
label: (resource) => { return resource.toString(); },
separator: '/',
}
});
const uri1 = URI.parse('vscode://microsoft.com/1/2/3/4/5');
assert.strictEqual(labelService.getUriLabel(uri1), uri1.toString());
});
test('label caching', () => {
const m = new Memento('cachedResourceLabelFormatters', storageService).getMemento(StorageScope.PROFILE, StorageTarget.MACHINE);