uriDisplayService with tests

This commit is contained in:
isidor 2018-07-26 17:25:38 +02:00
parent 742767ef9c
commit 501156e3c2
2 changed files with 90 additions and 32 deletions

View file

@ -12,6 +12,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'
import { isEqual, basenameOrAuthority } from 'vs/base/common/resources';
import { isLinux, isWindows } from 'vs/base/common/platform';
import { tildify, normalizeDriveLetter } from 'vs/base/common/labels';
import { ltrim } from 'vs/base/common/strings';
export interface IUriDisplayService {
_serviceBrand: any;
@ -21,18 +22,20 @@ export interface IUriDisplayService {
export interface UriDisplayRules {
label: string; // myLabel:/${path}
separator: '/' | '\\' | undefined;
separator: '/' | '\\' | '';
tildify?: boolean;
normalizeDriveLetter?: boolean;
}
const URI_DISPLAY_SERVICE_ID = 'uriDisplay';
const sepRegexp = /\//g;
const labelMatchingRegexp = /\$\{scheme\}|\$\{authority\}|\$\{path\}/g;
function hasDriveLetter(path: string): boolean {
return isWindows && path && path[1] === ':';
}
class UriDisplayService implements IUriDisplayService {
export class UriDisplayService implements IUriDisplayService {
_serviceBrand: any;
private formaters = new Map<string, UriDisplayRules>();
@ -46,28 +49,33 @@ class UriDisplayService implements IUriDisplayService {
if (!resource) {
return undefined;
}
if (relative) {
const hasMultipleRoots = this.contextService.getWorkspace().folders.length > 1;
const baseResource = this.contextService.getWorkspaceFolder(resource);
let pathLabel: string;
if (isEqual(baseResource.uri, resource, !isLinux)) {
pathLabel = ''; // no label if paths are identical
} else {
const baseResourceLabel = this.formatUri(baseResource.uri);
pathLabel = this.formatUri(resource).substring(baseResourceLabel.length);
}
if (hasMultipleRoots) {
const rootName = (baseResource && baseResource.name) ? baseResource.name : basenameOrAuthority(baseResource.uri);
pathLabel = pathLabel ? (rootName + ' • ' + pathLabel) : rootName; // always show root basename if there are multiple
}
return pathLabel;
const formater = this.formaters.get(resource.scheme);
if (!formater) {
return resource.with({ query: null, fragment: null }).toString(true);
}
return this.formatUri(resource);
if (relative) {
const baseResource = this.contextService.getWorkspaceFolder(resource);
if (baseResource) {
let relativeLabel: string;
if (isEqual(baseResource.uri, resource, !isLinux)) {
relativeLabel = ''; // no label if resources are identical
} else {
const baseResourceLabel = this.formatUri(baseResource.uri, formater);
relativeLabel = ltrim(this.formatUri(resource, formater).substring(baseResourceLabel.length), formater.separator);
}
const hasMultipleRoots = this.contextService.getWorkspace().folders.length > 1;
if (hasMultipleRoots) {
const rootName = (baseResource && baseResource.name) ? baseResource.name : basenameOrAuthority(baseResource.uri);
relativeLabel = relativeLabel ? (rootName + ' • ' + relativeLabel) : rootName; // always show root basename if there are multiple
}
return relativeLabel;
}
}
return this.formatUri(resource, formater);
}
registerFormater(scheme: string, formater: UriDisplayRules): IDisposable {
@ -78,26 +86,26 @@ class UriDisplayService implements IUriDisplayService {
};
}
private formatUri(resource: URI): string {
const formater = this.formaters.get(resource.scheme);
if (!formater) {
return resource.with({ query: null, fragment: null }).toString(true);
}
// TODO@isidor transform
let label = resource.path;
private formatUri(resource: URI, formater: UriDisplayRules): string {
let label = formater.label.replace(labelMatchingRegexp, match => {
switch (match) {
case '${scheme}': return resource.scheme;
case '${authority}': return resource.authority;
case '${path}': return resource.path;
default: return '';
}
});
// convert c:\something => C:\something
if (formater.normalizeDriveLetter && hasDriveLetter(label)) {
label = normalizeDriveLetter(label);
}
// normalize and tildify (macOS, Linux only)
if (formater.tildify) {
label = tildify(label, this.environmentService.userHome);
}
return label;
return label.replace(sepRegexp, formater.separator);
}
}

View file

@ -0,0 +1,50 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { IUriDisplayService, UriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay';
import { TestEnvironmentService, TestContextService } from 'vs/workbench/test/workbenchTestServices';
import { Schemas } from 'vs/base/common/network';
import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace';
import URI from 'vs/base/common/uri';
import { nativeSep } from 'vs/base/common/paths';
import { isWindows } from 'vs/base/common/platform';
suite('URI Display', () => {
let uriDisplayService: IUriDisplayService;
setup(() => {
uriDisplayService = new UriDisplayService(TestEnvironmentService, new TestContextService());
});
test('file scheme', function () {
uriDisplayService.registerFormater(Schemas.file, {
label: '${path}',
separator: nativeSep,
tildify: !isWindows,
normalizeDriveLetter: isWindows
});
const uri1 = TestWorkspace.folders[0].uri.with({ path: TestWorkspace.folders[0].uri.path.concat('/a/b/c/d') });
assert.equal(uriDisplayService.getLabel(uri1, true), isWindows ? 'a\\b\\c\\d' : 'a/b/c/d');
assert.equal(uriDisplayService.getLabel(uri1, false), isWindows ? '\\testWorkspace\\a\\b\\c\\d' : '/testWorkspace/a/b/c/d');
const uri2 = URI.file('c:\\1/2/3');
assert.equal(uriDisplayService.getLabel(uri2, false), isWindows ? 'C:\\1\\2\\3' : '/c:\\1/2/3');
});
test('custom scheme', function () {
uriDisplayService.registerFormater(Schemas.vscode, {
label: 'LABEL/${path}/${authority}/END',
separator: '/',
tildify: true,
normalizeDriveLetter: true
});
const uri1 = URI.parse('vscode://microsoft.com/1/2/3/4/5');
assert.equal(uriDisplayService.getLabel(uri1, false), 'LABEL//1/2/3/4/5/microsoft.com/END');
});
});