mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-03 23:06:49 +01:00
Support file-uris as arguments
This commit is contained in:
@@ -64,6 +64,7 @@ import { IMenubarService } from 'vs/platform/menubar/common/menubar';
|
||||
import { MenubarService } from 'vs/platform/menubar/electron-main/menubarService';
|
||||
import { MenubarChannel } from 'vs/platform/menubar/common/menubarIpc';
|
||||
import { IUriDisplayService } from 'vs/platform/uriDisplay/common/uriDisplay';
|
||||
import { asArray } from 'vs/code/node/args';
|
||||
|
||||
export class CodeApplication {
|
||||
|
||||
@@ -466,12 +467,16 @@ export class CodeApplication {
|
||||
// Open our first window
|
||||
const macOpenFiles = (<any>global).macOpenFiles as string[];
|
||||
const context = !!process.env['VSCODE_CLI'] ? OpenContext.CLI : OpenContext.DESKTOP;
|
||||
if (args['new-window'] && args._.length === 0 && (args['folder-uri'] || []).length === 0) {
|
||||
const cliArgs = args._ || [];
|
||||
const folderURIs = asArray(args['folder-uri']);
|
||||
const fileURIs = asArray(args['file-uri']);
|
||||
|
||||
if (args['new-window'] && !cliArgs.length && !folderURIs.length && !fileURIs.length) {
|
||||
this.windowsMainService.open({ context, cli: args, forceNewWindow: true, forceEmpty: true, initialStartup: true }); // new window if "-n" was used without paths
|
||||
} else if (macOpenFiles && macOpenFiles.length && (!args._ || !args._.length || !args['folder-uri'] || !args['folder-uri'].length)) {
|
||||
} else if (macOpenFiles && macOpenFiles.length && !cliArgs.length && !folderURIs.length && !fileURIs.length) {
|
||||
this.windowsMainService.open({ context: OpenContext.DOCK, cli: args, urisToOpen: macOpenFiles.map(file => URI.file(file)), initialStartup: true }); // mac: open-file event received on startup
|
||||
} else {
|
||||
this.windowsMainService.open({ context, cli: args, forceNewWindow: args['new-window'] || (!args._.length && args['unity-launch']), diffMode: args.diff, initialStartup: true }); // default: read paths from cli
|
||||
this.windowsMainService.open({ context, cli: args, forceNewWindow: args['new-window'] || (!cliArgs.length && args['unity-launch']), diffMode: args.diff, initialStartup: true }); // default: read paths from cli
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
|
||||
import URI, { UriComponents } from 'vs/base/common/uri';
|
||||
import { BrowserWindow } from 'electron';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { asArray } from 'vs/code/node/args';
|
||||
|
||||
export const ID = 'launchService';
|
||||
export const ILaunchService = createDecorator<ILaunchService>(ID);
|
||||
@@ -178,7 +179,7 @@ export class LaunchService implements ILaunchService {
|
||||
}
|
||||
|
||||
// Start without file/folder arguments
|
||||
else if (args._.length === 0 && (args['folder-uri'] || []).length === 0) {
|
||||
else if (args._.length === 0 && !asArray(args['folder-uri'].length && !asArray(args['file-uri'].length))) {
|
||||
let openNewWindow = false;
|
||||
|
||||
// Force new window
|
||||
|
||||
@@ -527,18 +527,18 @@ export class Menubar {
|
||||
}
|
||||
}
|
||||
|
||||
private createOpenRecentMenuItem(workspace: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | string, commandId: string, isFile: boolean): Electron.MenuItem {
|
||||
private createOpenRecentMenuItem(workspaceOrFile: IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier | URI, commandId: string, isFile: boolean): Electron.MenuItem {
|
||||
let label: string;
|
||||
let uri: URI;
|
||||
if (isSingleFolderWorkspaceIdentifier(workspace)) {
|
||||
label = unmnemonicLabel(getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService, { verbose: true }));
|
||||
uri = workspace;
|
||||
} else if (isWorkspaceIdentifier(workspace)) {
|
||||
label = getWorkspaceLabel(workspace, this.environmentService, this.uriDisplayService, { verbose: true });
|
||||
uri = URI.file(workspace.configPath);
|
||||
if (isSingleFolderWorkspaceIdentifier(workspaceOrFile) && !isFile) {
|
||||
label = unmnemonicLabel(getWorkspaceLabel(workspaceOrFile, this.environmentService, this.uriDisplayService, { verbose: true }));
|
||||
uri = workspaceOrFile;
|
||||
} else if (isWorkspaceIdentifier(workspaceOrFile)) {
|
||||
label = getWorkspaceLabel(workspaceOrFile, this.environmentService, this.uriDisplayService, { verbose: true });
|
||||
uri = URI.file(workspaceOrFile.configPath);
|
||||
} else {
|
||||
uri = URI.file(workspace);
|
||||
label = unmnemonicLabel(this.uriDisplayService.getLabel(uri));
|
||||
label = unmnemonicLabel(this.uriDisplayService.getLabel(workspaceOrFile));
|
||||
uri = workspaceOrFile;
|
||||
}
|
||||
|
||||
return new MenuItem(this.likeAction(commandId, {
|
||||
@@ -554,7 +554,7 @@ export class Menubar {
|
||||
}).length > 0;
|
||||
|
||||
if (!success) {
|
||||
this.historyMainService.removeFromRecentlyOpened([workspace]);
|
||||
this.historyMainService.removeFromRecentlyOpened([workspaceOrFile]);
|
||||
}
|
||||
}
|
||||
}, false));
|
||||
|
||||
@@ -14,6 +14,7 @@ import { IBackupMainService } from 'vs/platform/backup/common/backup';
|
||||
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import { IStateService } from 'vs/platform/state/common/state';
|
||||
import { CodeWindow, defaultWindowState } from 'vs/code/electron-main/window';
|
||||
import { asArray } from 'vs/code/node/args';
|
||||
import { ipcMain as ipc, screen, BrowserWindow, dialog, systemPreferences, app } from 'electron';
|
||||
import { IPathWithLineAndColumn, parseLineAndColumnAware } from 'vs/code/node/paths';
|
||||
import { ILifecycleService, UnloadReason, IWindowUnloadEvent } from 'vs/platform/lifecycle/electron-main/lifecycleMain';
|
||||
@@ -365,8 +366,8 @@ export class WindowsManager implements IWindowsMainService {
|
||||
pathsToOpen = pathsToOpen.filter(path => !path.folderUri);
|
||||
}
|
||||
|
||||
let filesToOpen = pathsToOpen.filter(path => !!path.filePath && !path.createFilePath);
|
||||
let filesToCreate = pathsToOpen.filter(path => !!path.filePath && path.createFilePath);
|
||||
let filesToOpen = pathsToOpen.filter(path => !!path.fileUri && !path.createFilePath);
|
||||
let filesToCreate = pathsToOpen.filter(path => !!path.fileUri && path.createFilePath);
|
||||
|
||||
// When run with --diff, take the files to open as files to diff
|
||||
// if there are exactly two files provided.
|
||||
@@ -391,7 +392,7 @@ export class WindowsManager implements IWindowsMainService {
|
||||
//
|
||||
// These are windows to open to show either folders or files (including diffing files or creating them)
|
||||
//
|
||||
const foldersToOpen = arrays.distinct(pathsToOpen.filter(win => win.folderUri && !win.filePath).map(win => win.folderUri), folder => getComparisonKey(folder)); // prevent duplicates
|
||||
const foldersToOpen = arrays.distinct(pathsToOpen.filter(win => win.folderUri && !win.fileUri).map(win => win.folderUri), folder => getComparisonKey(folder)); // prevent duplicates
|
||||
|
||||
//
|
||||
// These are windows to restore because of hot-exit or from previous session (only performed once on startup!)
|
||||
@@ -413,7 +414,7 @@ export class WindowsManager implements IWindowsMainService {
|
||||
//
|
||||
// These are empty windows to open
|
||||
//
|
||||
const emptyToOpen = pathsToOpen.filter(win => !win.workspace && !win.folderUri && !win.filePath && !win.backupPath).length;
|
||||
const emptyToOpen = pathsToOpen.filter(win => !win.workspace && !win.folderUri && !win.fileUri && !win.backupPath).length;
|
||||
|
||||
// Open based on config
|
||||
const usedWindows = this.doOpen(openConfig, workspacesToOpen, workspacesToRestore, foldersToOpen, foldersToRestore, emptyToRestore, emptyToOpen, filesToOpen, filesToCreate, filesToDiff, filesToWait, foldersToAdd);
|
||||
@@ -421,7 +422,7 @@ export class WindowsManager implements IWindowsMainService {
|
||||
// Make sure to pass focus to the most relevant of the windows if we open multiple
|
||||
if (usedWindows.length > 1) {
|
||||
|
||||
let focusLastActive = this.windowsState.lastActiveWindow && !openConfig.forceEmpty && !openConfig.cli._.length && !(openConfig.cli['folder-uri'] || []).length && !(openConfig.urisToOpen || []).length;
|
||||
let focusLastActive = this.windowsState.lastActiveWindow && !openConfig.forceEmpty && !openConfig.cli._.length && !asArray(openConfig.cli['file-uri']).length && !asArray(openConfig.cli['folder-uri']).length && !asArray(openConfig.urisToOpen).length;
|
||||
let focusLastOpened = true;
|
||||
let focusLastWindow = true;
|
||||
|
||||
@@ -463,13 +464,13 @@ export class WindowsManager implements IWindowsMainService {
|
||||
// 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 recentlyOpenedWorkspaces: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)[] = [];
|
||||
const recentlyOpenedFiles: string[] = [];
|
||||
const recentlyOpenedFiles: URI[] = [];
|
||||
|
||||
pathsToOpen.forEach(win => {
|
||||
if (win.workspace || win.folderUri) {
|
||||
recentlyOpenedWorkspaces.push(win.workspace || win.folderUri);
|
||||
} else if (win.filePath) {
|
||||
recentlyOpenedFiles.push(win.filePath);
|
||||
} else if (win.fileUri) {
|
||||
recentlyOpenedFiles.push(win.fileUri);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -539,7 +540,7 @@ export class WindowsManager implements IWindowsMainService {
|
||||
newWindow: openFilesInNewWindow,
|
||||
reuseWindow: openConfig.forceReuseWindow,
|
||||
context: openConfig.context,
|
||||
filePath: fileToCheck && fileToCheck.filePath,
|
||||
fileUri: fileToCheck && fileToCheck.fileUri,
|
||||
workspaceResolver: workspace => this.workspacesMainService.resolveWorkspaceSync(workspace.configPath)
|
||||
});
|
||||
|
||||
@@ -789,7 +790,7 @@ export class WindowsManager implements IWindowsMainService {
|
||||
}
|
||||
|
||||
// Extract paths: from CLI
|
||||
else if (openConfig.cli._.length > 0 || (openConfig.cli['folder-uri'] || []).length > 0) {
|
||||
else if (openConfig.cli._.length > 0 || asArray(openConfig.cli['folder-uri']).length > 0 || asArray(openConfig.cli['file-uri']).length > 0) {
|
||||
windowsToOpen = this.doExtractPathsFromCLI(openConfig.cli);
|
||||
isCommandLineOrAPICall = true;
|
||||
}
|
||||
@@ -819,7 +820,7 @@ export class WindowsManager implements IWindowsMainService {
|
||||
|
||||
private doExtractPathsFromAPI(openConfig: IOpenConfiguration): IPath[] {
|
||||
let pathsToOpen = openConfig.urisToOpen.map(pathToOpen => {
|
||||
const path = this.parseUri(pathToOpen, { gotoLineMode: openConfig.cli && openConfig.cli.goto, forceOpenWorkspaceAsFile: openConfig.forceOpenWorkspaceAsFile });
|
||||
const path = this.parseUri(pathToOpen, openConfig.forceOpenWorkspaceAsFile, { gotoLineMode: openConfig.cli && openConfig.cli.goto, forceOpenWorkspaceAsFile: openConfig.forceOpenWorkspaceAsFile });
|
||||
|
||||
// Warn if the requested path to open does not exist
|
||||
if (!path) {
|
||||
@@ -848,10 +849,15 @@ export class WindowsManager implements IWindowsMainService {
|
||||
const pathsToOpen = [];
|
||||
|
||||
// folder uris
|
||||
if (cli['folder-uri'] && cli['folder-uri'].length) {
|
||||
const arg = cli['folder-uri'];
|
||||
const folderUris: string[] = typeof arg === 'string' ? [arg] : arg;
|
||||
pathsToOpen.push(...arrays.coalesce(folderUris.map(candidate => this.parseUri(this.parseFolderUriArg(candidate), { ignoreFileNotFound: true, gotoLineMode: cli.goto }))));
|
||||
const folderUris = asArray(cli['folder-uri']);
|
||||
if (folderUris.length) {
|
||||
pathsToOpen.push(...arrays.coalesce(folderUris.map(candidate => this.parseUri(this.parseUriArg(candidate), false, { ignoreFileNotFound: true, gotoLineMode: cli.goto }))));
|
||||
}
|
||||
|
||||
// file uris
|
||||
const fileUris = asArray(cli['file-uri']);
|
||||
if (fileUris.length) {
|
||||
pathsToOpen.push(...arrays.coalesce(fileUris.map(candidate => this.parseUri(this.parseUriArg(candidate), true, { ignoreFileNotFound: true, gotoLineMode: cli.goto }))));
|
||||
}
|
||||
|
||||
// folder or file paths
|
||||
@@ -892,7 +898,7 @@ export class WindowsManager implements IWindowsMainService {
|
||||
|
||||
// folder (if path is valid)
|
||||
else if (lastActiveWindow.folderUri) {
|
||||
const validatedFolder = this.parseUri(lastActiveWindow.folderUri);
|
||||
const validatedFolder = this.parseUri(lastActiveWindow.folderUri, false);
|
||||
if (validatedFolder && validatedFolder.folderUri) {
|
||||
return [validatedFolder];
|
||||
}
|
||||
@@ -923,7 +929,7 @@ export class WindowsManager implements IWindowsMainService {
|
||||
if (lastActiveWindow && lastActiveWindow.folderUri) {
|
||||
folderCandidates.push(lastActiveWindow.folderUri);
|
||||
}
|
||||
windowsToOpen.push(...folderCandidates.map(candidate => this.parseUri(candidate)).filter(window => window && window.folderUri));
|
||||
windowsToOpen.push(...folderCandidates.map(candidate => this.parseUri(candidate, false)).filter(window => window && window.folderUri));
|
||||
|
||||
// Windows that were Empty
|
||||
if (restoreWindows === 'all') {
|
||||
@@ -963,7 +969,7 @@ export class WindowsManager implements IWindowsMainService {
|
||||
return restoreWindows;
|
||||
}
|
||||
|
||||
private parseFolderUriArg(arg: string): URI {
|
||||
private parseUriArg(arg: string): URI {
|
||||
// Do not support if user has passed folder path on Windows
|
||||
if (isWindows && /^([a-z])\:(.*)$/i.test(arg)) {
|
||||
return null;
|
||||
@@ -971,7 +977,7 @@ export class WindowsManager implements IWindowsMainService {
|
||||
return URI.parse(arg);
|
||||
}
|
||||
|
||||
private parseUri(anyUri: URI, options?: { ignoreFileNotFound?: boolean, gotoLineMode?: boolean, forceOpenWorkspaceAsFile?: boolean; }): IPathToOpen {
|
||||
private parseUri(anyUri: URI, isFile: boolean, options?: { ignoreFileNotFound?: boolean, gotoLineMode?: boolean, forceOpenWorkspaceAsFile?: boolean; }): IPathToOpen {
|
||||
if (!anyUri || !anyUri.scheme) {
|
||||
return null;
|
||||
}
|
||||
@@ -979,7 +985,11 @@ export class WindowsManager implements IWindowsMainService {
|
||||
if (anyUri.scheme === Schemas.file) {
|
||||
return this.parsePath(anyUri.fsPath, options);
|
||||
}
|
||||
|
||||
if (isFile) {
|
||||
return {
|
||||
fileUri: anyUri
|
||||
};
|
||||
}
|
||||
return {
|
||||
folderUri: anyUri
|
||||
};
|
||||
@@ -1014,7 +1024,7 @@ export class WindowsManager implements IWindowsMainService {
|
||||
|
||||
// File
|
||||
return {
|
||||
filePath: candidate,
|
||||
fileUri: URI.file(candidate),
|
||||
lineNumber: gotoLineMode ? parsedPath.line : void 0,
|
||||
columnNumber: gotoLineMode ? parsedPath.column : void 0
|
||||
};
|
||||
@@ -1030,10 +1040,11 @@ export class WindowsManager implements IWindowsMainService {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
this.historyMainService.removeFromRecentlyOpened([candidate]); // since file does not seem to exist anymore, remove from recent
|
||||
const fileUri = URI.file(candidate);
|
||||
this.historyMainService.removeFromRecentlyOpened([fileUri]); // since file does not seem to exist anymore, remove from recent
|
||||
|
||||
if (options && options.ignoreFileNotFound) {
|
||||
return { filePath: candidate, createFilePath: true }; // assume this is a file that does not yet exist
|
||||
return { fileUri, createFilePath: true }; // assume this is a file that does not yet exist
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1093,38 +1104,46 @@ export class WindowsManager implements IWindowsMainService {
|
||||
|
||||
return;
|
||||
}
|
||||
let folderUris = asArray(openConfig.cli['folder-uri']);
|
||||
let fileUris = asArray(openConfig.cli['file-uri']);
|
||||
let cliArgs = openConfig.cli._;
|
||||
|
||||
// Fill in previously opened workspace unless an explicit path is provided and we are not unit testing
|
||||
if (openConfig.cli._.length === 0 && (openConfig.cli['folder-uri'] || []).length === 0 && !openConfig.cli.extensionTestsPath) {
|
||||
if (!cliArgs.length && !folderUris.length && !fileUris.length && !openConfig.cli.extensionTestsPath) {
|
||||
const extensionDevelopmentWindowState = this.windowsState.lastPluginDevelopmentHostWindow;
|
||||
const workspaceToOpen = extensionDevelopmentWindowState && (extensionDevelopmentWindowState.workspace || extensionDevelopmentWindowState.folderUri);
|
||||
if (workspaceToOpen) {
|
||||
if (isSingleFolderWorkspaceIdentifier(workspaceToOpen)) {
|
||||
if (workspaceToOpen.scheme === Schemas.file) {
|
||||
openConfig.cli._ = [workspaceToOpen.fsPath];
|
||||
cliArgs = [workspaceToOpen.fsPath];
|
||||
} else {
|
||||
openConfig.cli['folder-uri'] = [workspaceToOpen.toString()];
|
||||
folderUris = [workspaceToOpen.toString()];
|
||||
}
|
||||
} else {
|
||||
openConfig.cli._ = [workspaceToOpen.configPath];
|
||||
cliArgs = [workspaceToOpen.configPath];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we are not asked to open a workspace or folder that is already opened
|
||||
if (openConfig.cli._.some(path => !!findWindowOnWorkspaceOrFolderUri(WindowsManager.WINDOWS, URI.file(path)))) {
|
||||
openConfig.cli._ = [];
|
||||
}
|
||||
if (openConfig.cli['folder-uri']) {
|
||||
const arg = openConfig.cli['folder-uri'];
|
||||
const folderUris: string[] = typeof arg === 'string' ? [arg] : arg;
|
||||
if (folderUris.some(uri => !!findWindowOnWorkspaceOrFolderUri(WindowsManager.WINDOWS, this.parseFolderUriArg(uri)))) {
|
||||
openConfig.cli['folder-uri'] = [];
|
||||
}
|
||||
if (cliArgs.length && cliArgs.some(path => !!findWindowOnWorkspaceOrFolderUri(WindowsManager.WINDOWS, URI.file(path)))) {
|
||||
cliArgs = [];
|
||||
}
|
||||
|
||||
if (folderUris.length && folderUris.some(uri => !!findWindowOnWorkspaceOrFolderUri(WindowsManager.WINDOWS, this.parseUriArg(uri)))) {
|
||||
folderUris = [];
|
||||
}
|
||||
|
||||
if (fileUris.length && fileUris.some(uri => !!findWindowOnWorkspaceOrFolderUri(WindowsManager.WINDOWS, this.parseUriArg(uri)))) {
|
||||
fileUris = [];
|
||||
}
|
||||
|
||||
openConfig.cli._ = cliArgs;
|
||||
openConfig.cli['folder-uri'] = folderUris;
|
||||
openConfig.cli['file-uri'] = fileUris;
|
||||
|
||||
// Open it
|
||||
this.open({ context: openConfig.context, cli: openConfig.cli, forceNewWindow: true, forceEmpty: openConfig.cli._.length === 0 && (openConfig.cli['folder-uri'] || []).length === 0, userEnv: openConfig.userEnv });
|
||||
this.open({ context: openConfig.context, cli: openConfig.cli, forceNewWindow: true, forceEmpty: !cliArgs.length && !folderUris.length && !fileUris.length, userEnv: openConfig.userEnv });
|
||||
}
|
||||
|
||||
private openInBrowserWindow(options: IOpenBrowserWindowOptions): ICodeWindow {
|
||||
|
||||
20
src/vs/code/node/args.ts
Normal file
20
src/vs/code/node/args.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Converts an arument into to an array
|
||||
* @param arg a argument value. Can be undefined, en entry or an array
|
||||
*/
|
||||
export function asArray<T>(arg: T | T[] | undefined): T[] {
|
||||
if (arg) {
|
||||
if (Array.isArray(arg)) {
|
||||
return arg;
|
||||
}
|
||||
return [arg];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
@@ -9,14 +9,13 @@ import * as platform from 'vs/base/common/platform';
|
||||
import * as paths from 'vs/base/common/paths';
|
||||
import { OpenContext } from 'vs/platform/windows/common/windows';
|
||||
import { IWorkspaceIdentifier, IResolvedWorkspace, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { hasToIgnoreCase, isEqual } from 'vs/base/common/resources';
|
||||
import { hasToIgnoreCase, isEqual, isEqualOrParent } from 'vs/base/common/resources';
|
||||
|
||||
export interface ISimpleWindow {
|
||||
openedWorkspace?: IWorkspaceIdentifier;
|
||||
openedFolderUri?: URI;
|
||||
openedFilePath?: string;
|
||||
openedFileUri?: URI;
|
||||
extensionDevelopmentPath?: string;
|
||||
lastFocusTime: number;
|
||||
}
|
||||
@@ -26,15 +25,15 @@ export interface IBestWindowOrFolderOptions<W extends ISimpleWindow> {
|
||||
newWindow: boolean;
|
||||
reuseWindow: boolean;
|
||||
context: OpenContext;
|
||||
filePath?: string;
|
||||
fileUri?: URI;
|
||||
userHome?: string;
|
||||
codeSettingsFolder?: string;
|
||||
workspaceResolver: (workspace: IWorkspaceIdentifier) => IResolvedWorkspace;
|
||||
}
|
||||
|
||||
export function findBestWindowOrFolderForFile<W extends ISimpleWindow>({ windows, newWindow, reuseWindow, context, filePath, workspaceResolver }: IBestWindowOrFolderOptions<W>): W {
|
||||
if (!newWindow && filePath && (context === OpenContext.DESKTOP || context === OpenContext.CLI || context === OpenContext.DOCK)) {
|
||||
const windowOnFilePath = findWindowOnFilePath(windows, filePath, workspaceResolver);
|
||||
export function findBestWindowOrFolderForFile<W extends ISimpleWindow>({ windows, newWindow, reuseWindow, context, fileUri, workspaceResolver }: IBestWindowOrFolderOptions<W>): W {
|
||||
if (!newWindow && fileUri && (context === OpenContext.DESKTOP || context === OpenContext.CLI || context === OpenContext.DOCK)) {
|
||||
const windowOnFilePath = findWindowOnFilePath(windows, fileUri, workspaceResolver);
|
||||
if (windowOnFilePath) {
|
||||
return windowOnFilePath;
|
||||
}
|
||||
@@ -43,20 +42,20 @@ export function findBestWindowOrFolderForFile<W extends ISimpleWindow>({ windows
|
||||
return !newWindow ? getLastActiveWindow(windows) : null;
|
||||
}
|
||||
|
||||
function findWindowOnFilePath<W extends ISimpleWindow>(windows: W[], filePath: string, workspaceResolver: (workspace: IWorkspaceIdentifier) => IResolvedWorkspace): W {
|
||||
function findWindowOnFilePath<W extends ISimpleWindow>(windows: W[], fileUri: URI, workspaceResolver: (workspace: IWorkspaceIdentifier) => IResolvedWorkspace): W {
|
||||
|
||||
// First check for windows with workspaces that have a parent folder of the provided path opened
|
||||
const workspaceWindows = windows.filter(window => !!window.openedWorkspace);
|
||||
for (let i = 0; i < workspaceWindows.length; i++) {
|
||||
const window = workspaceWindows[i];
|
||||
const resolvedWorkspace = workspaceResolver(window.openedWorkspace);
|
||||
if (resolvedWorkspace && resolvedWorkspace.folders.some(folder => folder.uri.scheme === Schemas.file && paths.isEqualOrParent(filePath, folder.uri.fsPath, !platform.isLinux /* ignorecase */))) {
|
||||
if (resolvedWorkspace && resolvedWorkspace.folders.some(folder => isEqualOrParent(fileUri, folder.uri, hasToIgnoreCase(fileUri)))) {
|
||||
return window;
|
||||
}
|
||||
}
|
||||
|
||||
// Then go with single folder windows that are parent of the provided file path
|
||||
const singleFolderWindowsOnFilePath = windows.filter(window => window.openedFolderUri && window.openedFolderUri.scheme === Schemas.file && paths.isEqualOrParent(filePath, window.openedFolderUri.fsPath, !platform.isLinux /* ignorecase */));
|
||||
const singleFolderWindowsOnFilePath = windows.filter(window => window.openedFolderUri && isEqualOrParent(fileUri, window.openedFolderUri, hasToIgnoreCase(fileUri)));
|
||||
if (singleFolderWindowsOnFilePath.length) {
|
||||
return singleFolderWindowsOnFilePath.sort((a, b) => -(a.openedFolderUri.path.length - b.openedFolderUri.path.length))[0];
|
||||
}
|
||||
|
||||
@@ -45,32 +45,32 @@ suite('WindowsFinder', () => {
|
||||
test('New window without folder when no windows exist', () => {
|
||||
assert.equal(findBestWindowOrFolderForFile(options()), null);
|
||||
assert.equal(findBestWindowOrFolderForFile(options({
|
||||
filePath: path.join(fixturesFolder, 'no_vscode_folder', 'file.txt')
|
||||
fileUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'file.txt'))
|
||||
})), null);
|
||||
assert.equal(findBestWindowOrFolderForFile(options({
|
||||
filePath: path.join(fixturesFolder, 'vscode_folder', 'file.txt'),
|
||||
fileUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'file.txt')),
|
||||
newWindow: true
|
||||
})), null);
|
||||
assert.equal(findBestWindowOrFolderForFile(options({
|
||||
filePath: path.join(fixturesFolder, 'vscode_folder', 'file.txt'),
|
||||
fileUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'file.txt')),
|
||||
reuseWindow: true
|
||||
})), null);
|
||||
assert.equal(findBestWindowOrFolderForFile(options({
|
||||
filePath: path.join(fixturesFolder, 'vscode_folder', 'file.txt'),
|
||||
fileUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'file.txt')),
|
||||
context: OpenContext.API
|
||||
})), null);
|
||||
assert.equal(findBestWindowOrFolderForFile(options({
|
||||
filePath: path.join(fixturesFolder, 'vscode_folder', 'file.txt')
|
||||
fileUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'file.txt'))
|
||||
})), null);
|
||||
assert.equal(findBestWindowOrFolderForFile(options({
|
||||
filePath: path.join(fixturesFolder, 'vscode_folder', 'new_folder', 'new_file.txt')
|
||||
fileUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'new_folder', 'new_file.txt'))
|
||||
})), null);
|
||||
});
|
||||
|
||||
test('New window without folder when windows exist', () => {
|
||||
assert.equal(findBestWindowOrFolderForFile(options({
|
||||
windows,
|
||||
filePath: path.join(fixturesFolder, 'no_vscode_folder', 'file.txt'),
|
||||
fileUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'file.txt')),
|
||||
newWindow: true
|
||||
})), null);
|
||||
});
|
||||
@@ -81,16 +81,16 @@ suite('WindowsFinder', () => {
|
||||
})), lastActiveWindow);
|
||||
assert.equal(findBestWindowOrFolderForFile(options({
|
||||
windows,
|
||||
filePath: path.join(fixturesFolder, 'no_vscode_folder2', 'file.txt')
|
||||
fileUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder2', 'file.txt'))
|
||||
})), lastActiveWindow);
|
||||
assert.equal(findBestWindowOrFolderForFile(options({
|
||||
windows: [lastActiveWindow, noVscodeFolderWindow],
|
||||
filePath: path.join(fixturesFolder, 'vscode_folder', 'file.txt'),
|
||||
fileUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'file.txt')),
|
||||
reuseWindow: true
|
||||
})), lastActiveWindow);
|
||||
assert.equal(findBestWindowOrFolderForFile(options({
|
||||
windows,
|
||||
filePath: path.join(fixturesFolder, 'no_vscode_folder', 'file.txt'),
|
||||
fileUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'file.txt')),
|
||||
context: OpenContext.API
|
||||
})), lastActiveWindow);
|
||||
});
|
||||
@@ -98,16 +98,16 @@ suite('WindowsFinder', () => {
|
||||
test('Existing window with folder', () => {
|
||||
assert.equal(findBestWindowOrFolderForFile(options({
|
||||
windows,
|
||||
filePath: path.join(fixturesFolder, 'no_vscode_folder', 'file.txt')
|
||||
fileUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'file.txt'))
|
||||
})), noVscodeFolderWindow);
|
||||
assert.equal(findBestWindowOrFolderForFile(options({
|
||||
windows,
|
||||
filePath: path.join(fixturesFolder, 'vscode_folder', 'file.txt')
|
||||
fileUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'file.txt'))
|
||||
})), vscodeFolderWindow);
|
||||
const window: ISimpleWindow = { lastFocusTime: 1, openedFolderUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'nested_folder')) };
|
||||
assert.equal(findBestWindowOrFolderForFile(options({
|
||||
windows: [window],
|
||||
filePath: path.join(fixturesFolder, 'vscode_folder', 'nested_folder', 'subfolder', 'file.txt')
|
||||
fileUri: URI.file(path.join(fixturesFolder, 'vscode_folder', 'nested_folder', 'subfolder', 'file.txt'))
|
||||
})), window);
|
||||
});
|
||||
|
||||
@@ -116,7 +116,7 @@ suite('WindowsFinder', () => {
|
||||
const nestedFolderWindow: ISimpleWindow = { lastFocusTime: 1, openedFolderUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'nested_folder')) };
|
||||
assert.equal(findBestWindowOrFolderForFile(options({
|
||||
windows: [window, nestedFolderWindow],
|
||||
filePath: path.join(fixturesFolder, 'no_vscode_folder', 'nested_folder', 'subfolder', 'file.txt')
|
||||
fileUri: URI.file(path.join(fixturesFolder, 'no_vscode_folder', 'nested_folder', 'subfolder', 'file.txt'))
|
||||
})), nestedFolderWindow);
|
||||
});
|
||||
|
||||
@@ -124,7 +124,7 @@ suite('WindowsFinder', () => {
|
||||
const window: ISimpleWindow = { lastFocusTime: 1, openedWorkspace: testWorkspace };
|
||||
assert.equal(findBestWindowOrFolderForFile(options({
|
||||
windows: [window],
|
||||
filePath: path.join(fixturesFolder, 'vscode_workspace_2_folder', 'nested_vscode_folder', 'subfolder', 'file.txt')
|
||||
fileUri: URI.file(path.join(fixturesFolder, 'vscode_workspace_2_folder', 'nested_vscode_folder', 'subfolder', 'file.txt'))
|
||||
})), window);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user