未验证 提交 91b94963 编写于 作者: J Johannes Rieken 提交者: GitHub

Merge pull request #46177 from Microsoft/sandy081/treeViewAPI

API - Expose TreeView in API
......@@ -5189,12 +5189,39 @@ declare module 'vscode' {
/**
* Register a [TreeDataProvider](#TreeDataProvider) for the view contributed using the extension point `views`.
* This will allow you to contribute data to the [TreeView](#TreeView) and update if the data changes.
* To get access to the [TreeView](#TreeView) and perform operations on it, use [createTreeView](#window.createTreeView).
*
* @param viewId Id of the view contributed using the extension point `views`.
* @param treeDataProvider A [TreeDataProvider](#TreeDataProvider) that provides tree data for the view
*/
export function registerTreeDataProvider<T>(viewId: string, treeDataProvider: TreeDataProvider<T>): Disposable;
/**
* Create a [TreeView](#TreeView) for the view contributed using the extension point `views`.
* @param viewId Id of the view contributed using the extension point `views`.
* @param options Options object to provide [TreeDataProvider](#TreeDataProvider) for the view.
* @returns a [TreeView](#TreeView).
*/
export function createTreeView<T>(viewId: string, options: { treeDataProvider: TreeDataProvider<T> }): TreeView<T>;
}
/**
* Represents a Tree view
*/
export interface TreeView<T> extends Disposable {
/**
* Reveal an element. By default revealed element is selected.
*
* In order to not to select, set the option `select` to `false`.
*
* **NOTE:** [TreeDataProvider](#TreeDataProvider) is required to implement [getParent](#TreeDataProvider.getParent) method to access this API.
*/
reveal(element: T, options?: { select?: boolean }): Thenable<void>;
}
/**
* A data provider that provides tree data
*/
......@@ -5221,6 +5248,17 @@ declare module 'vscode' {
* @return Children of `element` or root if no element is passed.
*/
getChildren(element?: T): ProviderResult<T[]>;
/**
* Optional method to return the parent of `element`.
* Return `null` or `undefined` if `element` is a child of root.
*
* **NOTE:** This method should be implemented in order to access [reveal](#TreeView.reveal) API.
*
* @param element The element for which the parent has to be returned.
* @return Parent of `element`.
*/
getParent?(element: T): ProviderResult<T>;
}
export class TreeItem {
......
......@@ -663,76 +663,6 @@ declare module 'vscode' {
//#endregion
//#region Sandeep: TreeView
export namespace window {
/**
* Register a [TreeDataProvider](#TreeDataProvider) for the view contributed using the extension point `views`.
* @param viewId Id of the view contributed using the extension point `views`.
* @param treeDataProvider A [TreeDataProvider](#TreeDataProvider) that provides tree data for the view
* @return handle to the [treeview](#TreeView) that can be disposable.
*/
export function registerTreeDataProvider<T>(viewId: string, treeDataProvider: TreeDataProvider<T>): TreeView<T>;
}
/**
* Represents a Tree view
*/
export interface TreeView<T> extends Disposable {
/**
* Reveal an element. By default revealed element is selected.
*
* In order to not to select, set the option `select` to `false`.
*
* **NOTE:** [TreeDataProvider](#TreeDataProvider) is required to implement [getParent](#TreeDataProvider.getParent) method to access this API.
*/
reveal(element: T, options?: { select?: boolean }): Thenable<void>;
}
/**
* A data provider that provides tree data
*/
export interface TreeDataProvider<T> {
/**
* An optional event to signal that an element or root has changed.
* This will trigger the view to update the changed element/root and its children recursively (if shown).
* To signal that root has changed, do not pass any argument or pass `undefined` or `null`.
*/
onDidChangeTreeData?: Event<T | undefined | null>;
/**
* Get [TreeItem](#TreeItem) representation of the `element`
*
* @param element The element for which [TreeItem](#TreeItem) representation is asked for.
* @return [TreeItem](#TreeItem) representation of the element
*/
getTreeItem(element: T): TreeItem | Thenable<TreeItem>;
/**
* Get the children of `element` or root if no element is passed.
*
* @param element The element from which the provider gets children. Can be `undefined`.
* @return Children of `element` or root if no element is passed.
*/
getChildren(element?: T): ProviderResult<T[]>;
/**
* Optional method to return the parent of `element`.
* Return `null` or `undefined` if `element` is a child of root.
*
* **NOTE:** This method should be implemented in order to access [reveal](#TreeView.reveal) API.
*
* @param element The element for which the parent has to be returned.
* @return Parent of `element`.
*/
getParent?(element: T): ProviderResult<T>;
}
//#endregion
//#region Alex: TextEditor.visibleRange and related event
export interface TextEditor {
......
......@@ -403,8 +403,11 @@ export function createApiFactory(
}
return extHostTerminalService.createTerminal(<string>nameOrOptions, shellPath, shellArgs);
},
registerTreeDataProvider(viewId: string, treeDataProvider: vscode.TreeDataProvider<any>): vscode.TreeView<any> {
return extHostTreeViews.registerTreeDataProvider(viewId, treeDataProvider, (fn) => proposedApiFunction(extension, fn));
registerTreeDataProvider(viewId: string, treeDataProvider: vscode.TreeDataProvider<any>): vscode.Disposable {
return extHostTreeViews.registerTreeDataProvider(viewId, treeDataProvider);
},
createTreeView(viewId: string, options: { treeDataProvider: vscode.TreeDataProvider<any> }): vscode.TreeView<any> {
return extHostTreeViews.createTreeView(viewId, options);
},
// proposed API
sampleFunction: proposedApiFunction(extension, () => {
......
......@@ -38,14 +38,22 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape {
});
}
registerTreeDataProvider<T>(id: string, dataProvider: vscode.TreeDataProvider<T>, proposedApiFunction: <U>(fn: U) => U): vscode.TreeView<T> {
const treeView = this.createExtHostTreeViewer(id, dataProvider);
registerTreeDataProvider<T>(id: string, treeDataProvider: vscode.TreeDataProvider<T>): vscode.Disposable {
const treeView = this.createTreeView(id, { treeDataProvider });
return { dispose: () => treeView.dispose() };
}
createTreeView<T>(viewId: string, options: { treeDataProvider: vscode.TreeDataProvider<T> }): vscode.TreeView<T> {
if (!options || !options.treeDataProvider) {
throw new Error('Options with treeDataProvider is mandatory');
}
const treeView = this.createExtHostTreeViewer(viewId, options.treeDataProvider);
return {
reveal: proposedApiFunction((element: T, options?: { select?: boolean }): Thenable<void> => {
reveal: (element: T, options?: { select?: boolean }): Thenable<void> => {
return treeView.reveal(element, options);
}),
},
dispose: () => {
this.treeViews.delete(id);
this.treeViews.delete(viewId);
treeView.dispose();
}
};
......
......@@ -75,8 +75,8 @@ suite('ExtHostTreeView', function () {
testObject = new ExtHostTreeViews(target, new ExtHostCommands(rpcProtocol, new ExtHostHeapService(), new NullLogService()));
onDidChangeTreeNode = new Emitter<{ key: string }>();
onDidChangeTreeNodeWithId = new Emitter<{ key: string }>();
testObject.registerTreeDataProvider('testNodeTreeProvider', aNodeTreeDataProvider(), (fn) => fn);
testObject.registerTreeDataProvider('testNodeWithIdTreeProvider', aNodeWithIdTreeDataProvider(), (fn) => fn);
testObject.createTreeView('testNodeTreeProvider', { treeDataProvider: aNodeTreeDataProvider() });
testObject.createTreeView('testNodeWithIdTreeProvider', { treeDataProvider: aNodeWithIdTreeDataProvider() });
testObject.$getChildren('testNodeTreeProvider').then(elements => {
for (const element of elements) {
......@@ -405,14 +405,14 @@ suite('ExtHostTreeView', function () {
});
test('reveal will throw an error if getParent is not implemented', () => {
const treeView = testObject.registerTreeDataProvider('treeDataProvider', aNodeTreeDataProvider(), (fn) => fn);
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aNodeTreeDataProvider() });
return treeView.reveal({ key: 'a' })
.then(() => assert.fail('Reveal should throw an error as getParent is not implemented'), () => null);
});
test('reveal will return empty array for root element', () => {
const revealTarget = sinon.spy(target, '$reveal');
const treeView = testObject.registerTreeDataProvider('treeDataProvider', aCompleteNodeTreeDataProvider(), (fn) => fn);
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() });
return treeView.reveal({ key: 'a' })
.then(() => {
assert.ok(revealTarget.calledOnce);
......@@ -425,7 +425,7 @@ suite('ExtHostTreeView', function () {
test('reveal will return parents array for an element', () => {
const revealTarget = sinon.spy(target, '$reveal');
const treeView = testObject.registerTreeDataProvider('treeDataProvider', aCompleteNodeTreeDataProvider(), (fn) => fn);
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() });
return treeView.reveal({ key: 'aa' })
.then(() => {
assert.ok(revealTarget.calledOnce);
......@@ -445,7 +445,7 @@ suite('ExtHostTreeView', function () {
}
};
const revealTarget = sinon.spy(target, '$reveal');
const treeView = testObject.registerTreeDataProvider('treeDataProvider', aCompleteNodeTreeDataProvider(), (fn) => fn);
const treeView = testObject.createTreeView('treeDataProvider', { treeDataProvider: aCompleteNodeTreeDataProvider() });
return treeView.reveal({ key: 'bac' }, { select: false })
.then(() => {
assert.ok(revealTarget.calledOnce);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册