提交 55354382 编写于 作者: B Benjamin Pasero

implement getTitle/getDescription for untitled editors

上级 3d6f59a3
...@@ -51,6 +51,8 @@ interface IEditorInputLabel { ...@@ -51,6 +51,8 @@ interface IEditorInputLabel {
title?: string; title?: string;
} }
type AugmentedLabel = IEditorInputLabel & { editor: IEditorInput };
export class TabsTitleControl extends TitleControl { export class TabsTitleControl extends TitleControl {
private titleContainer: HTMLElement; private titleContainer: HTMLElement;
private tabsContainer: HTMLElement; private tabsContainer: HTMLElement;
...@@ -342,7 +344,6 @@ export class TabsTitleControl extends TitleControl { ...@@ -342,7 +344,6 @@ export class TabsTitleControl extends TitleControl {
const { verbosity, shortenDuplicates } = this.getSubtitleConfigFlags(tabSubtitleStyle); const { verbosity, shortenDuplicates } = this.getSubtitleConfigFlags(tabSubtitleStyle);
// Build labels and descriptions for each editor // Build labels and descriptions for each editor
type AugmentedLabel = IEditorInputLabel & { editor: IEditorInput };
const labels = editors.map(editor => ({ const labels = editors.map(editor => ({
editor, editor,
name: editor.getName(), name: editor.getName(),
...@@ -350,72 +351,81 @@ export class TabsTitleControl extends TitleControl { ...@@ -350,72 +351,81 @@ export class TabsTitleControl extends TitleControl {
title: editor.getTitle(Verbosity.LONG) title: editor.getTitle(Verbosity.LONG)
})); }));
// Shorten labels as needed
if (shortenDuplicates) { if (shortenDuplicates) {
// gather duplicate titles, while filtering out invalid descriptions this.shortenTabLabels(labels);
const mapTitleToDuplicates = new Map<string, AugmentedLabel[]>(); }
for (const label of labels) {
if (typeof label.description === 'string' && label.description) { return labels;
getOrSet(mapTitleToDuplicates, label.name, []).push(label); }
} else {
label.description = ''; private shortenTabLabels(labels: AugmentedLabel[]): void {
}
// Gather duplicate titles, while filtering out invalid descriptions
const mapTitleToDuplicates = new Map<string, AugmentedLabel[]>();
for (const label of labels) {
if (typeof label.description === 'string' && label.description) {
getOrSet(mapTitleToDuplicates, label.name, []).push(label);
} else {
label.description = '';
} }
}
// identify duplicate titles and shorten descriptions // Identify duplicate titles and shorten descriptions
mapTitleToDuplicates.forEach(duplicateTitles => { mapTitleToDuplicates.forEach(duplicateTitles => {
// remove description if the title isn't duplicated
if (duplicateTitles.length === 1) {
duplicateTitles[0].description = '';
return;
}
// identify duplicate descriptions // Remove description if the title isn't duplicated
const mapDescriptionToDuplicates = new Map<string, AugmentedLabel[]>(); if (duplicateTitles.length === 1) {
for (const label of duplicateTitles) { duplicateTitles[0].description = '';
getOrSet(mapDescriptionToDuplicates, label.description, []).push(label);
return;
}
// Identify duplicate descriptions
const mapDescriptionToDuplicates = new Map<string, AugmentedLabel[]>();
for (const label of duplicateTitles) {
getOrSet(mapDescriptionToDuplicates, label.description, []).push(label);
}
// For editors with duplicate descriptions, check whether any long descriptions differ
let useLongDescriptions = false;
mapDescriptionToDuplicates.forEach((duplicateDescriptions, name) => {
if (!useLongDescriptions && duplicateDescriptions.length > 1) {
const [first, ...rest] = duplicateDescriptions.map(({ editor }) => editor.getDescription(Verbosity.LONG));
useLongDescriptions = rest.some(description => description !== first);
} }
});
// for editors with duplicate descriptions, check whether any long descriptions differ // If so, replace all descriptions with long descriptions
let useLongDescriptions = false; if (useLongDescriptions) {
mapDescriptionToDuplicates.forEach((duplicateDescriptions, name) => { mapDescriptionToDuplicates.clear();
if (!useLongDescriptions && duplicateDescriptions.length > 1) { duplicateTitles.forEach(label => {
const [first, ...rest] = duplicateDescriptions.map(({ editor }) => editor.getDescription(Verbosity.LONG)); label.description = label.editor.getDescription(Verbosity.LONG);
useLongDescriptions = rest.some(description => description !== first); getOrSet(mapDescriptionToDuplicates, label.description, []).push(label);
}
}); });
}
// if so, replace all descriptions with long descriptions // Obtain final set of descriptions
if (useLongDescriptions) { const descriptions: string[] = [];
mapDescriptionToDuplicates.clear(); mapDescriptionToDuplicates.forEach((_, description) => descriptions.push(description));
duplicateTitles.forEach(label => {
label.description = label.editor.getDescription(Verbosity.LONG); // Remove description if all descriptions are identical
getOrSet(mapDescriptionToDuplicates, label.description, []).push(label); if (descriptions.length === 1) {
}); for (const label of mapDescriptionToDuplicates.get(descriptions[0])) {
label.description = '';
} }
// obtain final set of descriptions return;
const descriptions: string[] = []; }
mapDescriptionToDuplicates.forEach((_, description) => descriptions.push(description));
// remove description if all descriptions are identical // Shorten descriptions
if (descriptions.length === 1) { const shortenedDescriptions = shorten(descriptions);
for (const label of mapDescriptionToDuplicates.get(descriptions[0])) { descriptions.forEach((description, i) => {
label.description = ''; for (const label of mapDescriptionToDuplicates.get(description)) {
} label.description = shortenedDescriptions[i];
return;
} }
// shorten descriptions
const shortenedDescriptions = shorten(descriptions);
descriptions.forEach((description, i) => {
for (const label of mapDescriptionToDuplicates.get(description)) {
label.description = shortenedDescriptions[i];
}
});
}); });
} });
return labels;
} }
private getSubtitleConfigFlags(value: string) { private getSubtitleConfigFlags(value: string) {
......
...@@ -19,6 +19,7 @@ import Event, { Emitter } from 'vs/base/common/event'; ...@@ -19,6 +19,7 @@ import Event, { Emitter } from 'vs/base/common/event';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { telemetryURIDescriptor } from 'vs/platform/telemetry/common/telemetryUtils'; import { telemetryURIDescriptor } from 'vs/platform/telemetry/common/telemetryUtils';
import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { Verbosity } from 'vs/platform/editor/common/editor';
/** /**
* An editor input to be used for untitled text buffers. * An editor input to be used for untitled text buffers.
...@@ -36,6 +37,14 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport ...@@ -36,6 +37,14 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport
private toUnbind: IDisposable[]; private toUnbind: IDisposable[];
private shortDescription: string;
private mediumDescription: string;
private longDescription: string;
private shortTitle: string;
private mediumTitle: string;
private longTitle: string;
constructor( constructor(
private resource: URI, private resource: URI,
hasAssociatedFilePath: boolean, hasAssociatedFilePath: boolean,
...@@ -88,8 +97,47 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport ...@@ -88,8 +97,47 @@ export class UntitledEditorInput extends EditorInput implements IEncodingSupport
return this.hasAssociatedFilePath ? paths.basename(this.resource.fsPath) : this.resource.fsPath; return this.hasAssociatedFilePath ? paths.basename(this.resource.fsPath) : this.resource.fsPath;
} }
public getDescription(): string { public getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string {
return this.hasAssociatedFilePath ? labels.getPathLabel(paths.dirname(this.resource.fsPath), this.contextService, this.environmentService) : null; if (!this.hasAssociatedFilePath) {
return null;
}
let description: string;
switch (verbosity) {
case Verbosity.SHORT:
description = this.shortDescription ? this.shortDescription : (this.shortDescription = paths.basename(labels.getPathLabel(paths.dirname(this.resource.fsPath), void 0, this.environmentService)));
break;
case Verbosity.LONG:
description = this.longDescription ? this.longDescription : (this.longDescription = labels.getPathLabel(paths.dirname(this.resource.fsPath), void 0, this.environmentService));
break;
case Verbosity.MEDIUM:
default:
description = this.mediumDescription ? this.mediumDescription : (this.mediumDescription = labels.getPathLabel(paths.dirname(this.resource.fsPath), this.contextService, this.environmentService));
break;
}
return description;
}
public getTitle(verbosity: Verbosity): string {
if (!this.hasAssociatedFilePath) {
return this.getName();
}
let title: string;
switch (verbosity) {
case Verbosity.SHORT:
title = this.shortTitle ? this.shortTitle : (this.shortTitle = this.getName());
break;
case Verbosity.MEDIUM:
title = this.mediumTitle ? this.mediumTitle : (this.mediumTitle = labels.getPathLabel(this.resource, this.contextService, this.environmentService));
break;
case Verbosity.LONG:
title = this.longTitle ? this.longTitle : (this.longTitle = labels.getPathLabel(this.resource, void 0, this.environmentService));
break;
}
return title;
} }
public isDirty(): boolean { public isDirty(): boolean {
......
...@@ -131,24 +131,21 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput { ...@@ -131,24 +131,21 @@ export class FileEditorInput extends EditorInput implements IFileEditorInput {
} }
public getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string { public getDescription(verbosity: Verbosity = Verbosity.MEDIUM): string {
let description: string;
switch (verbosity) { switch (verbosity) {
case Verbosity.SHORT: case Verbosity.SHORT:
if (!this.shortDescription) { description = this.shortDescription ? this.shortDescription : (this.shortDescription = paths.basename(labels.getPathLabel(paths.dirname(this.resource.fsPath), void 0, this.environmentService)));
this.shortDescription = paths.basename(labels.getPathLabel(paths.dirname(this.resource.fsPath), void 0, this.environmentService)); break;
}
return this.shortDescription;
case Verbosity.LONG: case Verbosity.LONG:
if (!this.longDescription) { description = this.longDescription ? this.longDescription : (this.longDescription = labels.getPathLabel(paths.dirname(this.resource.fsPath), void 0, this.environmentService));
this.longDescription = labels.getPathLabel(paths.dirname(this.resource.fsPath), void 0, this.environmentService); break;
}
return this.longDescription;
case Verbosity.MEDIUM: case Verbosity.MEDIUM:
default: default:
if (!this.mediumDescription) { description = this.mediumDescription ? this.mediumDescription : (this.mediumDescription = labels.getPathLabel(paths.dirname(this.resource.fsPath), this.contextService, this.environmentService));
this.mediumDescription = labels.getPathLabel(paths.dirname(this.resource.fsPath), this.contextService, this.environmentService); break;
}
return this.mediumDescription;
} }
return description;
} }
public getTitle(verbosity: Verbosity): string { public getTitle(verbosity: Verbosity): string {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册