diff --git a/src/clientHandler.ts b/src/clientHandler.ts index 7c980662b5..5c22285116 100644 --- a/src/clientHandler.ts +++ b/src/clientHandler.ts @@ -20,6 +20,7 @@ import { sortedWorkspaceFolders } from './vscodeUtils'; import TelemetryReporter from 'vscode-extension-telemetry'; +import { ShowReferencesFeature } from './showReferences'; import { ServerPath, CUSTOM_BIN_PATH_OPTION_NAME } from './serverPath'; export interface TerraformLanguageClient { @@ -177,6 +178,8 @@ export class ClientHandler { clientOptions ); + client.registerFeature(new ShowReferencesFeature(client)); + client.onDidChangeState((event) => { if (event.newState === State.Stopped) { clients.delete(location); diff --git a/src/showReferences.ts b/src/showReferences.ts new file mode 100644 index 0000000000..360ccc8e11 --- /dev/null +++ b/src/showReferences.ts @@ -0,0 +1,64 @@ +import * as vscode from 'vscode'; +import { + ClientCapabilities, + ServerCapabilities, + StaticFeature, + ReferencesRequest, + ReferenceContext, + BaseLanguageClient +} from 'vscode-languageclient'; + +type Position = { + line: number; + character: number; +} + +type RefContext = { + includeDeclaration: boolean; +} + +const showReferencesCommandId = 'client.showReferences' + +export class ShowReferencesFeature implements StaticFeature { + private registeredCommands: vscode.Disposable[] = []; + + constructor(private _client: BaseLanguageClient) { + } + + public fillClientCapabilities(capabilities: ClientCapabilities): void { + if (!capabilities['experimental']) { + capabilities['experimental'] = {}; + } + capabilities['experimental']['showReferencesCommandId'] = showReferencesCommandId; + } + + public initialize(capabilities: ServerCapabilities): void { + if ( !capabilities.experimental?.referenceCountCodeLens ) { + return + } + + const showRefs = vscode.commands.registerCommand(showReferencesCommandId, async (pos: Position, refCtx: RefContext) => { + const client = this._client; + + const doc = vscode.window.activeTextEditor.document; + + const position = new vscode.Position(pos.line, pos.character); + const context: ReferenceContext = {includeDeclaration: refCtx.includeDeclaration} + + const provider: vscode.ReferenceProvider = client.getFeature(ReferencesRequest.method).getProvider(doc); + const tokenSource: vscode.CancellationTokenSource = new vscode.CancellationTokenSource(); + + const locations = await provider.provideReferences(doc, position, context, tokenSource.token); + + await vscode.commands.executeCommand('editor.action.showReferences', doc.uri, position, locations); + }) + this.registeredCommands.push(showRefs); + } + + public dispose(): void { + this.registeredCommands.forEach(function(cmd, index, commands) { + cmd.dispose(); + commands.splice(index, 1); + }) + } +}