提交 2bb8f890 编写于 作者: B Benjamin Pasero

mr: unify recent history for workspaces and folders

上级 de4dc5c6
......@@ -443,7 +443,7 @@ export class CodeMenu {
private setOpenRecentMenu(openRecentMenu: Electron.Menu): void {
openRecentMenu.append(this.createMenuItem(nls.localize({ key: 'miReopenClosedEditor', comment: ['&& denotes a mnemonic'] }, "&&Reopen Closed Editor"), 'workbench.action.reopenClosedEditor'));
const { workspaces, folders, files } = this.historyService.getRecentlyOpened();
const { workspaces, files } = this.historyService.getRecentlyOpened();
// Workspaces
if (workspaces.length > 0) {
......@@ -454,15 +454,6 @@ export class CodeMenu {
}
}
// Folders
if (folders.length > 0) {
openRecentMenu.append(__separator__());
for (let i = 0; i < CodeMenu.MAX_MENU_RECENT_ENTRIES && i < folders.length; i++) {
openRecentMenu.append(this.createOpenRecentMenuItem(folders[i], 'openRecentFolder'));
}
}
// Files
if (files.length > 0) {
openRecentMenu.append(__separator__());
......@@ -472,7 +463,7 @@ export class CodeMenu {
}
}
if (folders.length || files.length) {
if (workspaces.length || files.length) {
openRecentMenu.append(__separator__());
openRecentMenu.append(this.createMenuItem(nls.localize({ key: 'miMore', comment: ['&& denotes a mnemonic'] }, "&&More..."), 'workbench.action.openRecent'));
openRecentMenu.append(__separator__());
......
......@@ -26,7 +26,7 @@ import product from 'vs/platform/node/product';
import { ITelemetryService, ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
import { isEqual } from 'vs/base/common/paths';
import { IWindowsMainService, IOpenConfiguration } from "vs/platform/windows/electron-main/windows";
import { IHistoryMainService, IRecentlyOpenedFile } from "vs/platform/history/common/history";
import { IHistoryMainService } from "vs/platform/history/common/history";
import { IProcessEnvironment, isLinux, isMacintosh, isWindows } from 'vs/base/common/platform';
import { TPromise } from "vs/base/common/winjs.base";
import { IWorkspacesMainService, IWorkspaceIdentifier } from "vs/platform/workspaces/common/workspaces";
......@@ -350,19 +350,18 @@ export class WindowsManager implements IWindowsMainService {
// Remember in recent document list (unless this opens for extension development)
// Also do not add paths when files are opened for diffing, only if opened individually
if (!usedWindows.some(w => w.isExtensionDevelopmentHost) && !openConfig.cli.diff) {
const recentlyOpened: (IWorkspaceIdentifier | IRecentlyOpenedFile)[] = [];
const recentlyOpenedWorkspaces: (IWorkspaceIdentifier | string)[] = [];
const recentlyOpenedFiles: string[] = [];
windowsToOpen.forEach(win => {
if (win.workspace) {
recentlyOpened.push(win.workspace);
} else if (win.folderPath || win.filePath) {
recentlyOpened.push({ path: win.folderPath || win.filePath, isFile: !!win.filePath });
if (win.workspace || win.folderPath) {
recentlyOpenedWorkspaces.push(win.workspace || win.folderPath);
} else if (win.filePath) {
recentlyOpenedFiles.push(win.filePath);
}
});
if (recentlyOpened.length) {
this.historyService.addToRecentlyOpened(recentlyOpened);
}
this.historyService.addRecentlyOpened(recentlyOpenedWorkspaces, recentlyOpenedFiles);
}
// Emit events
......
......@@ -13,24 +13,18 @@ import { IWorkspaceIdentifier } from "vs/platform/workspaces/common/workspaces";
export const IHistoryMainService = createDecorator<IHistoryMainService>('historyMainService');
export interface IRecentlyOpened {
workspaces: IWorkspaceIdentifier[];
folders: string[];
workspaces: (IWorkspaceIdentifier | string)[];
files: string[];
}
export interface IRecentlyOpenedFile {
path: string;
isFile?: boolean;
}
export interface IHistoryMainService {
_serviceBrand: any;
onRecentlyOpenedChange: CommonEvent<void>;
addToRecentlyOpened(recent: (IWorkspaceIdentifier | IRecentlyOpenedFile)[]): void;
addRecentlyOpened(workspaces: (IWorkspaceIdentifier | string)[], files: string[]): void;
getRecentlyOpened(currentWorkspace?: IWorkspaceIdentifier, currentFolderPath?: string, currentFiles?: IPath[]): IRecentlyOpened;
getRecentlyOpened(currentWorkspace?: IWorkspaceIdentifier | string, currentFiles?: IPath[]): IRecentlyOpened;
removeFromRecentlyOpened(toRemove: IWorkspaceIdentifier | string): void;
removeFromRecentlyOpened(toRemove: (IWorkspaceIdentifier | string)[]): void;
......
......@@ -16,8 +16,13 @@ import { getPathLabel } 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';
import { IWorkspaceIdentifier, IWorkspacesMainService } from "vs/platform/workspaces/common/workspaces";
import { IHistoryMainService, IRecentlyOpenedFile, IRecentlyOpened } from "vs/platform/history/common/history";
import { IWorkspaceIdentifier, IWorkspacesMainService, getWorkspaceLabel } from "vs/platform/workspaces/common/workspaces";
import { IHistoryMainService, IRecentlyOpened } from "vs/platform/history/common/history";
import { IEnvironmentService } from "vs/platform/environment/common/environment";
export interface ILegacyRecentlyOpened extends IRecentlyOpened {
folders: string[]; // TODO@Ben migration
}
export class HistoryMainService implements IHistoryMainService {
......@@ -33,97 +38,84 @@ export class HistoryMainService implements IHistoryMainService {
constructor(
@IStorageService private storageService: IStorageService,
@ILogService private logService: ILogService,
@IWorkspacesMainService private workspacesService: IWorkspacesMainService
@IWorkspacesMainService private workspacesService: IWorkspacesMainService,
@IEnvironmentService private environmentService: IEnvironmentService
) {
}
public addToRecentlyOpened(recent: (IWorkspaceIdentifier | IRecentlyOpenedFile)[]): void {
if (!recent || !recent.length) {
return;
}
const mru = this.getRecentlyOpened();
recent.forEach((workspaceOrFile: IWorkspaceIdentifier | IRecentlyOpenedFile) => {
public addRecentlyOpened(workspaces: (IWorkspaceIdentifier | string)[], files: string[]): void {
if ((workspaces && workspaces.length > 0) || (files && files.length > 0)) {
const mru = this.getRecentlyOpened();
// Add Workspace
if (this.isWorkspace(workspaceOrFile)) {
mru.workspaces.unshift(workspaceOrFile);
mru.workspaces = arrays.distinct(mru.workspaces, w => w.id);
// Workspaces
workspaces.forEach(workspace => {
mru.workspaces.unshift(workspace);
mru.workspaces = arrays.distinct(mru.workspaces, workspace => this.isSingleFolderWorkspace(workspace) ? workspace : workspace.id);
// Add to recent documents unless the workspace is untitled (Windows/macOS only)
if ((isMacintosh || isWindows) && !this.workspacesService.isUntitledWorkspace(workspaceOrFile)) {
app.addRecentDocument(workspaceOrFile.configPath);
// Add to recent documents unless the workspace is untitled (macOS only, Windows can show workspaces separately)
const isUntitledWorkspace = this.isWorkspace(workspace) && this.workspacesService.isUntitledWorkspace(workspace);
if (isMacintosh && !isUntitledWorkspace) {
app.addRecentDocument(this.isSingleFolderWorkspace(workspace) ? workspace : workspace.configPath);
}
}
});
// Add File/Folder
else {
const { path, isFile } = workspaceOrFile as IRecentlyOpenedFile;
if (isFile) {
mru.files.unshift(path);
mru.files = arrays.distinct(mru.files, f => isLinux ? f : f.toLowerCase());
} else {
mru.folders.unshift(path);
mru.folders = arrays.distinct(mru.folders, f => isLinux ? f : f.toLowerCase());
}
// Files
files.forEach((path) => {
mru.files.unshift(path);
mru.files = arrays.distinct(mru.files, f => isLinux ? f : f.toLowerCase());
// Add to recent documents (Windows/macOS only)
if (isMacintosh || isWindows) {
app.addRecentDocument(path);
}
}
});
// Make sure its bounded
mru.workspaces = mru.workspaces.slice(0, HistoryMainService.MAX_TOTAL_RECENT_ENTRIES);
mru.folders = mru.folders.slice(0, HistoryMainService.MAX_TOTAL_RECENT_ENTRIES);
mru.files = mru.files.slice(0, HistoryMainService.MAX_TOTAL_RECENT_ENTRIES);
});
this.storageService.setItem(HistoryMainService.recentlyOpenedStorageKey, mru);
this._onRecentlyOpenedChange.fire();
this.storageService.setItem(HistoryMainService.recentlyOpenedStorageKey, mru);
this._onRecentlyOpenedChange.fire();
}
}
private isWorkspace(obj: any): obj is IWorkspaceIdentifier {
return !!(obj as IWorkspaceIdentifier).id;
}
private isSingleFolderWorkspace(obj: any): obj is string {
return typeof obj === 'string';
}
public removeFromRecentlyOpened(toRemove: IWorkspaceIdentifier | string): void;
public removeFromRecentlyOpened(toRemove: (IWorkspaceIdentifier | string)[]): void;
public removeFromRecentlyOpened(arg1: any): void {
let workspacesOrFiles: any[];
let workspacesOrFilesToRemove: any[];
if (Array.isArray(arg1)) {
workspacesOrFiles = arg1;
workspacesOrFilesToRemove = arg1;
} else {
workspacesOrFiles = [arg1];
workspacesOrFilesToRemove = [arg1];
}
const mru = this.getRecentlyOpened();
let update = false;
workspacesOrFiles.forEach((workspaceOrFile: IWorkspaceIdentifier | string) => {
workspacesOrFilesToRemove.forEach((workspaceOrFileToRemove: IWorkspaceIdentifier | string) => {
// Remove workspace
if (this.isWorkspace(workspaceOrFile)) {
let index = arrays.firstIndex(mru.workspaces, w => w.id === workspaceOrFile.id);
if (index >= 0) {
mru.workspaces.splice(index, 1);
update = true;
}
let index = arrays.firstIndex(mru.workspaces, workspace => this.equals(workspace, workspaceOrFileToRemove));
if (index >= 0) {
mru.workspaces.splice(index, 1);
update = true;
}
// Remove file/folder
else {
let index = mru.files.indexOf(workspaceOrFile);
// Remove file
if (typeof workspaceOrFileToRemove === 'string') {
let index = mru.files.indexOf(workspaceOrFileToRemove);
if (index >= 0) {
mru.files.splice(index, 1);
update = true;
}
index = mru.folders.indexOf(workspaceOrFile);
if (index >= 0) {
mru.folders.splice(index, 1);
update = true;
}
}
});
......@@ -133,6 +125,18 @@ export class HistoryMainService implements IHistoryMainService {
}
}
private equals(w1: IWorkspaceIdentifier | string, w2: IWorkspaceIdentifier | string): boolean {
if (w1 === w2) {
return true;
}
if (typeof w1 === 'string' || typeof w2 === 'string') {
return false;
}
return w1.id === w2.id;
}
public clearRecentlyOpened(): void {
this.storageService.setItem(HistoryMainService.recentlyOpenedStorageKey, <IRecentlyOpened>{ workspaces: [], folders: [], files: [] });
app.clearRecentDocuments();
......@@ -141,21 +145,18 @@ export class HistoryMainService implements IHistoryMainService {
this._onRecentlyOpenedChange.fire();
}
public getRecentlyOpened(currentWorkspace?: IWorkspaceIdentifier, currentFolderPath?: string, currentFiles?: IPath[]): IRecentlyOpened {
let workspaces: IWorkspaceIdentifier[];
public getRecentlyOpened(currentWorkspace?: IWorkspaceIdentifier | string, currentFiles?: IPath[]): IRecentlyOpened {
let workspaces: (IWorkspaceIdentifier | string)[];
let files: string[];
let folders: string[];
// Get from storage
const storedRecents = this.storageService.getItem<IRecentlyOpened>(HistoryMainService.recentlyOpenedStorageKey);
const storedRecents = this.storageService.getItem<IRecentlyOpened>(HistoryMainService.recentlyOpenedStorageKey) as ILegacyRecentlyOpened;
if (storedRecents) {
workspaces = storedRecents.workspaces || [];
workspaces = storedRecents.workspaces || storedRecents.folders || [];
files = storedRecents.files || [];
folders = storedRecents.folders || [];
} else {
workspaces = [];
files = [];
folders = [];
}
// Add current workspace to beginning if set
......@@ -168,17 +169,11 @@ export class HistoryMainService implements IHistoryMainService {
files.unshift(...currentFiles.map(f => f.filePath));
}
// Add current folder path to beginning if set
if (currentFolderPath) {
folders.unshift(currentFolderPath);
}
// Clear those dupes
workspaces = arrays.distinct(workspaces, w => w.id);
workspaces = arrays.distinct(workspaces, workspace => this.isSingleFolderWorkspace(workspace) ? workspace : workspace.id);
files = arrays.distinct(files);
folders = arrays.distinct(folders);
return { workspaces, files, folders };
return { workspaces, files };
}
public updateWindowsJumpList(): void {
......@@ -204,8 +199,8 @@ export class HistoryMainService implements IHistoryMainService {
]
});
// Recent Folders
if (this.getRecentlyOpened().folders.length > 0) {
// Recent Workspaces
if (this.getRecentlyOpened().workspaces.length > 0) {
// The user might have meanwhile removed items from the jump list and we have to respect that
// so we need to update our list of recent paths with the choice of the user to not add them again
......@@ -216,14 +211,17 @@ export class HistoryMainService implements IHistoryMainService {
// Add entries
jumpList.push({
type: 'custom',
name: nls.localize('recentFolders', "Recent Folders"),
items: this.getRecentlyOpened().folders.slice(0, 7 /* limit number of entries here */).map(folder => {
name: nls.localize('recentFolders', "Recent Workspaces"),
items: this.getRecentlyOpened().workspaces.slice(0, 7 /* limit number of entries here */).map(workspace => {
const title = this.isSingleFolderWorkspace(workspace) ? (path.basename(workspace) || workspace) : getWorkspaceLabel(this.environmentService, workspace);
const description = this.isSingleFolderWorkspace(workspace) ? nls.localize('folderDesc', "{0} {1}", path.basename(workspace), getPathLabel(path.dirname(workspace))) : nls.localize('codeWorkspace', "Code Workspace");
return <Electron.JumpListItem>{
type: 'task',
title: path.basename(folder) || folder, // use the base name to show shorter entries in the list
description: nls.localize('folderDesc', "{0} {1}", path.basename(folder), getPathLabel(path.dirname(folder))),
title,
description,
program: process.execPath,
args: `"${folder}"`, // open folder (use quotes to support paths with whitespaces)
args: `"${this.isSingleFolderWorkspace(workspace) ? workspace : workspace.configPath}"`, // open folder (use quotes to support paths with whitespaces)
iconPath: 'explorer.exe', // simulate folder icon
iconIndex: 0
};
......
......@@ -12,7 +12,7 @@ import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
import { IProcessEnvironment } from 'vs/base/common/platform';
import { ParsedArgs } from 'vs/platform/environment/common/environment';
import { IWorkspaceIdentifier } from "vs/platform/workspaces/common/workspaces";
import { IRecentlyOpenedFile, IRecentlyOpened } from "vs/platform/history/common/history";
import { IRecentlyOpened } from "vs/platform/history/common/history";
export const IWindowsService = createDecorator<IWindowsService>('windowsService');
......@@ -33,7 +33,7 @@ export interface IWindowsService {
closeWorkspace(windowId: number): TPromise<void>;
toggleFullScreen(windowId: number): TPromise<void>;
setRepresentedFilename(windowId: number, fileName: string): TPromise<void>;
addToRecentlyOpened(recent: (IWorkspaceIdentifier | IRecentlyOpenedFile)[]): TPromise<void>;
addRecentlyOpened(files: string[]): TPromise<void>;
removeFromRecentlyOpened(toRemove: (IWorkspaceIdentifier | string)[]): TPromise<void>;
clearRecentlyOpened(): TPromise<void>;
getRecentlyOpened(windowId: number): TPromise<IRecentlyOpened>;
......
......@@ -11,7 +11,7 @@ import { IChannel, eventToCall, eventFromCall } from 'vs/base/parts/ipc/common/i
import { IWindowsService } from './windows';
import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
import { IWorkspaceIdentifier } from "vs/platform/workspaces/common/workspaces";
import { IRecentlyOpenedFile, IRecentlyOpened } from "vs/platform/history/common/history";
import { IRecentlyOpened } from "vs/platform/history/common/history";
export interface IWindowsChannel extends IChannel {
call(command: 'event:onWindowOpen'): TPromise<number>;
......@@ -25,7 +25,7 @@ export interface IWindowsChannel extends IChannel {
call(command: 'closeWorkspace', arg: number): TPromise<void>;
call(command: 'toggleFullScreen', arg: number): TPromise<void>;
call(command: 'setRepresentedFilename', arg: [number, string]): TPromise<void>;
call(command: 'addToRecentlyOpened', arg: (IWorkspaceIdentifier | IRecentlyOpenedFile)[]): TPromise<void>;
call(command: 'addRecentlyOpened', arg: string[]): TPromise<void>;
call(command: 'removeFromRecentlyOpened', arg: (IWorkspaceIdentifier | string)[]): TPromise<void>;
call(command: 'clearRecentlyOpened'): TPromise<void>;
call(command: 'getRecentlyOpened', arg: number): TPromise<IRecentlyOpened>;
......@@ -78,7 +78,7 @@ export class WindowsChannel implements IWindowsChannel {
case 'closeWorkspace': return this.service.closeWorkspace(arg);
case 'toggleFullScreen': return this.service.toggleFullScreen(arg);
case 'setRepresentedFilename': return this.service.setRepresentedFilename(arg[0], arg[1]);
case 'addToRecentlyOpened': return this.service.addToRecentlyOpened(arg);
case 'addRecentlyOpened': return this.service.addRecentlyOpened(arg);
case 'removeFromRecentlyOpened': return this.service.removeFromRecentlyOpened(arg);
case 'clearRecentlyOpened': return this.service.clearRecentlyOpened();
case 'getRecentlyOpened': return this.service.getRecentlyOpened(arg);
......@@ -161,8 +161,8 @@ export class WindowsChannelClient implements IWindowsService {
return this.channel.call('setRepresentedFilename', [windowId, fileName]);
}
addToRecentlyOpened(recent: (IWorkspaceIdentifier | IRecentlyOpenedFile)[]): TPromise<void> {
return this.channel.call('addToRecentlyOpened', recent);
addRecentlyOpened(files: string[]): TPromise<void> {
return this.channel.call('addRecentlyOpened', files);
}
removeFromRecentlyOpened(toRemove: (IWorkspaceIdentifier | string)[]): TPromise<void> {
......
......@@ -18,7 +18,7 @@ import { IURLService } from 'vs/platform/url/common/url';
import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
import { ILifecycleService } from "vs/platform/lifecycle/electron-main/lifecycleMain";
import { IWindowsMainService, ISharedProcess } from "vs/platform/windows/electron-main/windows";
import { IHistoryMainService, IRecentlyOpenedFile, IRecentlyOpened } from "vs/platform/history/common/history";
import { IHistoryMainService, IRecentlyOpened } from "vs/platform/history/common/history";
import { findExtensionDevelopmentWindow } from "vs/code/node/windowsFinder";
import { IWorkspaceIdentifier } from "vs/platform/workspaces/common/workspaces";
......@@ -140,8 +140,8 @@ export class WindowsService implements IWindowsService, IDisposable {
return TPromise.as(null);
}
addToRecentlyOpened(recent: (IWorkspaceIdentifier | IRecentlyOpenedFile)[]): TPromise<void> {
this.historyService.addToRecentlyOpened(recent);
addRecentlyOpened(files: string[]): TPromise<void> {
this.historyService.addRecentlyOpened(void 0, files);
return TPromise.as(null);
}
......@@ -162,12 +162,12 @@ export class WindowsService implements IWindowsService, IDisposable {
const codeWindow = this.windowsMainService.getWindowById(windowId);
if (codeWindow) {
const recentlyOpened = this.historyService.getRecentlyOpened(codeWindow.config.workspace, codeWindow.config.folderPath, codeWindow.config.filesToOpen);
const recentlyOpened = this.historyService.getRecentlyOpened(codeWindow.config.workspace || codeWindow.config.folderPath, codeWindow.config.filesToOpen);
return TPromise.as(recentlyOpened);
}
return TPromise.as(<IRecentlyOpened>{ workspaces: [], files: [], folders: [] });
return TPromise.as(<IRecentlyOpened>{ workspaces: [], files: [] });
}
focusWindow(windowId: number): TPromise<void> {
......
......@@ -1118,12 +1118,7 @@ export class EditorGroupsControl extends Themable implements IEditorGroupsContro
// Add external ones to recently open list
const externalResources = droppedResources.filter(d => d.isExternal).map(d => d.resource);
if (externalResources.length) {
$this.windowsService.addToRecentlyOpened(externalResources.map(resource => {
return {
path: resource.fsPath,
isFile: true
};
}));
$this.windowsService.addRecentlyOpened(externalResources.map(resource => resource.fsPath));
}
// Open in Editor
......
......@@ -691,12 +691,7 @@ export class TabsTitleControl extends TitleControl {
// Add external ones to recently open list
const externalResources = resources.filter(d => d.isExternal).map(d => d.resource);
if (externalResources.length) {
this.windowsService.addToRecentlyOpened(externalResources.map(resource => {
return {
path: resource.fsPath,
isFile: true
};
}));
this.windowsService.addRecentlyOpened(externalResources.map(resource => resource.fsPath));
}
// Open in Editor
......
......@@ -665,10 +665,10 @@ export abstract class BaseOpenRecentAction extends Action {
public run(): TPromise<void> {
return this.windowService.getRecentlyOpened()
.then(({ workspaces, files, folders }) => this.openRecent(workspaces, files, folders));
.then(({ workspaces, files }) => this.openRecent(workspaces, files));
}
private openRecent(recentWorkspaces: IWorkspaceIdentifier[], recentFiles: string[], recentFolders: string[]): void {
private openRecent(recentWorkspaces: (IWorkspaceIdentifier | string)[], recentFiles: string[]): void {
function toPick(arg1: IWorkspaceIdentifier | string, separator: ISeparator, isFolder: boolean, environmentService: IEnvironmentService): IFilePickOpenEntry {
const path = (typeof arg1 === 'string') ? arg1 : arg1.configPath;
......@@ -696,25 +696,14 @@ export abstract class BaseOpenRecentAction extends Action {
this.windowsService.openWindow([typeof arg1 === 'string' ? arg1 : arg1.configPath], { forceNewWindow });
};
const workspacePicks: IFilePickOpenEntry[] = recentWorkspaces.map((p, index) => toPick(p, index === 0 ? { label: nls.localize('workspaces', "workspaces") } : void 0, false, this.environmentService));
const folderPicks: IFilePickOpenEntry[] = recentFolders.map((p, index) => toPick(p, index === 0 ? { label: nls.localize('folders', "folders") } : void 0, true, this.environmentService));
const workspacePicks: IFilePickOpenEntry[] = recentWorkspaces.map((workspace, index) => toPick(workspace, index === 0 ? { label: nls.localize('workspaces', "workspaces") } : void 0, true, this.environmentService));
const filePicks: IFilePickOpenEntry[] = recentFiles.map((p, index) => toPick(p, index === 0 ? { label: nls.localize('files', "files"), border: true } : void 0, false, this.environmentService));
const hasWorkspace = this.contextService.hasWorkspace();
let autoFocusFirstEntry = !hasWorkspace;
let autoFocusSecondEntry = !autoFocusFirstEntry;
if (workspacePicks.length > 0 && folderPicks.length > 0) {
// if we show both workspace picks and folder picks, we can no longer make any smart
// auto focus choice because the list is no longer in pure MRU order. In this case
// we simply do not focus any entry.
autoFocusFirstEntry = false;
autoFocusSecondEntry = false;
}
this.quickOpenService.pick([...workspacePicks, ...folderPicks, ...filePicks], {
this.quickOpenService.pick([...workspacePicks, ...filePicks], {
contextKey: inRecentFilesPickerContextKey,
autoFocus: { autoFocusFirstEntry, autoFocusSecondEntry },
autoFocus: { autoFocusFirstEntry: !hasWorkspace, autoFocusSecondEntry: hasWorkspace },
placeHolder: isMacintosh ? nls.localize('openRecentPlaceHolderMac', "Select to open (hold Cmd-key to open in new window)") : nls.localize('openRecentPlaceHolder', "Select to open (hold Ctrl-key to open in new window)"),
matchOnDescription: true,
quickNavigateConfiguration: this.isQuickNavigate() ? { keybindings: this.keybindingService.lookupKeybindings(this.id) } : void 0
......
......@@ -39,6 +39,7 @@ import { registerColor, focusBorder, textLinkForeground, textLinkActiveForegroun
import { getExtraColor } from 'vs/workbench/parts/welcome/walkThrough/node/walkThroughUtils';
import { IExtensionsWorkbenchService } from 'vs/workbench/parts/extensions/common/extensions';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IWorkspaceIdentifier, getWorkspaceLabel } from "vs/platform/workspaces/common/workspaces";
used();
......@@ -200,7 +201,7 @@ class WelcomePage {
.then(null, onUnexpectedError);
}
private onReady(container: HTMLElement, recentlyOpened: TPromise<{ files: string[]; folders: string[]; }>, installedExtensions: TPromise<IExtensionStatus[]>): void {
private onReady(container: HTMLElement, recentlyOpened: TPromise<{ files: string[]; workspaces: (IWorkspaceIdentifier | string)[]; }>, installedExtensions: TPromise<IExtensionStatus[]>): void {
const enabled = isWelcomePageEnabled(this.configurationService);
const showOnStartup = <HTMLInputElement>container.querySelector('#showOnStartup');
if (enabled) {
......@@ -210,24 +211,36 @@ class WelcomePage {
this.configurationEditingService.writeConfiguration(ConfigurationTarget.USER, { key: configurationKey, value: showOnStartup.checked ? 'welcomePage' : 'newUntitledFile' });
});
recentlyOpened.then(({ folders }) => {
if (this.contextService.hasWorkspace()) {
const currents = this.contextService.getWorkspace().roots;
folders = folders.filter(folder => !currents.some(current => this.pathEquals(folder, current.fsPath)));
}
if (!folders.length) {
recentlyOpened.then(({ workspaces }) => {
const context = this.contextService.getWorkspace();
workspaces = workspaces.filter(workspace => {
if (this.contextService.hasMultiFolderWorkspace() && typeof workspace !== 'string' && context.id === workspace.id) {
return false; // do not show current workspace
}
if (this.contextService.hasFolderWorkspace() && typeof workspace === 'string' && this.pathEquals(context.roots[0].fsPath, workspace)) {
return false; // do not show current workspace (single folder case)
}
return true;
});
if (!workspaces.length) {
const recent = container.querySelector('.welcomePage') as HTMLElement;
recent.classList.add('emptyRecent');
return;
}
const ul = container.querySelector('.recent ul');
const before = ul.firstElementChild;
folders.slice(0, 5).forEach(folder => {
workspaces.slice(0, 5).forEach(workspace => {
const label = (typeof workspace === 'string') ? path.basename(workspace) : getWorkspaceLabel(this.environmentService, workspace);
const parent = (typeof workspace === 'string') ? path.dirname(workspace) : '';
const wsPath = (typeof workspace === 'string') ? workspace : workspace.configPath;
const li = document.createElement('li');
const a = document.createElement('a');
let name = path.basename(folder);
let parentFolder = path.dirname(folder);
let name = label;
let parentFolder = parent;
if (!name && parentFolder) {
const tmp = name;
name = parentFolder;
......@@ -236,7 +249,7 @@ class WelcomePage {
const tildifiedParentFolder = tildify(parentFolder, this.environmentService.userHome);
a.innerText = name;
a.title = folder;
a.title = label;
a.setAttribute('aria-label', localize('welcomePage.openFolderWithPath', "Open folder {0} with path {1}", name, tildifiedParentFolder));
a.href = 'javascript:void(0)';
a.addEventListener('click', e => {
......@@ -244,7 +257,7 @@ class WelcomePage {
id: 'openRecentFolder',
from: telemetryFrom
});
this.windowsService.openWindow([folder], { forceNewWindow: e.ctrlKey || e.metaKey });
this.windowsService.openWindow([wsPath], { forceNewWindow: e.ctrlKey || e.metaKey });
e.preventDefault();
e.stopPropagation();
});
......@@ -254,7 +267,7 @@ class WelcomePage {
span.classList.add('path');
span.classList.add('detail');
span.innerText = tildifiedParentFolder;
span.title = folder;
span.title = label;
li.appendChild(span);
ul.insertBefore(li, before);
......
......@@ -55,7 +55,7 @@ import { isLinux } from 'vs/base/common/platform';
import { generateUuid } from 'vs/base/common/uuid';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
import { IWorkspaceIdentifier } from "vs/platform/workspaces/common/workspaces";
import { IRecentlyOpened, IRecentlyOpenedFile } from "vs/platform/history/common/history";
import { IRecentlyOpened } from "vs/platform/history/common/history";
export function createFileInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput {
return instantiationService.createInstance(FileEditorInput, resource, void 0);
......@@ -1022,7 +1022,7 @@ export class TestWindowsService implements IWindowsService {
return TPromise.as(void 0);
}
addToRecentlyOpened(recent: (IWorkspaceIdentifier | IRecentlyOpenedFile)[]): TPromise<void> {
addRecentlyOpened(files: string[]): TPromise<void> {
return TPromise.as(void 0);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册