mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-27 12:04:04 +01:00
Clean up multi root labels (#102051)
* Change labels of URI's in multi-root workspaces to be
[RootName] • [Path From RootPaath to File]
rather than
[RootName] • [basename RootPath]/[Path From RootPath to File]
in cases where the root has an explicit name and
[RootName] • [Path From RootName to File]
in cases where the root's name is defaulted to basename
* Fixup cases where context added after path.
(073398241b)
* Remove unused
* Additional test case
This commit is contained in:
@@ -12,7 +12,7 @@ import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry, IWo
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IWorkspaceContextService, IWorkspace } from 'vs/platform/workspace/common/workspace';
|
||||
import { isEqual, basenameOrAuthority, basename, joinPath, dirname } from 'vs/base/common/resources';
|
||||
import { basenameOrAuthority, basename, joinPath, dirname } from 'vs/base/common/resources';
|
||||
import { tildify, getPathLabel } from 'vs/base/common/labels';
|
||||
import { IWorkspaceIdentifier, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, WORKSPACE_EXTENSION, toWorkspaceIdentifier, isWorkspaceIdentifier, isUntitledWorkspace } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { ILabelService, ResourceLabelFormatter, ResourceLabelFormatting, IFormatterChangeEvent } from 'vs/platform/label/common/label';
|
||||
@@ -141,21 +141,18 @@ export class LabelService extends Disposable implements ILabelService {
|
||||
const baseResource = this.contextService?.getWorkspaceFolder(resource);
|
||||
|
||||
if (options.relative && baseResource) {
|
||||
const rootName = baseResource?.name ?? basenameOrAuthority(baseResource.uri);
|
||||
const baseResourceLabel = this.formatUri(baseResource.uri, formatting, options.noPrefix);
|
||||
let relativeLabel = this.formatUri(resource, formatting, options.noPrefix);
|
||||
|
||||
let relativeLabel: string;
|
||||
if (isEqual(baseResource.uri, resource)) {
|
||||
relativeLabel = ''; // no label if resources are identical
|
||||
} else {
|
||||
const baseResourceLabel = this.formatUri(baseResource.uri, formatting, options.noPrefix);
|
||||
relativeLabel = this.formatUri(resource, formatting, options.noPrefix).substring(baseResourceLabel.lastIndexOf(formatting.separator) + 1);
|
||||
if (relativeLabel.startsWith(rootName)) {
|
||||
relativeLabel = relativeLabel.substring(rootName.length + (relativeLabel[rootName.length] === formatting.separator ? 1 : 0));
|
||||
}
|
||||
let overlap = 0;
|
||||
while (relativeLabel[overlap] && relativeLabel[overlap] === baseResourceLabel[overlap]) { overlap++; }
|
||||
if (!relativeLabel[overlap] || relativeLabel[overlap] === formatting.separator) {
|
||||
relativeLabel = relativeLabel.substring(1 + overlap);
|
||||
}
|
||||
|
||||
const hasMultipleRoots = this.contextService.getWorkspace().folders.length > 1;
|
||||
if (hasMultipleRoots && !options.noPrefix) {
|
||||
const rootName = baseResource?.name ?? basenameOrAuthority(baseResource.uri);
|
||||
relativeLabel = relativeLabel ? (rootName + ' • ' + relativeLabel) : rootName; // always show root basename if there are multiple
|
||||
}
|
||||
|
||||
|
||||
@@ -3,14 +3,15 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as resources from 'vs/base/common/resources';
|
||||
import * as assert from 'assert';
|
||||
import { TestEnvironmentService, TestPathService } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { LabelService } from 'vs/workbench/services/label/common/labelService';
|
||||
import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices';
|
||||
import { Workspace, WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
|
||||
suite('URI Label', () => {
|
||||
|
||||
let labelService: LabelService;
|
||||
|
||||
setup(() => {
|
||||
@@ -156,3 +157,75 @@ suite('URI Label', () => {
|
||||
assert.equal(labelService.getUriLabel(uri1, { relative: false }), 'LABEL: /END');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
suite('multi-root worksapce', () => {
|
||||
let labelService: LabelService;
|
||||
|
||||
setup(() => {
|
||||
const sources = URI.file('folder1/src');
|
||||
const tests = URI.file('folder1/test');
|
||||
const other = URI.file('folder2');
|
||||
|
||||
labelService = new LabelService(
|
||||
TestEnvironmentService,
|
||||
new TestContextService(
|
||||
new Workspace('test-workspaace', [
|
||||
new WorkspaceFolder({ uri: sources, index: 0, name: 'Sources' }, { uri: sources.toString() }),
|
||||
new WorkspaceFolder({ uri: tests, index: 1, name: 'Tests' }, { uri: tests.toString() }),
|
||||
new WorkspaceFolder({ uri: other, index: 2, name: resources.basename(other) }, { uri: other.toString() }),
|
||||
])),
|
||||
new TestPathService());
|
||||
});
|
||||
|
||||
test('labels of files in multiroot workspaces are the foldername folloed by offset from the folder', () => {
|
||||
labelService.registerFormatter({
|
||||
scheme: 'file',
|
||||
formatting: {
|
||||
label: '${authority}${path}',
|
||||
separator: '/',
|
||||
tildify: false,
|
||||
normalizeDriveLetter: false,
|
||||
authorityPrefix: '//',
|
||||
workspaceSuffix: ''
|
||||
}
|
||||
});
|
||||
|
||||
const tests = {
|
||||
'folder1/src/file': 'Sources • file',
|
||||
'folder1/src/folder/file': 'Sources • folder/file',
|
||||
'folder1/src': 'Sources',
|
||||
'folder1/other': '/folder1/other',
|
||||
'folder2/other': 'folder2 • other',
|
||||
};
|
||||
|
||||
Object.entries(tests).forEach(([path, label]) => {
|
||||
const generated = labelService.getUriLabel(URI.file(path), { relative: true });
|
||||
assert.equal(generated, label);
|
||||
});
|
||||
});
|
||||
|
||||
test('labels with context after path', () => {
|
||||
labelService.registerFormatter({
|
||||
scheme: 'file',
|
||||
formatting: {
|
||||
label: '${path} (${scheme})',
|
||||
separator: '/',
|
||||
}
|
||||
});
|
||||
|
||||
const tests = {
|
||||
'folder1/src/file': 'Sources • file (file)',
|
||||
'folder1/src/folder/file': 'Sources • folder/file (file)',
|
||||
'folder1/src': 'Sources',
|
||||
'folder1/other': '/folder1/other (file)',
|
||||
'folder2/other': 'folder2 • other (file)',
|
||||
};
|
||||
|
||||
Object.entries(tests).forEach(([path, label]) => {
|
||||
const generated = labelService.getUriLabel(URI.file(path), { relative: true });
|
||||
assert.equal(generated, label, path);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user