UNPKG

coc-ccls

Version:

C/C++/ObjC language server supporting cross references, hierarchies, completion and semantic highlighting

90 lines (81 loc) 2.63 kB
import { commands } from 'coc.nvim'; import { LanguageClient } from 'vscode-languageclient/lib/main'; import { Position, } from "vscode-languageserver-protocol"; import Uri from "vscode-uri"; import { Icon, IHierarchyNode } from '../types'; import { resourcePath } from '../utils'; import { Hierarchy } from './hierarchy'; enum CallType { Normal = 0, Base = 1, Derived = 2, All = CallType.Base | CallType.Derived // Normal and Base and Derived } interface CallHierarchyNode extends IHierarchyNode { children: CallHierarchyNode[]; callType: CallType; } export class CallHierarchyProvider extends Hierarchy<CallHierarchyNode> { protected contextValue: string = 'extension.ccls.callHierarchyVisible'; private baseIcon: Icon; private derivedIcon: Icon; private useCallee = false; constructor( languageClient: LanguageClient ) { super(languageClient, 'ccls.callHierarchy', 'ccls.closeCallHierarchy'); this.baseIcon = { dark: resourcePath("base-dark.svg"), light: resourcePath("base-light.svg") }; this.derivedIcon = { dark: resourcePath("derived-dark.svg"), light: resourcePath("derived-light.svg") }; this._dispose.push(commands.registerCommand("ccls.call.useCallers", () => this.updateCallee(false))); this._dispose.push(commands.registerCommand("ccls.call.useCallees", () => this.updateCallee(true))); } public onTreeItem(ti: TreeItem, element: CallHierarchyNode) { if (element.callType === CallType.Base) ti.iconPath = this.baseIcon; else if (element.callType === CallType.Derived) ti.iconPath = this.derivedIcon; } protected async onGetChildren(element: CallHierarchyNode): Promise<CallHierarchyNode[]> { const result = await this.languageClient.sendRequest<CallHierarchyNode>('$ccls/call', { callType: CallType.All, callee: this.useCallee, hierarchy: true, id: element.id, levels: 1, qualified: false, }); element.children = result.children; return result.children; } protected async onReveal(uri: Uri, position: Position): Promise<CallHierarchyNode> { return this.languageClient.sendRequest<CallHierarchyNode>( '$ccls/call', { callType: CallType.All, callee: this.useCallee, hierarchy: true, levels: 2, position, qualified: false, textDocument: { uri: uri.toString(true), }, } ); } private updateCallee(val: boolean) { this.useCallee = val; if (this.root) { this.root.children = []; this.onDidChangeEmitter.fire(); } } }