提交 93101a2d 编写于 作者: J Johannes Rieken

fix #29641

上级 496e3ffc
......@@ -7,9 +7,14 @@
declare module 'vscode' {
export interface WorkspaceFoldersChangeEvent {
readonly addedFolders: Uri[];
readonly removedFolders: Uri[];
}
export namespace workspace {
export const onDidChangeWorkspaceFolders: Event<Uri[] | undefined>;
export const onDidChangeWorkspaceFolders: Event<WorkspaceFoldersChangeEvent>;
export let workspaceFolders: Uri[] | undefined;
}
......
......@@ -7,7 +7,7 @@
import URI from 'vs/base/common/uri';
import Event, { Emitter } from 'vs/base/common/event';
import { normalize } from 'vs/base/common/paths';
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
import { isFalsyOrEmpty, delta } from 'vs/base/common/arrays';
import { relative } from 'path';
import { Workspace } from 'vs/platform/workspace/common/workspace';
import { IThreadService } from 'vs/workbench/services/thread/common/threadService';
......@@ -16,16 +16,17 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { fromRange, EndOfLine } from 'vs/workbench/api/node/extHostTypeConverters';
import { IWorkspaceData, ExtHostWorkspaceShape, MainContext, MainThreadWorkspaceShape } from './extHost.protocol';
import * as vscode from 'vscode';
import { compare } from "vs/base/common/strings";
export class ExtHostWorkspace extends ExtHostWorkspaceShape {
private static _requestIdPool = 0;
private readonly _onDidChangeWorkspace = new Emitter<URI[]>();
private readonly _onDidChangeWorkspace = new Emitter<vscode.WorkspaceFoldersChangeEvent>();
private readonly _proxy: MainThreadWorkspaceShape;
private _workspace: Workspace;
readonly onDidChangeWorkspace: Event<URI[]> = this._onDidChangeWorkspace.event;
readonly onDidChangeWorkspace: Event<vscode.WorkspaceFoldersChangeEvent> = this._onDidChangeWorkspace.event;
constructor(threadService: IThreadService, data: IWorkspaceData) {
super();
......@@ -95,8 +96,24 @@ export class ExtHostWorkspace extends ExtHostWorkspaceShape {
}
$acceptWorkspaceData(data: IWorkspaceData): void {
// compute delta
const oldRoots = this._workspace ? this._workspace.roots.sort(ExtHostWorkspace._compareUri) : [];
const newRoots = data ? data.roots.sort(ExtHostWorkspace._compareUri) : [];
const { added, removed } = delta(oldRoots, newRoots, ExtHostWorkspace._compareUri);
// update state
this._workspace = data ? new Workspace(data.id, data.name, data.roots) : null;
this._onDidChangeWorkspace.fire(this.getRoots());
// send event
this._onDidChangeWorkspace.fire(Object.freeze({
addedFolders: Object.freeze<vscode.Uri[]>(added),
removedFolders: Object.freeze<vscode.Uri[]>(removed)
}));
}
private static _compareUri(a: vscode.Uri, b: vscode.Uri): number {
return compare(a.toString(), b.toString());
}
// --- search ---
......
......@@ -65,4 +65,57 @@ suite('ExtHostWorkspace', function () {
ws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', name: 'Test', roots: [URI.file('/Folder')] });
assert.equal(ws.getPath().replace(/\\/g, '/'), '/Folder');
});
test('Multiroot change event should have a delta, #29641', function () {
let ws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', name: 'Test', roots: [] });
let sub = ws.onDidChangeWorkspace(e => {
assert.deepEqual(e.addedFolders, []);
assert.deepEqual(e.removedFolders, []);
});
ws.$acceptWorkspaceData({ id: 'foo', name: 'Test', roots: [] });
sub.dispose();
sub = ws.onDidChangeWorkspace(e => {
assert.deepEqual(e.removedFolders, []);
assert.equal(e.addedFolders.length, 1);
assert.equal(e.addedFolders[0].toString(), 'foo:bar');
});
ws.$acceptWorkspaceData({ id: 'foo', name: 'Test', roots: [URI.parse('foo:bar')] });
sub.dispose();
sub = ws.onDidChangeWorkspace(e => {
assert.deepEqual(e.removedFolders, []);
assert.equal(e.addedFolders.length, 1);
assert.equal(e.addedFolders[0].toString(), 'foo:bar2');
});
ws.$acceptWorkspaceData({ id: 'foo', name: 'Test', roots: [URI.parse('foo:bar'), URI.parse('foo:bar2')] });
sub.dispose();
sub = ws.onDidChangeWorkspace(e => {
assert.equal(e.removedFolders.length, 2);
assert.equal(e.removedFolders[0].toString(), 'foo:bar');
assert.equal(e.removedFolders[1].toString(), 'foo:bar2');
assert.equal(e.addedFolders.length, 1);
assert.equal(e.addedFolders[0].toString(), 'foo:bar3');
});
ws.$acceptWorkspaceData({ id: 'foo', name: 'Test', roots: [URI.parse('foo:bar3')] });
sub.dispose();
});
test('Multiroot change event is immutable', function () {
let ws = new ExtHostWorkspace(new TestThreadService(), { id: 'foo', name: 'Test', roots: [] });
let sub = ws.onDidChangeWorkspace(e => {
assert.throws(() => {
e.addedFolders = [];
});
assert.throws(() => {
(<any>e.addedFolders)[0] = null;
});
});
ws.$acceptWorkspaceData({ id: 'foo', name: 'Test', roots: [] });
sub.dispose();
});
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册