Cannot distinguish different files with the same path.filename(x) (fixes #8499)
This commit is contained in:
parent
6df36e50f2
commit
be4b9711f6
|
@ -9,7 +9,6 @@ import platform = require('vs/base/common/platform');
|
|||
import types = require('vs/base/common/types');
|
||||
import strings = require('vs/base/common/strings');
|
||||
import paths = require('vs/base/common/paths');
|
||||
import {LinkedMap} from 'vs/base/common/map';
|
||||
|
||||
export interface ILabelProvider {
|
||||
|
||||
|
@ -71,34 +70,4 @@ function getPath(arg1: URI | string | IWorkspaceProvider): string {
|
|||
}
|
||||
|
||||
return (<URI>arg1).fsPath;
|
||||
}
|
||||
|
||||
export interface IPathLabel {
|
||||
resource: URI;
|
||||
label: string;
|
||||
meta?: string;
|
||||
}
|
||||
|
||||
export function getPathLabels(resources: URI[], provider?: IWorkspaceProvider): LinkedMap<URI, IPathLabel> {
|
||||
const labels = new LinkedMap<URI, IPathLabel>();
|
||||
const mapLabelToDuplicates = new LinkedMap<string, IPathLabel[]>();
|
||||
|
||||
resources.forEach(resource => {
|
||||
const item = { resource, label: paths.basename(resource.fsPath) };
|
||||
labels.set(resource, item);
|
||||
|
||||
const duplicates = mapLabelToDuplicates.getOrSet(item.label, []);
|
||||
duplicates.push(item);
|
||||
});
|
||||
|
||||
const duplicates = mapLabelToDuplicates.values();
|
||||
duplicates.forEach(duplicates => {
|
||||
if (duplicates.length > 1) {
|
||||
duplicates.forEach(duplicate => {
|
||||
duplicate.meta = getPathLabel(paths.dirname(duplicate.resource.fsPath), provider);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return labels;
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
import * as assert from 'assert';
|
||||
import {getPathLabels} from 'vs/base/common/labels';
|
||||
import uri from 'vs/base/common/uri';
|
||||
|
||||
suite('Labels', () => {
|
||||
|
||||
test('getPathLabels - no collisions', () => {
|
||||
const uris = [
|
||||
uri.file('/parentA/childA.txt'),
|
||||
uri.file('/parentA/childB.txt'),
|
||||
uri.file('/parentA/other/childC.txt')
|
||||
];
|
||||
|
||||
const res = getPathLabels(uris).values();
|
||||
assert.equal(res.length, 3);
|
||||
assert.equal(res[0].label, 'childA.txt');
|
||||
assert.ok(!res[0].meta);
|
||||
assert.equal(res[1].label, 'childB.txt');
|
||||
assert.ok(!res[1].meta);
|
||||
assert.equal(res[2].label, 'childC.txt');
|
||||
assert.ok(!res[2].meta);
|
||||
});
|
||||
|
||||
test('getPathLabels - collisions', () => {
|
||||
const uris = [
|
||||
uri.file('/parentA/childA.txt'),
|
||||
uri.file('/parentB/childA.txt'),
|
||||
uri.file('/parentC/other/childA.txt')
|
||||
];
|
||||
|
||||
const res = getPathLabels(uris).values();
|
||||
assert.equal(res.length, 3);
|
||||
assert.equal(res[0].label, 'childA.txt');
|
||||
assert.equal(res[0].meta, '/parentA');
|
||||
assert.equal(res[1].label, 'childA.txt');
|
||||
assert.equal(res[1].meta, '/parentB');
|
||||
assert.equal(res[2].label, 'childA.txt');
|
||||
assert.equal(res[2].meta, '/parentC/other');
|
||||
});
|
||||
});
|
|
@ -35,22 +35,6 @@
|
|||
padding-left: 2px;
|
||||
}
|
||||
|
||||
/* Title Description */
|
||||
|
||||
.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-label span {
|
||||
margin-left: 0.5em;
|
||||
font-size: 0.9em;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-label span {
|
||||
color: rgba(108, 108, 108, 0.7);
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-label span {
|
||||
color: rgba(204, 204, 204, 0.7);
|
||||
}
|
||||
|
||||
/* Title Actions */
|
||||
.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-actions {
|
||||
display: flex;
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-label span {
|
||||
.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-label span,
|
||||
.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab .tab-label span {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
@ -48,6 +49,24 @@
|
|||
color: white;
|
||||
}
|
||||
|
||||
/* Title Description */
|
||||
|
||||
.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab .tab-label span,
|
||||
.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-label span {
|
||||
margin-left: 0.5em;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab .tab-label span,
|
||||
.vs .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-label span {
|
||||
color: rgba(108, 108, 108, 0.7);
|
||||
}
|
||||
|
||||
.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .tabs-container > .tab .tab-label span,
|
||||
.vs-dark .monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-label span {
|
||||
color: rgba(204, 204, 204, 0.7);
|
||||
}
|
||||
|
||||
/* Title Actions */
|
||||
|
||||
.monaco-workbench > .part.editor > .content > .one-editor-silo > .container > .title .title-actions .action-label,
|
||||
|
|
|
@ -12,7 +12,7 @@ import DOM = require('vs/base/browser/dom');
|
|||
import {isMacintosh} from 'vs/base/common/platform';
|
||||
import {MIME_BINARY} from 'vs/base/common/mime';
|
||||
import {Position} from 'vs/platform/editor/common/editor';
|
||||
import {IEditorGroup, IEditorIdentifier, asFileEditorInput} from 'vs/workbench/common/editor';
|
||||
import {IEditorGroup, IEditorIdentifier, asFileEditorInput, getUniqueLabels} from 'vs/workbench/common/editor';
|
||||
import {StandardKeyboardEvent} from 'vs/base/browser/keyboardEvent';
|
||||
import {CommonKeybindings as Kb, KeyCode} from 'vs/base/common/keyCodes';
|
||||
import {ActionBar} from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
|
@ -178,23 +178,37 @@ export class TabsTitleControl extends TitleControl {
|
|||
DOM.removeClass(this.titleContainer, 'active');
|
||||
}
|
||||
|
||||
// Compute labels and protect against duplicates
|
||||
const editorsOfGroup = this.context.getEditors();
|
||||
const labels = getUniqueLabels(editorsOfGroup);
|
||||
|
||||
// Tab label and styles
|
||||
this.context.getEditors().forEach((editor, index) => {
|
||||
editorsOfGroup.forEach((editor, index) => {
|
||||
const tabContainer = this.tabsContainer.children[index];
|
||||
if (tabContainer instanceof HTMLElement) {
|
||||
const tabLabel = <HTMLAnchorElement>(<HTMLElement>tabContainer.children[0]).children[0];
|
||||
const tabLabelsContainer = <HTMLElement>tabContainer.children[0];
|
||||
const tabLabel = <HTMLAnchorElement>tabLabelsContainer.children[0];
|
||||
const tabDescription = <HTMLSpanElement>tabLabelsContainer.children[1];
|
||||
|
||||
const isPinned = group.isPinned(editor);
|
||||
const isActive = group.isActive(editor);
|
||||
const isDirty = editor.isDirty();
|
||||
|
||||
const description = editor.getDescription(true) || '';
|
||||
const name = editor.getName();
|
||||
const label = labels[index];
|
||||
const name = label.name;
|
||||
const description = label.hasAmbiguosName && label.description ? label.description : '';
|
||||
const verboseDescription = label.verboseDescription || '';
|
||||
|
||||
// Label & Description
|
||||
tabContainer.setAttribute('aria-label', `tab, ${name}`);
|
||||
tabContainer.title = description;
|
||||
tabContainer.title = verboseDescription;
|
||||
tabLabel.innerText = name;
|
||||
tabDescription.innerText = description;
|
||||
if (description) {
|
||||
DOM.show(tabDescription);
|
||||
} else {
|
||||
DOM.hide(tabDescription);
|
||||
}
|
||||
|
||||
// Pinned state
|
||||
if (isPinned) {
|
||||
|
@ -280,6 +294,10 @@ export class TabsTitleControl extends TitleControl {
|
|||
const tabLabel = document.createElement('a');
|
||||
tabLabelContainer.appendChild(tabLabel);
|
||||
|
||||
// Tab Description
|
||||
const tabDescription = document.createElement('span');
|
||||
tabLabelContainer.appendChild(tabDescription);
|
||||
|
||||
// Tab Close
|
||||
const tabCloseContainer = document.createElement('div');
|
||||
DOM.addClass(tabCloseContainer, 'tab-close');
|
||||
|
|
|
@ -16,6 +16,7 @@ import {Event as BaseEvent} from 'vs/base/common/events';
|
|||
import {IEditorGroupService} from 'vs/workbench/services/group/common/groupService';
|
||||
import {SyncDescriptor, AsyncDescriptor} from 'vs/platform/instantiation/common/descriptors';
|
||||
import {IInstantiationService, IConstructorSignature0} from 'vs/platform/instantiation/common/instantiation';
|
||||
import {LinkedMap} from 'vs/base/common/map';
|
||||
|
||||
export enum ConfirmResult {
|
||||
SAVE,
|
||||
|
@ -844,4 +845,35 @@ export interface ActiveEditorMoveArguments {
|
|||
|
||||
export var EditorCommands = {
|
||||
MoveActiveEditor: 'moveActiveEditor'
|
||||
};
|
||||
};
|
||||
|
||||
export interface IEditorInputLabel {
|
||||
name: string;
|
||||
hasAmbiguosName?: boolean;
|
||||
description?: string;
|
||||
verboseDescription?: string;
|
||||
}
|
||||
|
||||
export function getUniqueLabels(editors: IEditorInput[]): IEditorInputLabel[] {
|
||||
const labels: IEditorInputLabel[] = [];
|
||||
const mapLabelToDuplicates = new LinkedMap<string, IEditorInputLabel[]>();
|
||||
|
||||
editors.forEach(editor => {
|
||||
const item:IEditorInputLabel = { name: editor.getName(), description: editor.getDescription(), verboseDescription: editor.getDescription(true) };
|
||||
labels.push(item);
|
||||
|
||||
const duplicates = mapLabelToDuplicates.getOrSet(item.name, []);
|
||||
duplicates.push(item);
|
||||
});
|
||||
|
||||
const duplicates = mapLabelToDuplicates.values();
|
||||
duplicates.forEach(duplicates => {
|
||||
if (duplicates.length > 1) {
|
||||
duplicates.forEach(duplicate => {
|
||||
duplicate.hasAmbiguosName = true;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return labels;
|
||||
}
|
Loading…
Reference in a new issue