From 7651c9459bf48503b95bce562cf4c8b53bc9e56f Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Tue, 19 Jul 2022 18:32:52 +0200 Subject: [PATCH 1/3] Initial implementation of the label provider --- src/vs/platform/label/common/label.ts | 2 +- .../workbench/contrib/scm/browser/activity.ts | 47 +++++++++++++++++++ .../contrib/scm/browser/scm.contribution.ts | 5 +- .../services/label/common/labelService.ts | 47 ++++++++++--------- 4 files changed, 76 insertions(+), 25 deletions(-) diff --git a/src/vs/platform/label/common/label.ts b/src/vs/platform/label/common/label.ts index e5b6b8a10458b2..b9ee570c43e633 100644 --- a/src/vs/platform/label/common/label.ts +++ b/src/vs/platform/label/common/label.ts @@ -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; diff --git a/src/vs/workbench/contrib/scm/browser/activity.ts b/src/vs/workbench/contrib/scm/browser/activity.ts index 75929726a57a90..828b538658b480 100644 --- a/src/vs/workbench/contrib/scm/browser/activity.ts +++ b/src/vs/workbench/contrib/scm/browser/activity.ts @@ -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 = '/'; + + label = (resource: URI) => { + const match = /git\/(?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) + }); + } +} diff --git a/src/vs/workbench/contrib/scm/browser/scm.contribution.ts b/src/vs/workbench/contrib/scm/browser/scm.contribution.ts index 956e867a21f20a..6c0ceafb8ace0c 100644 --- a/src/vs/workbench/contrib/scm/browser/scm.contribution.ts +++ b/src/vs/workbench/contrib/scm/browser/scm.contribution.ts @@ -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(WorkbenchExtensions.Workbench) Registry.as(WorkbenchExtensions.Workbench) .registerWorkbenchContribution(SCMStatusController, LifecyclePhase.Restored); +Registry.as(WorkbenchExtensions.Workbench) + .registerWorkbenchContribution(SCMInputTextDocumentContribution, LifecyclePhase.Restored); + Registry.as(ConfigurationExtensions.Configuration).registerConfiguration({ id: 'scm', order: 5, diff --git a/src/vs/workbench/services/label/common/labelService.ts b/src/vs/workbench/services/label/common/labelService.ts index 4135a251e94852..b680533dabc366 100644 --- a/src/vs/workbench/services/label/common/labelService.ts +++ b/src/vs/workbench/services/label/common/labelService.ts @@ -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)) { From 6b4664487225d10c0f91d0c6f0020f938608bd4b Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Tue, 19 Jul 2022 18:44:46 +0200 Subject: [PATCH 2/3] Add test --- .../services/label/test/browser/label.test.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/vs/workbench/services/label/test/browser/label.test.ts b/src/vs/workbench/services/label/test/browser/label.test.ts index 745055c930ef1e..338660d225b2b8 100644 --- a/src/vs/workbench/services/label/test/browser/label.test.ts +++ b/src/vs/workbench/services/label/test/browser/label.test.ts @@ -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); From 830be10bcecd1b182a883f3f4f97c48a3ece3e82 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Tue, 19 Jul 2022 22:26:08 +0200 Subject: [PATCH 3/3] Update src/vs/workbench/contrib/scm/browser/activity.ts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: João Moreno --- src/vs/workbench/contrib/scm/browser/activity.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/scm/browser/activity.ts b/src/vs/workbench/contrib/scm/browser/activity.ts index 828b538658b480..57e7afbf13a9cb 100644 --- a/src/vs/workbench/contrib/scm/browser/activity.ts +++ b/src/vs/workbench/contrib/scm/browser/activity.ts @@ -281,7 +281,7 @@ class SCMInputTextDocumentLabelFormatter { readonly separator = '/'; - label = (resource: URI) => { + readonly label = (resource: URI) => { const match = /git\/(?scm[\d+])\/input/i.exec(resource.path); if (match?.groups === undefined) {