Skip to content

Commit 6c2bca4

Browse files
committed
label polishes
1 parent 86526f4 commit 6c2bca4

7 files changed

Lines changed: 76 additions & 69 deletions

File tree

src/vs/base/common/labels.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { endsWith, ltrim, startsWithIgnoreCase, rtrim, startsWith } from 'vs/bas
99
import { Schemas } from 'vs/base/common/network';
1010
import { isLinux, isWindows, isMacintosh } from 'vs/base/common/platform';
1111
import { isEqual, basename } from 'vs/base/common/resources';
12+
import { CharCode } from 'vs/base/common/charCode';
1213

1314
export interface IWorkspaceFolderProvider {
1415
getWorkspaceFolder(resource: URI): { uri: URI, name?: string } | null;
@@ -383,3 +384,16 @@ export function mnemonicButtonLabel(label: string): string {
383384
export function unmnemonicLabel(label: string): string {
384385
return label.replace(/&/g, '&&');
385386
}
387+
388+
/**
389+
* Splits a path in name and parent path, supporting both '/' and '\'
390+
*/
391+
export function splitName(fullPath: string): { name: string, parentPath: string } {
392+
for (let i = fullPath.length - 1; i >= 1; i--) {
393+
const code = fullPath.charCodeAt(i);
394+
if (code === CharCode.Slash || code === CharCode.Backslash) {
395+
return { parentPath: fullPath.substr(0, i), name: fullPath.substr(i + 1) };
396+
}
397+
}
398+
return { parentPath: '', name: fullPath };
399+
}

src/vs/platform/history/electron-main/historyMainService.ts

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { IPath } from 'vs/platform/windows/common/windows';
1313
import { Event as CommonEvent, Emitter } from 'vs/base/common/event';
1414
import { isWindows, isMacintosh } from 'vs/base/common/platform';
1515
import { IWorkspaceIdentifier, IWorkspacesMainService, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
16-
import { IHistoryMainService, IRecentlyOpened, isRecentWorkspace, isRecentFolder, IRecent, isRecentFile } from 'vs/platform/history/common/history';
16+
import { IHistoryMainService, IRecentlyOpened, isRecentWorkspace, isRecentFolder, IRecent, isRecentFile, IRecentFolder, IRecentWorkspace, IRecentFile } from 'vs/platform/history/common/history';
1717
import { RunOnceScheduler } from 'vs/base/common/async';
1818
import { isEqual as areResourcesEqual, dirname, originalFSPath } from 'vs/base/common/resources';
1919
import { URI } from 'vs/base/common/uri';
@@ -51,15 +51,15 @@ export class HistoryMainService implements IHistoryMainService {
5151

5252
for (let curr of newlyAdded) {
5353
if (isRecentWorkspace(curr)) {
54-
if (!this.workspacesMainService.isUntitledWorkspace(curr.workspace) && indexOfWorkspace(mru.workspaces, curr.workspace) >= 0) {
54+
if (!this.workspacesMainService.isUntitledWorkspace(curr.workspace) && indexOfWorkspace(mru.workspaces, curr.workspace) === -1) {
5555
mru.workspaces.unshift(curr);
5656
}
5757
} else if (isRecentFolder(curr)) {
58-
if (indexOfFolder(mru.workspaces, curr.folderUri) >= 0) {
58+
if (indexOfFolder(mru.workspaces, curr.folderUri) === -1) {
5959
mru.workspaces.unshift(curr);
6060
}
6161
} else {
62-
if (indexOfFile(mru.files, curr.fileUri) >= 0) {
62+
if (indexOfFile(mru.files, curr.fileUri) === -1) {
6363
mru.files.unshift(curr);
6464
// Add to recent documents (Windows only, macOS later)
6565
if (isWindows && curr.fileUri.scheme === Schemas.file) {
@@ -150,28 +150,45 @@ export class HistoryMainService implements IHistoryMainService {
150150

151151
getRecentlyOpened(currentWorkspace?: IWorkspaceIdentifier, currentFolder?: ISingleFolderWorkspaceIdentifier, currentFiles?: IPath[]): IRecentlyOpened {
152152

153-
// Get from storage
154-
let { workspaces, files } = this.getRecentlyOpenedFromStorage();
153+
const workspaces: Array<IRecentFolder | IRecentWorkspace> = [];
154+
const files: IRecentFile[] = [];
155155

156156
// Add current workspace to beginning if set
157-
if (currentWorkspace && !this.workspacesMainService.isUntitledWorkspace(currentWorkspace) && !workspaces.some(w => isRecentWorkspace(w) && w.workspace.id === currentWorkspace.id)) {
158-
workspaces.unshift({ workspace: currentWorkspace });
157+
if (currentWorkspace && !this.workspacesMainService.isUntitledWorkspace(currentWorkspace)) {
158+
workspaces.push({ workspace: currentWorkspace });
159159
}
160-
161-
if (currentFolder && !workspaces.some(w => isRecentFolder(w) && areResourcesEqual(w.folderUri, currentFolder))) {
162-
workspaces.unshift({ folderUri: currentFolder });
160+
if (currentFolder) {
161+
workspaces.push({ folderUri: currentFolder });
163162
}
164163

165164
// Add currently files to open to the beginning if any
166165
if (currentFiles) {
167166
for (let currentFile of currentFiles) {
168167
const fileUri = currentFile.fileUri;
169-
if (fileUri && !files.some(f => areResourcesEqual(f.fileUri, fileUri))) {
170-
files.unshift({ fileUri });
168+
if (fileUri && indexOfFile(files, fileUri) === -1) {
169+
files.push({ fileUri });
171170
}
172171
}
173172
}
174173

174+
// Get from storage
175+
let recents = this.getRecentlyOpenedFromStorage();
176+
for (let recent of recents.workspaces) {
177+
let index = isRecentFolder(recent) ? indexOfFolder(workspaces, recent.folderUri) : indexOfWorkspace(workspaces, recent.workspace);
178+
if (index >= 0) {
179+
workspaces[index].label = workspaces[index].label || recent.label;
180+
} else {
181+
workspaces.push(recent);
182+
}
183+
}
184+
for (let recent of recents.files) {
185+
let index = indexOfFile(files, recent.fileUri);
186+
if (index >= 0) {
187+
files[index].label = files[index].label || recent.label;
188+
} else {
189+
files.push(recent);
190+
}
191+
}
175192
return { workspaces, files };
176193
}
177194

@@ -280,14 +297,14 @@ function location(recent: IRecent): URI {
280297
return recent.workspace.configPath;
281298
}
282299

283-
function indexOfWorkspace(arr: Array<IRecent>, workspace: IWorkspaceIdentifier): number {
300+
function indexOfWorkspace(arr: IRecent[], workspace: IWorkspaceIdentifier): number {
284301
return arrays.firstIndex(arr, w => isRecentWorkspace(w) && w.workspace.id === workspace.id);
285302
}
286303

287-
function indexOfFolder(arr: Array<IRecent>, folderURI: ISingleFolderWorkspaceIdentifier): number {
304+
function indexOfFolder(arr: IRecent[], folderURI: ISingleFolderWorkspaceIdentifier): number {
288305
return arrays.firstIndex(arr, f => isRecentFolder(f) && areResourcesEqual(f.folderUri, folderURI));
289306
}
290307

291-
function indexOfFile(arr: Array<IRecent>, fileURI: URI): number {
292-
return arrays.firstIndex(arr, f => isRecentFile(f) && areResourcesEqual(f.fileUri, fileURI));
308+
function indexOfFile(arr: IRecentFile[], fileURI: URI): number {
309+
return arrays.firstIndex(arr, f => areResourcesEqual(f.fileUri, fileURI));
293310
}

src/vs/platform/history/electron-main/historyStorage.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import { UriComponents, URI } from 'vs/base/common/uri';
66
import { IRecentlyOpened, isRecentFolder } from 'vs/platform/history/common/history';
77

88
interface ISerializedRecentlyOpened {
9-
workspaces3: Array<ISerializedWorkspace | string>; // workspace or URI.toString()
10-
workspaceLabels: Array<string | null>;
11-
files2: string[]; // files as URI.toString()
12-
fileLabels: Array<string | null>;
9+
workspaces3: Array<ISerializedWorkspace | string>; // workspace or URI.toString() // added in 1.32
10+
workspaceLabels: Array<string | null>; // added in 1.33
11+
files2: string[]; // files as URI.toString() // added in 1.32
12+
fileLabels: Array<string | null>; // added in 1.33
1313
}
1414

1515
interface ILegacySerializedRecentlyOpened {

src/vs/workbench/browser/parts/titlebar/menubarControl.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,9 +371,7 @@ export class MenubarControl extends Disposable {
371371
typeHint = 'file';
372372
}
373373

374-
label = unmnemonicLabel(label);
375-
376-
const ret: IAction = new Action(commandId, label, undefined, undefined, (event) => {
374+
const ret: IAction = new Action(commandId, unmnemonicLabel(label), undefined, undefined, (event) => {
377375
const openInNewWindow = event && ((!isMacintosh && (event.ctrlKey || event.shiftKey)) || (isMacintosh && (event.metaKey || event.altKey)));
378376

379377
return this.windowService.openWindow([{ uri, typeHint, label }], {

src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import 'vs/css!./welcomePage';
77
import { URI } from 'vs/base/common/uri';
88
import * as strings from 'vs/base/common/strings';
9-
import * as path from 'vs/base/common/path';
109
import { ICommandService } from 'vs/platform/commands/common/commands';
1110
import * as arrays from 'vs/base/common/arrays';
1211
import { WalkThroughInput } from 'vs/workbench/contrib/welcome/walkThrough/common/walkThroughInput';
@@ -20,15 +19,14 @@ import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configur
2019
import { localize } from 'vs/nls';
2120
import { Action } from 'vs/base/common/actions';
2221
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
23-
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
2422
import { Schemas } from 'vs/base/common/network';
2523
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
2624
import { getInstalledExtensions, IExtensionStatus, onExtensionChanged, isKeymapExtension } from 'vs/workbench/contrib/extensions/common/extensionsUtils';
2725
import { IExtensionEnablementService, IExtensionManagementService, IExtensionGalleryService, IExtensionTipsService, EnablementState, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement';
2826
import { used } from 'vs/workbench/contrib/welcome/page/browser/vs_code_welcome_page';
2927
import { ILifecycleService, StartupKind } from 'vs/platform/lifecycle/common/lifecycle';
3028
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
31-
import { tildify } from 'vs/base/common/labels';
29+
import { splitName } from 'vs/base/common/labels';
3230
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
3331
import { registerColor, focusBorder, textLinkForeground, textLinkActiveForeground, foreground, descriptionForeground, contrastBorder, activeContrastBorder } from 'vs/platform/theme/common/colorRegistry';
3432
import { getExtraColor } from 'vs/workbench/contrib/welcome/walkThrough/common/walkThroughUtils';
@@ -256,7 +254,6 @@ class WelcomePage {
256254
@IWindowService private readonly windowService: IWindowService,
257255
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
258256
@IConfigurationService private readonly configurationService: IConfigurationService,
259-
@IEnvironmentService private readonly environmentService: IEnvironmentService,
260257
@ILabelService private readonly labelService: ILabelService,
261258
@INotificationService private readonly notificationService: INotificationService,
262259
@IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService,
@@ -341,41 +338,27 @@ class WelcomePage {
341338

342339
private createListEntries(recents: (IRecentWorkspace | IRecentFolder)[]) {
343340
return recents.map(recent => {
344-
let label: string;
341+
let fullPath: string;
345342
let resource: URI;
346343
let typeHint: URIType | undefined;
347344
if (isRecentFolder(recent)) {
348345
resource = recent.folderUri;
349-
label = recent.label || this.labelService.getWorkspaceLabel(recent.folderUri);
346+
fullPath = recent.label || this.labelService.getWorkspaceLabel(recent.folderUri, { verbose: true });
350347
typeHint = 'folder';
351348
} else {
352-
label = recent.label || this.labelService.getWorkspaceLabel(recent.workspace);
349+
fullPath = recent.label || this.labelService.getWorkspaceLabel(recent.workspace, { verbose: true });
353350
resource = recent.workspace.configPath;
354351
typeHint = 'file';
355352
}
356353

357-
const li = document.createElement('li');
354+
const { name, parentPath } = splitName(fullPath);
358355

356+
const li = document.createElement('li');
359357
const a = document.createElement('a');
360-
let name = label;
361-
let parentFolderPath: string | undefined;
362-
363-
if (resource.scheme === Schemas.file) {
364-
let parentFolder = path.dirname(resource.fsPath);
365-
if (!name && parentFolder) {
366-
const tmp = name;
367-
name = parentFolder;
368-
parentFolder = tmp;
369-
}
370-
parentFolderPath = tildify(parentFolder, this.environmentService.userHome);
371-
} else {
372-
parentFolderPath = this.labelService.getUriLabel(resource);
373-
}
374-
375358

376359
a.innerText = name;
377-
a.title = label;
378-
a.setAttribute('aria-label', localize('welcomePage.openFolderWithPath', "Open folder {0} with path {1}", name, parentFolderPath));
360+
a.title = fullPath;
361+
a.setAttribute('aria-label', localize('welcomePage.openFolderWithPath', "Open folder {0} with path {1}", name, parentPath));
379362
a.href = 'javascript:void(0)';
380363
a.addEventListener('click', e => {
381364
/* __GDPR__
@@ -388,7 +371,7 @@ class WelcomePage {
388371
id: 'openRecentFolder',
389372
from: telemetryFrom
390373
});
391-
this.windowService.openWindow([{ uri: resource, typeHint, label }], { forceNewWindow: e.ctrlKey || e.metaKey });
374+
this.windowService.openWindow([{ uri: resource, typeHint }], { forceNewWindow: e.ctrlKey || e.metaKey });
392375
e.preventDefault();
393376
e.stopPropagation();
394377
});
@@ -397,8 +380,8 @@ class WelcomePage {
397380
const span = document.createElement('span');
398381
span.classList.add('path');
399382
span.classList.add('detail');
400-
span.innerText = parentFolderPath;
401-
span.title = label;
383+
span.innerText = parentPath;
384+
span.title = fullPath;
402385
li.appendChild(span);
403386

404387
return li;

src/vs/workbench/electron-browser/actions/windowActions.ts

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@ import { isMacintosh } from 'vs/base/common/platform';
1414
import * as browser from 'vs/base/browser/browser';
1515
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
1616
import { webFrame } from 'electron';
17-
import { getBaseLabel } from 'vs/base/common/labels';
1817
import { FileKind } from 'vs/platform/files/common/files';
1918
import { ILabelService } from 'vs/platform/label/common/label';
20-
import { dirname } from 'vs/base/common/resources';
2119
import { IModelService } from 'vs/editor/common/services/modelService';
2220
import { IModeService } from 'vs/editor/common/services/modeService';
2321
import { IQuickInputService, IQuickPickItem, IQuickInputButton, IQuickPickSeparator, IKeyMods } from 'vs/platform/quickinput/common/quickInput';
@@ -27,6 +25,7 @@ import { ICommandHandler } from 'vs/platform/commands/common/commands';
2725
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
2826
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
2927
import { IRecentFolder, IRecentFile, IRecentWorkspace, IRecent, isRecentFolder, isRecentWorkspace } from 'vs/platform/history/common/history';
28+
import { splitName } from 'vs/base/common/labels';
3029

3130
export class CloseCurrentWindowAction extends Action {
3231

@@ -341,39 +340,35 @@ export abstract class BaseOpenRecentAction extends Action {
341340

342341
const toPick = (recent: IRecent, labelService: ILabelService, buttons: IQuickInputButton[] | undefined) => {
343342
let resource: URI | undefined;
344-
let label: string | undefined;
345-
let description: string | undefined;
343+
let fullLabel: string | undefined;
346344
let fileKind: FileKind | undefined;
347345
if (isRecentFolder(recent)) {
348346
resource = recent.folderUri;
349-
label = recent.label || labelService.getWorkspaceLabel(recent.folderUri);
350-
description = labelService.getUriLabel(dirname(resource));
347+
fullLabel = recent.label || labelService.getWorkspaceLabel(recent.folderUri, { verbose: true });
351348
fileKind = FileKind.FOLDER;
352349
} else if (isRecentWorkspace(recent)) {
353350
resource = recent.workspace.configPath;
354-
label = recent.label || labelService.getWorkspaceLabel(recent.workspace);
355-
description = labelService.getUriLabel(dirname(resource));
351+
fullLabel = recent.label || labelService.getWorkspaceLabel(recent.workspace, { verbose: true });
356352
fileKind = FileKind.ROOT_FOLDER;
357353
} else {
358354
resource = recent.fileUri;
359-
label = recent.label || getBaseLabel(recent.fileUri);
360-
description = labelService.getUriLabel(dirname(resource));
355+
fullLabel = recent.label || labelService.getUriLabel(recent.fileUri);
361356
fileKind = FileKind.FILE;
362357
}
363-
358+
const { name, parentPath } = splitName(fullLabel);
364359
return {
365360
iconClasses: getIconClasses(this.modelService, this.modeService, resource, fileKind),
366-
label,
367-
description,
361+
label: name,
362+
description: parentPath,
368363
buttons,
369364
resource,
370365
fileKind,
371366
};
372367
};
373368

374-
const runPick = (uri: URI, isFile: boolean, keyMods: IKeyMods, label: string) => {
369+
const runPick = (uri: URI, isFile: boolean, keyMods: IKeyMods) => {
375370
const forceNewWindow = keyMods.ctrlCmd;
376-
return this.windowService.openWindow([{ uri, typeHint: isFile ? 'file' : 'folder', label }], { forceNewWindow, forceOpenWorkspaceAsFile: isFile });
371+
return this.windowService.openWindow([{ uri, typeHint: isFile ? 'file' : 'folder' }], { forceNewWindow, forceOpenWorkspaceAsFile: isFile });
377372
};
378373

379374
const workspacePicks = recentWorkspaces.map(workspace => toPick(workspace, this.labelService, !this.isQuickNavigate() ? [this.removeFromRecentlyOpened] : undefined));
@@ -399,7 +394,7 @@ export abstract class BaseOpenRecentAction extends Action {
399394
}
400395
}).then((pick): Promise<void> | void => {
401396
if (pick) {
402-
return runPick(pick.resource, pick.fileKind === FileKind.FILE, keyMods, pick.label);
397+
return runPick(pick.resource, pick.fileKind === FileKind.FILE, keyMods);
403398
}
404399
});
405400
}

src/vs/workbench/services/workspace/node/workspaceEditingService.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
119119
if (newWorkspacePath) {
120120
return this.saveWorkspaceAs(workspaceIdentifier, newWorkspacePath).then(_ => {
121121
return this.workspaceService.getWorkspaceIdentifier(newWorkspacePath).then(newWorkspaceIdentifier => {
122-
const label = this.labelService.getWorkspaceLabel(newWorkspaceIdentifier);
122+
const label = this.labelService.getWorkspaceLabel(newWorkspaceIdentifier, { verbose: true });
123123
this.windowsService.addRecentlyOpened([{ label, workspace: newWorkspaceIdentifier }]);
124124
this.workspaceService.deleteUntitledWorkspace(workspaceIdentifier);
125125
return false;

0 commit comments

Comments
 (0)