Skip to content
This repository was archived by the owner on Nov 16, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@
{
"command": "references-view.remove",
"group": "inline",
"when": "view == references-view.tree && viewItem == file-item || view == references-view.tree && viewItem == reference-item"
"when": "view == references-view.tree && viewItem == file-item || view == references-view.tree && viewItem == reference-item || view == references-view.tree && viewItem == call-item"
},
{
"command": "references-view.refind",
Expand All @@ -203,7 +203,7 @@
{
"command": "references-view.remove",
"group": "1",
"when": "view == references-view.tree && viewItem == file-item || view == references-view.tree && viewItem == reference-item"
"when": "view == references-view.tree && viewItem == file-item || view == references-view.tree && viewItem == reference-item || view == references-view.tree && viewItem == call-item"
},
{
"command": "references-view.refind",
Expand Down
18 changes: 17 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ export function activate(context: vscode.ExtensionContext) {
}
};

const removeRefCommand = async (arg?: ReferenceItem | FileItem | any) => {
const removeRefCommand = async (arg?: ReferenceItem | FileItem | CallItem | any) => {
if (model instanceof ReferencesModel) {
let next: ReferenceItem | undefined;
if (arg instanceof ReferenceItem) {
Expand All @@ -253,6 +253,22 @@ export function activate(context: vscode.ExtensionContext) {
if (next) {
view.reveal(next, { select: true });
}
} else if (model instanceof CallsModel) {
const item = arg as CallItem;
const next = await model.move(item, true);
await model.remove(item);

if (await model.isEmpty()) {
return clearCommand();
}

editorHighlights.refresh();
showResultsMessage();
if (next) {
view.reveal(next, { select: true });
} else if (item.parent) {
view.reveal(item.parent, { select: true });
}
}
};

Expand Down
69 changes: 52 additions & 17 deletions src/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@
import * as vscode from 'vscode';
import { HistoryItem, WordAnchor } from './history';

function del<T>(array: T[], e: T): void {
const idx = array.indexOf(e);
if (idx >= 0) {
array.splice(idx, 1);
}
}

function tail<T>(array: T[]): T | undefined {
return array[array.length - 1];
}

export function getRequestRange(doc: vscode.TextDocument, pos: vscode.Position): vscode.Range | undefined {
let range = doc.getWordRangeAtPosition(pos);
Expand Down Expand Up @@ -219,13 +229,13 @@ export class ReferencesModel {
async remove(item: FileItem | ReferenceItem): Promise<void> {

if (item instanceof FileItem) {
ReferencesModel._del(await this.items, item);
del(await this.items, item);
this._onDidChange.fire(this);

} else if (item instanceof ReferenceItem) {
ReferencesModel._del(item.parent.results, item);
del(item.parent.results, item);
if (item.parent.results.length === 0) {
ReferencesModel._del(await this.items, item.parent);
del(await this.items, item.parent);
this._onDidChange.fire(this);
} else {
this._onDidChange.fire(item.parent);
Expand All @@ -246,14 +256,14 @@ export class ReferencesModel {
if (fwd) {
return _move(item).results[0];
} else {
return ReferencesModel._tail(_move(item).results);
return tail(_move(item).results);
}
}

if (item instanceof ReferenceItem) {
const idx = item.parent.results.indexOf(item) + delta;
if (idx < 0) {
return ReferencesModel._tail(_move(item.parent).results);
return tail(_move(item.parent).results);
} else if (idx >= item.parent.results.length) {
return _move(item.parent).results[0];
} else {
Expand Down Expand Up @@ -294,17 +304,6 @@ export class ReferencesModel {
}
return pos;
}

private static _del<T>(array: T[], e: T): void {
const idx = array.indexOf(e);
if (idx >= 0) {
array.splice(idx, 1);
}
}

private static _tail<T>(array: T[]): T | undefined {
return array[array.length - 1];
}
}


Expand Down Expand Up @@ -346,6 +345,8 @@ export class RichCallsDirection {
}

export class CallItem {
children: CallItem[] | undefined;

constructor(
readonly item: vscode.CallHierarchyItem,
readonly parent: CallItem | undefined,
Expand All @@ -359,13 +360,16 @@ export class CallsModel {

readonly roots: Promise<CallItem[]>;

private readonly _onDidChange = new vscode.EventEmitter<CallsModel>();
readonly onDidChange = this._onDidChange.event;

constructor(readonly uri: vscode.Uri, readonly position: vscode.Position, readonly direction: CallsDirection) {
this.roots = Promise.resolve(vscode.commands.executeCommand<vscode.CallHierarchyItem[]>('vscode.prepareCallHierarchy', uri, position)).then(items => {
return items ? items.map(item => new CallItem(item, undefined, undefined)) : [];
});
}

async resolveCalls(call: CallItem): Promise<CallItem[]> {
private async _resolveCalls(call: CallItem): Promise<CallItem[]> {
if (this.direction === CallsDirection.Incoming) {
const calls = await vscode.commands.executeCommand<vscode.CallHierarchyIncomingCall[]>('vscode.provideIncomingCalls', call.item);
return calls ? calls.map(item => new CallItem(item.from, call, item.fromRanges.map(range => new vscode.Location(item.from.uri, range)))) : [];
Expand All @@ -375,6 +379,14 @@ export class CallsModel {
}
}

async getCallChildren(call: CallItem): Promise<CallItem[]> {
if (call.children) {
return call.children;
}
call.children = await this._resolveCalls(call);
return call.children;
}

changeDirection(): CallsModel {
return new CallsModel(this.uri, this.position, this.direction === CallsDirection.Incoming ? CallsDirection.Outgoing : CallsDirection.Incoming);
}
Expand All @@ -388,6 +400,29 @@ export class CallsModel {
return first;
}

async move(item: CallItem, fwd: boolean): Promise<CallItem | undefined> {
const roots = await this.roots;
const array = -1 !== roots.indexOf(item) ? roots : item.parent?.children;

if (!array?.length) {
return undefined;
}
const ix0 = array.indexOf(item);
if (1 == array.length && 0 == ix0) {
return undefined; // No siblings to move to.
}
}

async remove(item: CallItem): Promise<void> {
const isInRoot = -1 != (await this.roots).indexOf(item);
const siblings = isInRoot ? await this.roots : item.parent?.children;
if (!siblings) {
return;
}
del(siblings, item);
this._onDidChange.fire(this);
}

async asHistoryItem(args: any[]) {

const [first] = await this.roots;
Expand Down
19 changes: 13 additions & 6 deletions src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,18 @@ export class CallItemDataProvider implements vscode.TreeDataProvider<CallHierarc
private readonly _emitter = new vscode.EventEmitter<CallHierarchyItem | undefined>();
readonly onDidChangeTreeData = this._emitter.event;

private readonly _modelListener: vscode.Disposable;

constructor(
private _model: CallsModel
) { }
) {
this._modelListener = _model.onDidChange(e => this._emitter.fire(e instanceof CallHierarchyItem ? e : undefined));
}

dispose(): void {
this._emitter.dispose();
this._modelListener.dispose();
}

getTreeItem(element: CallHierarchyItem): vscode.TreeItem {

Expand All @@ -91,11 +100,9 @@ export class CallItemDataProvider implements vscode.TreeDataProvider<CallHierarc
}

getChildren(element?: CallHierarchyItem | undefined) {
if (!element) {
return this._model.roots;
} else {
return this._model.resolveCalls(element);
}
return element
? this._model.getCallChildren(element)
: this._model.roots;
}

getParent(element: CallHierarchyItem) {
Expand Down