提交 6c2bca4b 编写于 作者: M Martin Aeschlimann

label polishes

上级 86526f40
......@@ -9,6 +9,7 @@ import { endsWith, ltrim, startsWithIgnoreCase, rtrim, startsWith } from 'vs/bas
import { Schemas } from 'vs/base/common/network';
import { isLinux, isWindows, isMacintosh } from 'vs/base/common/platform';
import { isEqual, basename } from 'vs/base/common/resources';
import { CharCode } from 'vs/base/common/charCode';
export interface IWorkspaceFolderProvider {
getWorkspaceFolder(resource: URI): { uri: URI, name?: string } | null;
......@@ -383,3 +384,16 @@ export function mnemonicButtonLabel(label: string): string {
export function unmnemonicLabel(label: string): string {
return label.replace(/&/g, '&&');
}
/**
* Splits a path in name and parent path, supporting both '/' and '\'
*/
export function splitName(fullPath: string): { name: string, parentPath: string } {
for (let i = fullPath.length - 1; i >= 1; i--) {
const code = fullPath.charCodeAt(i);
if (code === CharCode.Slash || code === CharCode.Backslash) {
return { parentPath: fullPath.substr(0, i), name: fullPath.substr(i + 1) };
}
}
return { parentPath: '', name: fullPath };
}
......@@ -13,7 +13,7 @@ import { IPath } from 'vs/platform/windows/common/windows';
import { Event as CommonEvent, Emitter } from 'vs/base/common/event';
import { isWindows, isMacintosh } from 'vs/base/common/platform';
import { IWorkspaceIdentifier, IWorkspacesMainService, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { IHistoryMainService, IRecentlyOpened, isRecentWorkspace, isRecentFolder, IRecent, isRecentFile } from 'vs/platform/history/common/history';
import { IHistoryMainService, IRecentlyOpened, isRecentWorkspace, isRecentFolder, IRecent, isRecentFile, IRecentFolder, IRecentWorkspace, IRecentFile } from 'vs/platform/history/common/history';
import { RunOnceScheduler } from 'vs/base/common/async';
import { isEqual as areResourcesEqual, dirname, originalFSPath } from 'vs/base/common/resources';
import { URI } from 'vs/base/common/uri';
......@@ -51,15 +51,15 @@ export class HistoryMainService implements IHistoryMainService {
for (let curr of newlyAdded) {
if (isRecentWorkspace(curr)) {
if (!this.workspacesMainService.isUntitledWorkspace(curr.workspace) && indexOfWorkspace(mru.workspaces, curr.workspace) >= 0) {
if (!this.workspacesMainService.isUntitledWorkspace(curr.workspace) && indexOfWorkspace(mru.workspaces, curr.workspace) === -1) {
mru.workspaces.unshift(curr);
}
} else if (isRecentFolder(curr)) {
if (indexOfFolder(mru.workspaces, curr.folderUri) >= 0) {
if (indexOfFolder(mru.workspaces, curr.folderUri) === -1) {
mru.workspaces.unshift(curr);
}
} else {
if (indexOfFile(mru.files, curr.fileUri) >= 0) {
if (indexOfFile(mru.files, curr.fileUri) === -1) {
mru.files.unshift(curr);
// Add to recent documents (Windows only, macOS later)
if (isWindows && curr.fileUri.scheme === Schemas.file) {
......@@ -150,28 +150,45 @@ export class HistoryMainService implements IHistoryMainService {
getRecentlyOpened(currentWorkspace?: IWorkspaceIdentifier, currentFolder?: ISingleFolderWorkspaceIdentifier, currentFiles?: IPath[]): IRecentlyOpened {
// Get from storage
let { workspaces, files } = this.getRecentlyOpenedFromStorage();
const workspaces: Array<IRecentFolder | IRecentWorkspace> = [];
const files: IRecentFile[] = [];
// Add current workspace to beginning if set
if (currentWorkspace && !this.workspacesMainService.isUntitledWorkspace(currentWorkspace) && !workspaces.some(w => isRecentWorkspace(w) && w.workspace.id === currentWorkspace.id)) {
workspaces.unshift({ workspace: currentWorkspace });
if (currentWorkspace && !this.workspacesMainService.isUntitledWorkspace(currentWorkspace)) {
workspaces.push({ workspace: currentWorkspace });
}
if (currentFolder && !workspaces.some(w => isRecentFolder(w) && areResourcesEqual(w.folderUri, currentFolder))) {
workspaces.unshift({ folderUri: currentFolder });
if (currentFolder) {
workspaces.push({ folderUri: currentFolder });
}
// Add currently files to open to the beginning if any
if (currentFiles) {
for (let currentFile of currentFiles) {
const fileUri = currentFile.fileUri;
if (fileUri && !files.some(f => areResourcesEqual(f.fileUri, fileUri))) {
files.unshift({ fileUri });
if (fileUri && indexOfFile(files, fileUri) === -1) {
files.push({ fileUri });
}
}
}
// Get from storage
let recents = this.getRecentlyOpenedFromStorage();
for (let recent of recents.workspaces) {
let index = isRecentFolder(recent) ? indexOfFolder(workspaces, recent.folderUri) : indexOfWorkspace(workspaces, recent.workspace);
if (index >= 0) {
workspaces[index].label = workspaces[index].label || recent.label;
} else {
workspaces.push(recent);
}
}
for (let recent of recents.files) {
let index = indexOfFile(files, recent.fileUri);
if (index >= 0) {
files[index].label = files[index].label || recent.label;
} else {
files.push(recent);
}
}
return { workspaces, files };
}
......@@ -280,14 +297,14 @@ function location(recent: IRecent): URI {
return recent.workspace.configPath;
}
function indexOfWorkspace(arr: Array<IRecent>, workspace: IWorkspaceIdentifier): number {
function indexOfWorkspace(arr: IRecent[], workspace: IWorkspaceIdentifier): number {
return arrays.firstIndex(arr, w => isRecentWorkspace(w) && w.workspace.id === workspace.id);
}
function indexOfFolder(arr: Array<IRecent>, folderURI: ISingleFolderWorkspaceIdentifier): number {
function indexOfFolder(arr: IRecent[], folderURI: ISingleFolderWorkspaceIdentifier): number {
return arrays.firstIndex(arr, f => isRecentFolder(f) && areResourcesEqual(f.folderUri, folderURI));
}
function indexOfFile(arr: Array<IRecent>, fileURI: URI): number {
return arrays.firstIndex(arr, f => isRecentFile(f) && areResourcesEqual(f.fileUri, fileURI));
function indexOfFile(arr: IRecentFile[], fileURI: URI): number {
return arrays.firstIndex(arr, f => areResourcesEqual(f.fileUri, fileURI));
}
\ No newline at end of file
......@@ -6,10 +6,10 @@ import { UriComponents, URI } from 'vs/base/common/uri';
import { IRecentlyOpened, isRecentFolder } from 'vs/platform/history/common/history';
interface ISerializedRecentlyOpened {
workspaces3: Array<ISerializedWorkspace | string>; // workspace or URI.toString()
workspaceLabels: Array<string | null>;
files2: string[]; // files as URI.toString()
fileLabels: Array<string | null>;
workspaces3: Array<ISerializedWorkspace | string>; // workspace or URI.toString() // added in 1.32
workspaceLabels: Array<string | null>; // added in 1.33
files2: string[]; // files as URI.toString() // added in 1.32
fileLabels: Array<string | null>; // added in 1.33
}
interface ILegacySerializedRecentlyOpened {
......
......@@ -371,9 +371,7 @@ export class MenubarControl extends Disposable {
typeHint = 'file';
}
label = unmnemonicLabel(label);
const ret: IAction = new Action(commandId, label, undefined, undefined, (event) => {
const ret: IAction = new Action(commandId, unmnemonicLabel(label), undefined, undefined, (event) => {
const openInNewWindow = event && ((!isMacintosh && (event.ctrlKey || event.shiftKey)) || (isMacintosh && (event.metaKey || event.altKey)));
return this.windowService.openWindow([{ uri, typeHint, label }], {
......
......@@ -6,7 +6,6 @@
import 'vs/css!./welcomePage';
import { URI } from 'vs/base/common/uri';
import * as strings from 'vs/base/common/strings';
import * as path from 'vs/base/common/path';
import { ICommandService } from 'vs/platform/commands/common/commands';
import * as arrays from 'vs/base/common/arrays';
import { WalkThroughInput } from 'vs/workbench/contrib/welcome/walkThrough/common/walkThroughInput';
......@@ -20,7 +19,6 @@ import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configur
import { localize } from 'vs/nls';
import { Action } from 'vs/base/common/actions';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { Schemas } from 'vs/base/common/network';
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
import { getInstalledExtensions, IExtensionStatus, onExtensionChanged, isKeymapExtension } from 'vs/workbench/contrib/extensions/common/extensionsUtils';
......@@ -28,7 +26,7 @@ import { IExtensionEnablementService, IExtensionManagementService, IExtensionGal
import { used } from 'vs/workbench/contrib/welcome/page/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 { splitName } 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/contrib/welcome/walkThrough/common/walkThroughUtils';
......@@ -256,7 +254,6 @@ class WelcomePage {
@IWindowService private readonly windowService: IWindowService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@ILabelService private readonly labelService: ILabelService,
@INotificationService private readonly notificationService: INotificationService,
@IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService,
......@@ -341,41 +338,27 @@ class WelcomePage {
private createListEntries(recents: (IRecentWorkspace | IRecentFolder)[]) {
return recents.map(recent => {
let label: string;
let fullPath: string;
let resource: URI;
let typeHint: URIType | undefined;
if (isRecentFolder(recent)) {
resource = recent.folderUri;
label = recent.label || this.labelService.getWorkspaceLabel(recent.folderUri);
fullPath = recent.label || this.labelService.getWorkspaceLabel(recent.folderUri, { verbose: true });
typeHint = 'folder';
} else {
label = recent.label || this.labelService.getWorkspaceLabel(recent.workspace);
fullPath = recent.label || this.labelService.getWorkspaceLabel(recent.workspace, { verbose: true });
resource = recent.workspace.configPath;
typeHint = 'file';
}
const li = document.createElement('li');
const { name, parentPath } = splitName(fullPath);
const li = document.createElement('li');
const a = document.createElement('a');
let name = label;
let parentFolderPath: string | undefined;
if (resource.scheme === Schemas.file) {
let parentFolder = path.dirname(resource.fsPath);
if (!name && parentFolder) {
const tmp = name;
name = parentFolder;
parentFolder = tmp;
}
parentFolderPath = tildify(parentFolder, this.environmentService.userHome);
} else {
parentFolderPath = this.labelService.getUriLabel(resource);
}
a.innerText = name;
a.title = label;
a.setAttribute('aria-label', localize('welcomePage.openFolderWithPath', "Open folder {0} with path {1}", name, parentFolderPath));
a.title = fullPath;
a.setAttribute('aria-label', localize('welcomePage.openFolderWithPath', "Open folder {0} with path {1}", name, parentPath));
a.href = 'javascript:void(0)';
a.addEventListener('click', e => {
/* __GDPR__
......@@ -388,7 +371,7 @@ class WelcomePage {
id: 'openRecentFolder',
from: telemetryFrom
});
this.windowService.openWindow([{ uri: resource, typeHint, label }], { forceNewWindow: e.ctrlKey || e.metaKey });
this.windowService.openWindow([{ uri: resource, typeHint }], { forceNewWindow: e.ctrlKey || e.metaKey });
e.preventDefault();
e.stopPropagation();
});
......@@ -397,8 +380,8 @@ class WelcomePage {
const span = document.createElement('span');
span.classList.add('path');
span.classList.add('detail');
span.innerText = parentFolderPath;
span.title = label;
span.innerText = parentPath;
span.title = fullPath;
li.appendChild(span);
return li;
......
......@@ -14,10 +14,8 @@ import { isMacintosh } from 'vs/base/common/platform';
import * as browser from 'vs/base/browser/browser';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { webFrame } from 'electron';
import { getBaseLabel } from 'vs/base/common/labels';
import { FileKind } from 'vs/platform/files/common/files';
import { ILabelService } from 'vs/platform/label/common/label';
import { dirname } from 'vs/base/common/resources';
import { IModelService } from 'vs/editor/common/services/modelService';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IQuickInputService, IQuickPickItem, IQuickInputButton, IQuickPickSeparator, IKeyMods } from 'vs/platform/quickinput/common/quickInput';
......@@ -27,6 +25,7 @@ import { ICommandHandler } from 'vs/platform/commands/common/commands';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IRecentFolder, IRecentFile, IRecentWorkspace, IRecent, isRecentFolder, isRecentWorkspace } from 'vs/platform/history/common/history';
import { splitName } from 'vs/base/common/labels';
export class CloseCurrentWindowAction extends Action {
......@@ -341,39 +340,35 @@ export abstract class BaseOpenRecentAction extends Action {
const toPick = (recent: IRecent, labelService: ILabelService, buttons: IQuickInputButton[] | undefined) => {
let resource: URI | undefined;
let label: string | undefined;
let description: string | undefined;
let fullLabel: string | undefined;
let fileKind: FileKind | undefined;
if (isRecentFolder(recent)) {
resource = recent.folderUri;
label = recent.label || labelService.getWorkspaceLabel(recent.folderUri);
description = labelService.getUriLabel(dirname(resource));
fullLabel = recent.label || labelService.getWorkspaceLabel(recent.folderUri, { verbose: true });
fileKind = FileKind.FOLDER;
} else if (isRecentWorkspace(recent)) {
resource = recent.workspace.configPath;
label = recent.label || labelService.getWorkspaceLabel(recent.workspace);
description = labelService.getUriLabel(dirname(resource));
fullLabel = recent.label || labelService.getWorkspaceLabel(recent.workspace, { verbose: true });
fileKind = FileKind.ROOT_FOLDER;
} else {
resource = recent.fileUri;
label = recent.label || getBaseLabel(recent.fileUri);
description = labelService.getUriLabel(dirname(resource));
fullLabel = recent.label || labelService.getUriLabel(recent.fileUri);
fileKind = FileKind.FILE;
}
const { name, parentPath } = splitName(fullLabel);
return {
iconClasses: getIconClasses(this.modelService, this.modeService, resource, fileKind),
label,
description,
label: name,
description: parentPath,
buttons,
resource,
fileKind,
};
};
const runPick = (uri: URI, isFile: boolean, keyMods: IKeyMods, label: string) => {
const runPick = (uri: URI, isFile: boolean, keyMods: IKeyMods) => {
const forceNewWindow = keyMods.ctrlCmd;
return this.windowService.openWindow([{ uri, typeHint: isFile ? 'file' : 'folder', label }], { forceNewWindow, forceOpenWorkspaceAsFile: isFile });
return this.windowService.openWindow([{ uri, typeHint: isFile ? 'file' : 'folder' }], { forceNewWindow, forceOpenWorkspaceAsFile: isFile });
};
const workspacePicks = recentWorkspaces.map(workspace => toPick(workspace, this.labelService, !this.isQuickNavigate() ? [this.removeFromRecentlyOpened] : undefined));
......@@ -399,7 +394,7 @@ export abstract class BaseOpenRecentAction extends Action {
}
}).then((pick): Promise<void> | void => {
if (pick) {
return runPick(pick.resource, pick.fileKind === FileKind.FILE, keyMods, pick.label);
return runPick(pick.resource, pick.fileKind === FileKind.FILE, keyMods);
}
});
}
......
......@@ -119,7 +119,7 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
if (newWorkspacePath) {
return this.saveWorkspaceAs(workspaceIdentifier, newWorkspacePath).then(_ => {
return this.workspaceService.getWorkspaceIdentifier(newWorkspacePath).then(newWorkspaceIdentifier => {
const label = this.labelService.getWorkspaceLabel(newWorkspaceIdentifier);
const label = this.labelService.getWorkspaceLabel(newWorkspaceIdentifier, { verbose: true });
this.windowsService.addRecentlyOpened([{ label, workspace: newWorkspaceIdentifier }]);
this.workspaceService.deleteUntitledWorkspace(workspaceIdentifier);
return false;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册