diff --git a/src/vs/base/common/map.ts b/src/vs/base/common/map.ts index 45b81888e0a..560103a08c6 100644 --- a/src/vs/base/common/map.ts +++ b/src/vs/base/common/map.ts @@ -235,11 +235,11 @@ export class TrieMap { static PathSplitter = (s: string) => s.split(/[\\/]/).filter(s => !!s); - private _splitter: (s: string) => string[]; + private readonly _splitter: (s: string) => string[]; private _root = new Node(); constructor(splitter: (s: string) => string[]) { - this._splitter = splitter; + this._splitter = s => splitter(s).filter(s => Boolean(s)); } insert(path: string, element: E): void { @@ -695,4 +695,4 @@ export class LinkedMap { this._tail = item; } } -} \ No newline at end of file +} diff --git a/src/vs/platform/workspace/common/workspace.ts b/src/vs/platform/workspace/common/workspace.ts index 2a922761192..f8ce46ebe97 100644 --- a/src/vs/platform/workspace/common/workspace.ts +++ b/src/vs/platform/workspace/common/workspace.ts @@ -131,7 +131,7 @@ export class LegacyWorkspace implements ILegacyWorkspace { export class Workspace implements IWorkspace { - protected _rootsMap: TrieMap = new TrieMap(TrieMap.PathSplitter); + private _rootsMap: TrieMap = new TrieMap(TrieMap.PathSplitter); constructor( public readonly id: string, diff --git a/src/vs/workbench/api/node/extHostWorkspace.ts b/src/vs/workbench/api/node/extHostWorkspace.ts index 2ef49280a8e..f42eb06cfa5 100644 --- a/src/vs/workbench/api/node/extHostWorkspace.ts +++ b/src/vs/workbench/api/node/extHostWorkspace.ts @@ -17,6 +17,7 @@ import { fromRange, EndOfLine } from 'vs/workbench/api/node/extHostTypeConverter import { IWorkspaceData, ExtHostWorkspaceShape, MainContext, MainThreadWorkspaceShape } from './extHost.protocol'; import * as vscode from 'vscode'; import { compare } from 'vs/base/common/strings'; +import { TrieMap } from 'vs/base/common/map'; class Workspace2 extends Workspace { @@ -24,29 +25,42 @@ class Workspace2 extends Workspace { return data ? new Workspace2(data) : null; } - private readonly _folder = new Map(); + private readonly _folder: vscode.WorkspaceFolder[] = []; + private readonly _structure = new TrieMap(s => s.split('/')); private constructor(data: IWorkspaceData) { super(data.id, data.name, data.roots); + // setup the workspace folder data structure this.roots.forEach((uri, index) => { - this._folder.set(uri, { + const folder = { name: basename(uri.fsPath), uri, index - }); + }; + this._folder.push(folder); + this._structure.insert(folder.uri.toString(), folder); }); } get folders(): vscode.WorkspaceFolder[] { - const ret: vscode.WorkspaceFolder[] = []; - this._folder.forEach(value => ret.push(value)); - return ret; + return this._folder.slice(0); } getWorkspaceFolder(uri: URI): vscode.WorkspaceFolder { - let root = this._rootsMap.findSubstr(uri.fsPath); - return root && this._folder.get(root); + let str = uri.toString(); + let folder = this._structure.lookUp(str); + if (folder) { + // `uri` is a workspace folder so we + let parts = str.split('/'); + while (parts.length) { + if (parts.pop()) { + break; + } + } + str = parts.join('/'); + } + return this._structure.findSubstr(str); } } diff --git a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts index c9a5e9cdd24..bd4c1109352 100644 --- a/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts +++ b/src/vs/workbench/test/electron-browser/api/extHostWorkspace.test.ts @@ -98,11 +98,14 @@ suite('ExtHostWorkspace', function () { folder = ws.getWorkspaceFolder(URI.file('/Coding/Two/Nested/f')); assert.equal(folder.name, 'Nested'); - // folder = ws.getWorkspaceFolder(URI.file('/Coding/Two/Nested')); - // assert.equal(folder.name, 'Two'); + folder = ws.getWorkspaceFolder(URI.file('/Coding/Two/Nested')); + assert.equal(folder.name, 'Two'); - // folder = ws.getWorkspaceFolder(URI.file('/Coding/Two/Nested/')); - // assert.equal(folder.name, 'Two'); + folder = ws.getWorkspaceFolder(URI.file('/Coding/Two/Nested/')); + assert.equal(folder.name, 'Two'); + + folder = ws.getWorkspaceFolder(URI.file('/Coding/Two')); + assert.equal(folder, undefined); }); test('Multiroot change event should have a delta, #29641', function () {