提交 249a796a 编写于 作者: B Benjamin Pasero

introduce and use getBaseLabel()

上级 b520c8f1
......@@ -11,7 +11,7 @@ import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlighte
import { IMatch } from 'vs/base/common/filters';
import uri from 'vs/base/common/uri';
import paths = require('vs/base/common/paths');
import { IWorkspaceFolderProvider, getPathLabel, IUserHomeProvider } from 'vs/base/common/labels';
import { IWorkspaceFolderProvider, getPathLabel, IUserHomeProvider, getBaseLabel } from 'vs/base/common/labels';
import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
export interface IIconLabelCreationOptions {
......@@ -163,6 +163,6 @@ export class FileLabel extends IconLabel {
public setFile(file: uri, provider: IWorkspaceFolderProvider, userHome: IUserHomeProvider): void {
const parent = paths.dirname(file.fsPath);
this.setValue(paths.basename(file.fsPath), parent && parent !== '.' ? getPathLabel(parent, provider, userHome) : '', { title: file.fsPath });
this.setValue(getBaseLabel(file), parent && parent !== '.' ? getPathLabel(parent, provider, userHome) : '', { title: file.fsPath });
}
}
......@@ -6,7 +6,7 @@
import URI from 'vs/base/common/uri';
import platform = require('vs/base/common/platform');
import { nativeSep, normalize, isEqualOrParent, isEqual, basename, join } from 'vs/base/common/paths';
import { nativeSep, normalize, isEqualOrParent, isEqual, basename as pathsBasename, join } from 'vs/base/common/paths';
import { endsWith, ltrim } from 'vs/base/common/strings';
export interface IWorkspaceFolderProvider {
......@@ -46,7 +46,7 @@ export function getPathLabel(resource: URI | string, rootProvider?: IWorkspaceFo
}
if (hasMultipleRoots) {
const rootName = basename(baseResource.uri.fsPath);
const rootName = pathsBasename(baseResource.uri.fsPath);
pathLabel = pathLabel ? join(rootName, pathLabel) : rootName; // always show root basename if there are multiple
}
......@@ -67,6 +67,26 @@ export function getPathLabel(resource: URI | string, rootProvider?: IWorkspaceFo
return res;
}
export function getBaseLabel(resource: URI | string): string {
if (!resource) {
return null;
}
if (typeof resource === 'string') {
resource = URI.file(resource);
}
let base = pathsBasename(resource.fsPath);
// Windows: basename('C:\') returns empty string, so make sure to always
// return the drive letter at least in that case.
if (!base) {
base = normalize(normalizeDriveLetter(resource.fsPath), true);
}
return base;
}
function hasDriveLetter(path: string): boolean {
return platform.isWindows && path && path[1] === ':';
}
......
......@@ -112,23 +112,23 @@ export function guessMimeTypes(path: string, firstLine?: string): string[] {
}
path = path.toLowerCase();
let filename = paths.basename(path);
const filename = paths.basename(path);
// 1.) User configured mappings have highest priority
let configuredMime = guessMimeTypeByPath(path, filename, userRegisteredAssociations);
const configuredMime = guessMimeTypeByPath(path, filename, userRegisteredAssociations);
if (configuredMime) {
return [configuredMime, MIME_TEXT];
}
// 2.) Registered mappings have middle priority
let registeredMime = guessMimeTypeByPath(path, filename, nonUserRegisteredAssociations);
const registeredMime = guessMimeTypeByPath(path, filename, nonUserRegisteredAssociations);
if (registeredMime) {
return [registeredMime, MIME_TEXT];
}
// 3.) Firstline has lowest priority
if (firstLine) {
let firstlineMime = guessMimeTypeByFirstline(firstLine);
const firstlineMime = guessMimeTypeByFirstline(firstLine);
if (firstlineMime) {
return [firstlineMime, MIME_TEXT];
}
......@@ -145,7 +145,7 @@ function guessMimeTypeByPath(path: string, filename: string, associations: IText
// We want to prioritize associations based on the order they are registered so that the last registered
// association wins over all other. This is for https://github.com/Microsoft/vscode/issues/20074
for (let i = associations.length - 1; i >= 0; i--) {
let association = associations[i];
const association = associations[i];
// First exact name match
if (filename === association.filenameLowercase) {
......@@ -156,7 +156,7 @@ function guessMimeTypeByPath(path: string, filename: string, associations: IText
// Longest pattern match
if (association.filepattern) {
if (!patternMatch || association.filepattern.length > patternMatch.filepattern.length) {
let target = association.filepatternOnPath ? path : filename; // match on full path if pattern contains path separator
const target = association.filepatternOnPath ? path : filename; // match on full path if pattern contains path separator
if (match(association.filepatternLowercase, target)) {
patternMatch = association;
}
......@@ -198,12 +198,12 @@ function guessMimeTypeByFirstline(firstLine: string): string {
if (firstLine.length > 0) {
for (let i = 0; i < registeredAssociations.length; ++i) {
let association = registeredAssociations[i];
const association = registeredAssociations[i];
if (!association.firstline) {
continue;
}
let matches = firstLine.match(association.firstline);
const matches = firstLine.match(association.firstline);
if (matches && matches.length > 0) {
return association.mime;
}
......@@ -227,7 +227,7 @@ export function isUnspecific(mime: string[] | string): boolean {
export function suggestFilename(langId: string, prefix: string): string {
for (let i = 0; i < registeredAssociations.length; i++) {
let association = registeredAssociations[i];
const association = registeredAssociations[i];
if (association.userConfigured) {
continue; // only support registered ones
}
......
......@@ -378,7 +378,7 @@ export function realcaseSync(path: string): string {
return path;
}
const name = paths.basename(path).toLowerCase();
const name = (paths.basename(path) /* can be '' for windows drive letters */ || path).toLowerCase();
try {
const entries = readdirSync(dir);
const found = entries.filter(e => e.toLowerCase() === name); // use a case insensitive search
......
......@@ -8,6 +8,7 @@
import * as assert from 'assert';
import labels = require('vs/base/common/labels');
import platform = require('vs/base/common/platform');
import { getBaseLabel } from 'vs/base/common/labels';
suite('Labels', () => {
test('shorten - windows', () => {
......@@ -143,4 +144,27 @@ suite('Labels', () => {
assert.strictEqual(labels.template(t, { dirty: '', activeEditorShort: 'somefile.txt', rootName: 'monaco', appName: 'Visual Studio Code', separator: { label: ' - ' } }), 'somefile.txt - monaco - Visual Studio Code');
assert.strictEqual(labels.template(t, { dirty: '* ', activeEditorShort: 'somefile.txt', rootName: 'monaco', appName: 'Visual Studio Code', separator: { label: ' - ' } }), '* somefile.txt - monaco - Visual Studio Code');
});
test('getBaseLabel - unix', () => {
if (platform.isWindows) {
assert.ok(true);
return;
}
assert.equal(getBaseLabel('/some/folder/file.txt'), 'file.txt');
assert.equal(getBaseLabel('/some/folder'), 'folder');
assert.equal(getBaseLabel('/'), '/');
});
test('getBaseLabel - windows', () => {
if (!platform.isWindows) {
assert.ok(true);
return;
}
assert.equal(getBaseLabel('c:'), 'C:\\');
assert.equal(getBaseLabel('c:\\'), 'C:\\');
assert.equal(getBaseLabel('c:\\some\\folder\\file.txt'), 'file.txt');
assert.equal(getBaseLabel('c:\\some\\folder'), 'folder');
});
});
\ No newline at end of file
......@@ -33,6 +33,7 @@ import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppen
import { mkdirp } from 'vs/base/node/pfs';
import { IChoiceService } from 'vs/platform/message/common/message';
import { ChoiceCliService } from 'vs/platform/message/node/messageCli';
import { getBaseLabel } from 'vs/base/common/labels';
const notFound = (id: string) => localize('notFound', "Extension '{0}' not found.", id);
const notInstalled = (id: string) => localize('notInstalled', "Extension '{0}' is not installed.", id);
......@@ -95,7 +96,7 @@ class Main {
const extension = path.isAbsolute(id) ? id : path.join(process.cwd(), id);
return this.extensionManagementService.install(extension).then(() => {
console.log(localize('successVsixInstall', "Extension '{0}' was successfully installed!", path.basename(extension)));
console.log(localize('successVsixInstall', "Extension '{0}' was successfully installed!", getBaseLabel(extension)));
});
});
......
......@@ -12,7 +12,7 @@ import { trim } from 'vs/base/common/strings';
import { IStorageService } from 'vs/platform/storage/node/storage';
import { app } from 'electron';
import { ILogService } from 'vs/platform/log/common/log';
import { getPathLabel } from 'vs/base/common/labels';
import { getPathLabel, getBaseLabel } from 'vs/base/common/labels';
import { IPath } from 'vs/platform/windows/common/windows';
import CommonEvent, { Emitter } from 'vs/base/common/event';
import { isWindows, isMacintosh, isLinux } from 'vs/base/common/platform';
......@@ -257,8 +257,8 @@ export class HistoryMainService implements IHistoryMainService {
type: 'custom',
name: nls.localize('recentFolders', "Recent Workspaces"),
items: this.getRecentlyOpened().workspaces.slice(0, 7 /* limit number of entries here */).map(workspace => {
const title = isSingleFolderWorkspaceIdentifier(workspace) ? path.basename(workspace) : getWorkspaceLabel(workspace, this.environmentService);
const description = isSingleFolderWorkspaceIdentifier(workspace) ? nls.localize('folderDesc', "{0} {1}", path.basename(workspace), getPathLabel(path.dirname(workspace))) : nls.localize('codeWorkspace', "Code Workspace");
const title = isSingleFolderWorkspaceIdentifier(workspace) ? getBaseLabel(workspace) : getWorkspaceLabel(workspace, this.environmentService);
const description = isSingleFolderWorkspaceIdentifier(workspace) ? nls.localize('folderDesc', "{0} {1}", getBaseLabel(workspace), getPathLabel(path.dirname(workspace))) : nls.localize('codeWorkspace', "Code Workspace");
return <Electron.JumpListItem>{
type: 'task',
......
......@@ -25,7 +25,6 @@ import { QuickOpenEntry, QuickOpenModel, QuickOpenEntryGroup, compareEntries, Qu
import { QuickOpenWidget, HideReason } from 'vs/base/parts/quickopen/browser/quickOpenWidget';
import { ContributableActionProvider } from 'vs/workbench/browser/actions';
import labels = require('vs/base/common/labels');
import paths = require('vs/base/common/paths');
import { ITextFileService, AutoSaveMode } from 'vs/workbench/services/textfile/common/textfiles';
import { Registry } from 'vs/platform/registry/common/platform';
import { IResourceInput, IEditorInput } from 'vs/platform/editor/common/editor';
......@@ -57,6 +56,7 @@ import { ITree, IActionProvider } from 'vs/base/parts/tree/browser/tree';
import { BaseActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { FileKind, IFileService } from 'vs/platform/files/common/files';
import { scoreItem, ScorerCache, compareItemsByScore, prepareQuery } from 'vs/base/parts/quickopen/common/quickOpenScorer';
import { getBaseLabel } from 'vs/base/common/labels';
const HELP_PREFIX = '?';
......@@ -1272,7 +1272,7 @@ export class EditorHistoryEntry extends EditorQuickOpenEntry {
} else {
const resourceInput = input as IResourceInput;
this.resource = resourceInput.resource;
this.label = paths.basename(resourceInput.resource.fsPath);
this.label = getBaseLabel(resourceInput.resource);
this.description = labels.getPathLabel(resources.dirname(this.resource), contextService, environmentService);
this.dirty = this.resource && this.textFileService.isDirty(this.resource);
......
......@@ -307,9 +307,11 @@ export class TitlebarPart extends Part implements ITitleService {
const path = segments.slice(0, pathOffset).join(paths.sep);
let label = paths.basename(path);
let label: string;
if (!isFile) {
label = paths.basename(paths.dirname(path));
label = labels.getBaseLabel(paths.dirname(path));
} else {
label = labels.getBaseLabel(path);
}
actions.push(new ShowItemInFolderAction(path, label || paths.sep, this.windowsService));
......
......@@ -38,7 +38,7 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import * as os from 'os';
import { webFrame } from 'electron';
import { getPathLabel } from 'vs/base/common/labels';
import { getPathLabel, getBaseLabel } from 'vs/base/common/labels';
import { IViewlet } from 'vs/workbench/common/viewlet';
import { IPanel } from 'vs/workbench/common/panel';
import { IWorkspaceIdentifier, getWorkspaceLabel, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
......@@ -724,7 +724,7 @@ export abstract class BaseOpenRecentAction extends Action {
let description: string;
if (isSingleFolderWorkspaceIdentifier(workspace)) {
path = workspace;
label = paths.basename(path);
label = getBaseLabel(path);
description = getPathLabel(paths.dirname(path), null, environmentService);
} else {
path = workspace.configPath;
......
......@@ -14,6 +14,7 @@ import { IEditorInput } from 'vs/platform/editor/common/editor';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IEditorGroup, toResource } from 'vs/workbench/common/editor';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { getPathLabel } from 'vs/base/common/labels';
export class Model {
......@@ -78,7 +79,7 @@ export class FileStat implements IFileStat {
public isDirectoryResolved: boolean;
constructor(resource: URI, public root: FileStat, isDirectory?: boolean, hasChildren?: boolean, name: string = paths.basename(resource.fsPath), mtime?: number, etag?: string) {
constructor(resource: URI, public root: FileStat, isDirectory?: boolean, hasChildren?: boolean, name: string = getPathLabel(resource), mtime?: number, etag?: string) {
this.resource = resource;
this.name = name;
this.isDirectory = !!isDirectory;
......
......@@ -3,7 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import paths = require('vs/base/common/paths');
import objects = require('vs/base/common/objects');
import strings = require('vs/base/common/strings');
import errors = require('vs/base/common/errors');
......@@ -25,6 +24,7 @@ import { IProgressRunner } from 'vs/platform/progress/common/progress';
import { ModelDecorationOptions } from 'vs/editor/common/model/textModelWithDecorations';
import { overviewRulerFindMatchForeground } from 'vs/platform/theme/common/colorRegistry';
import { themeColorFromId } from 'vs/platform/theme/common/themeService';
import { getBaseLabel } from 'vs/base/common/labels';
export class Match {
......@@ -302,7 +302,7 @@ export class FileMatch extends Disposable {
}
public name(): string {
return paths.basename(this.resource().fsPath);
return getBaseLabel(this.resource());
}
public add(match: Match, trigger?: boolean) {
......@@ -379,7 +379,7 @@ export class FolderMatch extends Disposable {
}
public name(): string {
return paths.basename(this.resource().fsPath);
return getBaseLabel(this.resource());
}
public parent(): SearchResult {
......
......@@ -30,7 +30,7 @@ import { IExtensionEnablementService, IExtensionManagementService, IExtensionGal
import { used } from 'vs/workbench/parts/welcome/page/electron-browser/vs_code_welcome_page';
import { ILifecycleService, StartupKind } from 'vs/platform/lifecycle/common/lifecycle';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { tildify } from 'vs/base/common/labels';
import { tildify, getBaseLabel } from 'vs/base/common/labels';
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { registerColor, focusBorder, textLinkForeground, textLinkActiveForeground, foreground, descriptionForeground, contrastBorder, activeContrastBorder } from 'vs/platform/theme/common/colorRegistry';
import { getExtraColor } from 'vs/workbench/parts/welcome/walkThrough/node/walkThroughUtils';
......@@ -286,7 +286,7 @@ class WelcomePage {
let parent: string;
let wsPath: string;
if (isSingleFolderWorkspaceIdentifier(workspace)) {
label = path.basename(workspace);
label = getBaseLabel(workspace);
parent = path.dirname(workspace);
wsPath = workspace;
} else {
......
......@@ -40,6 +40,7 @@ import { Schemas } from 'vs/base/common/network';
import { massageFolderPathForWorkspace } from 'vs/platform/workspaces/node/workspaces';
import { distinct } from 'vs/base/common/arrays';
import { UserConfiguration } from 'vs/platform/configuration/node/configuration';
import { getBaseLabel } from 'vs/base/common/labels';
export class WorkspaceService extends Disposable implements IWorkspaceConfigurationService, IWorkspaceContextService {
......@@ -335,7 +336,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat
const ctime = isLinux ? workspaceStat.ino : workspaceStat.birthtime.getTime(); // On Linux, birthtime is ctime, so we cannot use it! We use the ino instead!
const id = createHash('md5').update(folderPath.fsPath).update(ctime ? String(ctime) : '').digest('hex');
const folder = URI.file(folderPath.fsPath);
return new Workspace(id, paths.basename(folderPath.fsPath), toWorkspaceFolders([{ path: folder.fsPath }]), null, ctime);
return new Workspace(id, getBaseLabel(folder), toWorkspaceFolders([{ path: folder.fsPath }]), null, ctime);
});
}
......
......@@ -39,6 +39,7 @@ import { ITextResourceConfigurationService } from 'vs/editor/common/services/res
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
import { getBaseLabel } from 'vs/base/common/labels';
export interface IEncodingOverride {
resource: uri;
......@@ -1007,7 +1008,7 @@ export class StatResolver {
this.resource = resource;
this.isDirectory = isDirectory;
this.mtime = mtime;
this.name = paths.basename(resource.fsPath);
this.name = getBaseLabel(resource);
this.etag = etag(size, mtime);
this.size = size;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册