mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-24 02:28:34 +01:00
simple tree UX
This commit is contained in:
@@ -991,7 +991,7 @@ class CallHierarchyAdapter {
|
||||
|
||||
resolveCallHierarchyItem(item: callHierarchy.CallHierarchyItem, direction: callHierarchy.CallHierarchyDirection, token: CancellationToken): Promise<[callHierarchy.CallHierarchyItem, modes.Location[]][]> {
|
||||
return asPromise(() => this._provider.resolveCallHierarchyItem(
|
||||
this._cache.get(item._id),
|
||||
this._cache.get(item._id)!,
|
||||
direction as number, token) // todo@joh proper convert
|
||||
).then(data => {
|
||||
if (!data) {
|
||||
|
||||
@@ -8,6 +8,10 @@ import { localize } from 'vs/nls';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { CallHierarchyProviderRegistry, CallHierarchyDirection } from 'vs/workbench/contrib/callHierarchy/common/callHierarchy';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { CallHierarchyPeekWidget } from 'vs/workbench/contrib/callHierarchy/browser/callHierarchyPeek';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
|
||||
registerAction({
|
||||
id: 'editor.showCallHierarchy',
|
||||
@@ -19,8 +23,11 @@ registerAction({
|
||||
menuId: MenuId.CommandPalette
|
||||
},
|
||||
handler: async function (accessor) {
|
||||
const editor = accessor.get(ICodeEditorService).getActiveCodeEditor();
|
||||
|
||||
const instaService = accessor.get(IInstantiationService);
|
||||
const editorService = accessor.get(ICodeEditorService);
|
||||
|
||||
const editor = editorService.getActiveCodeEditor();
|
||||
if (!editor || !editor.hasModel()) {
|
||||
console.log('bad editor');
|
||||
return;
|
||||
@@ -32,14 +39,28 @@ registerAction({
|
||||
return;
|
||||
}
|
||||
|
||||
const data = await provider.provideCallHierarchyItem(editor.getModel(), editor.getPosition(), CancellationToken.None);
|
||||
if (!data) {
|
||||
const rootItem = await provider.provideCallHierarchyItem(editor.getModel(), editor.getPosition(), CancellationToken.None);
|
||||
if (!rootItem) {
|
||||
console.log('no data');
|
||||
return;
|
||||
}
|
||||
|
||||
const callsTo = await provider.resolveCallHierarchyItem(data, CallHierarchyDirection.CallsTo, CancellationToken.None);
|
||||
console.log(data);
|
||||
console.log(callsTo);
|
||||
const widget = instaService.createInstance(CallHierarchyPeekWidget, editor, provider, CallHierarchyDirection.CallsTo, rootItem);
|
||||
|
||||
const listener = Event.any<any>(editor.onDidChangeModel, editor.onDidChangeModelLanguage)(_ => widget.dispose());
|
||||
|
||||
widget.show(Range.fromPositions(editor.getPosition()));
|
||||
|
||||
widget.onDidClose(() => {
|
||||
console.log('DONE');
|
||||
listener.dispose();
|
||||
});
|
||||
|
||||
widget.tree.onDidOpen(e => {
|
||||
const [element] = e.elements;
|
||||
if (element) {
|
||||
console.log(element);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { PeekViewWidget } from 'vs/editor/contrib/referenceSearch/peekViewWidget';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { CallHierarchyItem, CallHierarchyProvider, CallHierarchyDirection } from 'vs/workbench/contrib/callHierarchy/common/callHierarchy';
|
||||
import { WorkbenchAsyncDataTree } from 'vs/platform/list/browser/listService';
|
||||
import { FuzzyScore } from 'vs/base/common/filters';
|
||||
import * as callHierarchyTree from 'vs/workbench/contrib/callHierarchy/browser/callHierarchyTree';
|
||||
import { IAsyncDataTreeOptions } from 'vs/base/browser/ui/tree/asyncDataTree';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ScrollType } from 'vs/editor/common/editorCommon';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
|
||||
|
||||
export class CallHierarchyPeekWidget extends PeekViewWidget {
|
||||
|
||||
private _tree: WorkbenchAsyncDataTree<CallHierarchyItem, callHierarchyTree.Call, FuzzyScore>;
|
||||
|
||||
constructor(
|
||||
editor: ICodeEditor,
|
||||
private readonly _provider: CallHierarchyProvider,
|
||||
private readonly _direction: CallHierarchyDirection,
|
||||
private readonly _item: CallHierarchyItem,
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
) {
|
||||
super(editor, { showFrame: true, showArrow: true, isResizeable: true, isAccessible: true });
|
||||
this.create();
|
||||
}
|
||||
|
||||
protected _fillBody(container: HTMLElement): void {
|
||||
|
||||
const options: IAsyncDataTreeOptions<callHierarchyTree.Call, FuzzyScore> = {
|
||||
identityProvider: new callHierarchyTree.IdentityProvider(),
|
||||
ariaLabel: localize('tree.aria', "Call Hierarchy"),
|
||||
expandOnlyOnTwistieClick: true,
|
||||
};
|
||||
|
||||
this._tree = <any>this._instantiationService.createInstance(
|
||||
WorkbenchAsyncDataTree,
|
||||
container,
|
||||
new callHierarchyTree.VirtualDelegate(),
|
||||
[new callHierarchyTree.CallRenderer()],
|
||||
new callHierarchyTree.SingleDirectionDataSource(this._provider, this._direction),
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
get tree(): WorkbenchAsyncDataTree<CallHierarchyItem, callHierarchyTree.Call, FuzzyScore> {
|
||||
return this._tree;
|
||||
}
|
||||
|
||||
show(where: IRange) {
|
||||
this.editor.revealRangeInCenterIfOutsideViewport(where, ScrollType.Smooth);
|
||||
super.show(where, 12);
|
||||
this.setTitle(localize('title', "Call Hierarchy for '{0}'", this._item.name));
|
||||
this._tree.setInput(this._item);
|
||||
this._tree.domFocus();
|
||||
this._tree.focusFirst();
|
||||
}
|
||||
|
||||
protected _doLayoutBody(height: number, width: number): void {
|
||||
super._doLayoutBody(height, width);
|
||||
this._tree.layout(height, width);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IAsyncDataSource, ITreeRenderer, ITreeNode } from 'vs/base/browser/ui/tree/tree';
|
||||
import { CallHierarchyItem, CallHierarchyDirection, CallHierarchyProvider } from 'vs/workbench/contrib/callHierarchy/common/callHierarchy';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IIdentityProvider, IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
||||
import { FuzzyScore, createMatches } from 'vs/base/common/filters';
|
||||
import { IconLabel } from 'vs/base/browser/ui/iconLabel/iconLabel';
|
||||
import { symbolKindToCssClass } from 'vs/editor/common/modes';
|
||||
import { localize } from 'vs/nls';
|
||||
|
||||
export class Call {
|
||||
constructor(
|
||||
readonly direction: CallHierarchyDirection,
|
||||
readonly item: CallHierarchyItem,
|
||||
readonly ranges: IRange[] | undefined
|
||||
) { }
|
||||
}
|
||||
|
||||
export class SingleDirectionDataSource implements IAsyncDataSource<CallHierarchyItem, Call> {
|
||||
|
||||
constructor(
|
||||
public provider: CallHierarchyProvider,
|
||||
public direction: CallHierarchyDirection
|
||||
) { }
|
||||
|
||||
hasChildren(_element: CallHierarchyItem): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
async getChildren(element: CallHierarchyItem | Call): Promise<Call[]> {
|
||||
if (element instanceof Call) {
|
||||
const calls = await this.provider.resolveCallHierarchyItem(element.item, this.direction, CancellationToken.None);
|
||||
return calls
|
||||
? calls.map(([item, locations]) => new Call(this.direction, item, locations.map(l => l.range)))
|
||||
: [];
|
||||
} else {
|
||||
return [new Call(this.direction, element, undefined)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class IdentityProvider implements IIdentityProvider<Call> {
|
||||
getId(element: Call): { toString(): string; } {
|
||||
return element.item._id;
|
||||
}
|
||||
}
|
||||
|
||||
class CallRenderingTemplate {
|
||||
iconLabel: IconLabel;
|
||||
}
|
||||
|
||||
export class CallRenderer implements ITreeRenderer<Call, FuzzyScore, CallRenderingTemplate> {
|
||||
|
||||
static id = 'CallRenderer';
|
||||
|
||||
templateId: string = CallRenderer.id;
|
||||
|
||||
renderTemplate(container: HTMLElement): CallRenderingTemplate {
|
||||
const iconLabel = new IconLabel(container, { supportHighlights: true });
|
||||
return { iconLabel };
|
||||
}
|
||||
renderElement(node: ITreeNode<Call, FuzzyScore>, _index: number, template: CallRenderingTemplate): void {
|
||||
const { element, filterData } = node;
|
||||
let detail: string | undefined;
|
||||
if (!element.ranges) {
|
||||
// root
|
||||
detail = element.item.detail;
|
||||
} else {
|
||||
detail = element.ranges.length === 1
|
||||
? localize('label.1', "(1 usage)")
|
||||
: localize('label.n', "({0} usages)", element.ranges.length);
|
||||
}
|
||||
template.iconLabel.setLabel(
|
||||
element.item.name,
|
||||
detail,
|
||||
{
|
||||
labelEscapeNewLines: true,
|
||||
matches: createMatches(filterData),
|
||||
extraClasses: [symbolKindToCssClass(element.item.kind, true)]
|
||||
}
|
||||
);
|
||||
}
|
||||
disposeTemplate(template: CallRenderingTemplate): void {
|
||||
template.iconLabel.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
export class VirtualDelegate implements IListVirtualDelegate<Call> {
|
||||
|
||||
getHeight(_element: Call): number {
|
||||
return 22;
|
||||
}
|
||||
|
||||
getTemplateId(_element: Call): string {
|
||||
return CallRenderer.id;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user