windowsFinder.ts 4.7 KB
Newer Older
B
Benjamin Pasero 已提交
1 2 3 4 5 6 7 8
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import * as platform from 'vs/base/common/platform';
import * as paths from 'vs/base/common/paths';
import { OpenContext } from 'vs/platform/windows/common/windows';
M
Martin Aeschlimann 已提交
9
import { IWorkspaceIdentifier, IResolvedWorkspace, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, isWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
10
import { URI } from 'vs/base/common/uri';
11
import { isEqual, isEqualOrParent } from 'vs/base/common/resources';
B
Benjamin Pasero 已提交
12 13

export interface ISimpleWindow {
14
	openedWorkspace?: IWorkspaceIdentifier;
15
	openedFolderUri?: URI;
M
polish  
Martin Aeschlimann 已提交
16

17
	extensionDevelopmentPath?: string;
B
Benjamin Pasero 已提交
18 19 20 21 22 23 24 25
	lastFocusTime: number;
}

export interface IBestWindowOrFolderOptions<W extends ISimpleWindow> {
	windows: W[];
	newWindow: boolean;
	reuseWindow: boolean;
	context: OpenContext;
26
	fileUri?: URI;
B
Benjamin Pasero 已提交
27 28
	userHome?: string;
	codeSettingsFolder?: string;
29
	workspaceResolver: (workspace: IWorkspaceIdentifier) => IResolvedWorkspace | null;
B
Benjamin Pasero 已提交
30 31
}

M
Matt Bierner 已提交
32
export function findBestWindowOrFolderForFile<W extends ISimpleWindow>({ windows, newWindow, reuseWindow, context, fileUri, workspaceResolver }: IBestWindowOrFolderOptions<W>): W | null {
33 34
	if (!newWindow && fileUri && (context === OpenContext.DESKTOP || context === OpenContext.CLI || context === OpenContext.DOCK)) {
		const windowOnFilePath = findWindowOnFilePath(windows, fileUri, workspaceResolver);
35
		if (windowOnFilePath) {
36 37
			return windowOnFilePath;
		}
B
Benjamin Pasero 已提交
38 39 40 41
	}
	return !newWindow ? getLastActiveWindow(windows) : null;
}

42
function findWindowOnFilePath<W extends ISimpleWindow>(windows: W[], fileUri: URI, workspaceResolver: (workspace: IWorkspaceIdentifier) => IResolvedWorkspace | null): W | null {
43 44 45 46 47

	// 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];
M
Matt Bierner 已提交
48
		const resolvedWorkspace = workspaceResolver(window.openedWorkspace!);
49
		if (resolvedWorkspace && resolvedWorkspace.folders.some(folder => isEqualOrParent(fileUri, folder.uri))) {
50 51 52
			return window;
		}
	}
B
Benjamin Pasero 已提交
53

54
	// Then go with single folder windows that are parent of the provided file path
55
	const singleFolderWindowsOnFilePath = windows.filter(window => window.openedFolderUri && isEqualOrParent(fileUri, window.openedFolderUri));
56
	if (singleFolderWindowsOnFilePath.length) {
M
Matt Bierner 已提交
57
		return singleFolderWindowsOnFilePath.sort((a, b) => -(a.openedFolderUri!.path.length - b.openedFolderUri!.path.length))[0];
B
Benjamin Pasero 已提交
58 59 60 61 62 63
	}

	return null;
}

export function getLastActiveWindow<W extends ISimpleWindow>(windows: W[]): W {
64
	const lastFocusedDate = Math.max.apply(Math, windows.map(window => window.lastFocusTime));
B
Benjamin Pasero 已提交
65

66
	return windows.filter(window => window.lastFocusTime === lastFocusedDate)[0];
B
Benjamin Pasero 已提交
67
}
68

M
Matt Bierner 已提交
69
export function findWindowOnWorkspace<W extends ISimpleWindow>(windows: W[], workspace: (IWorkspaceIdentifier | ISingleFolderWorkspaceIdentifier)): W | null {
M
Martin Aeschlimann 已提交
70 71 72 73
	if (isSingleFolderWorkspaceIdentifier(workspace)) {
		for (const window of windows) {
			// match on folder
			if (isSingleFolderWorkspaceIdentifier(workspace)) {
74
				if (window.openedFolderUri && isEqual(window.openedFolderUri, workspace)) {
M
Martin Aeschlimann 已提交
75 76
					return window;
				}
77
			}
78
		}
M
Martin Aeschlimann 已提交
79 80 81
	} else if (isWorkspaceIdentifier(workspace)) {
		for (const window of windows) {
			// match on workspace
82
			if (window.openedWorkspace && window.openedWorkspace.id === workspace.id) {
M
Martin Aeschlimann 已提交
83
				return window;
84
			}
85
		}
M
Martin Aeschlimann 已提交
86 87
	}
	return null;
88
}
89

M
Matt Bierner 已提交
90
export function findWindowOnExtensionDevelopmentPath<W extends ISimpleWindow>(windows: W[], extensionDevelopmentPath: string): W | null {
M
Martin Aeschlimann 已提交
91
	for (const window of windows) {
92
		// match on extension development path. The path can be a path or uri string, using paths.isEqual is not 100% correct but good enough
M
Matt Bierner 已提交
93
		if (window.extensionDevelopmentPath && paths.isEqual(window.extensionDevelopmentPath, extensionDevelopmentPath, !platform.isLinux /* ignorecase */)) {
M
Martin Aeschlimann 已提交
94
			return window;
95
		}
M
Martin Aeschlimann 已提交
96 97
	}
	return null;
98 99
}

M
Matt Bierner 已提交
100
export function findWindowOnWorkspaceOrFolderUri<W extends ISimpleWindow>(windows: W[], uri: URI): W | null {
M
Martin Aeschlimann 已提交
101 102 103 104
	if (!uri) {
		return null;
	}
	for (const window of windows) {
105
		// check for workspace config path
106
		if (window.openedWorkspace && isEqual(URI.file(window.openedWorkspace.configPath), uri, !platform.isLinux /* ignorecase */)) {
M
Martin Aeschlimann 已提交
107
			return window;
108 109 110
		}

		// check for folder path
111
		if (window.openedFolderUri && isEqual(window.openedFolderUri, uri)) {
M
Martin Aeschlimann 已提交
112
			return window;
113
		}
M
Martin Aeschlimann 已提交
114 115
	}
	return null;
J
Johannes Rieken 已提交
116
}