import * as vscode from "vscode" import { LanguageClient, Range, State } from "vscode-languageclient/node" // .def files are not synchronized with the language server, so each request // carries the current text of the document. const DEF_SELECTOR: vscode.DocumentSelector = { scheme: "file", language: "def" } function params(document: vscode.TextDocument, position: vscode.Position, extra: object = {}) { return { textDocument: { uri: document.uri.toString() }, position: { line: position.line, character: position.character }, text: document.getText(), ...extra } } export function registerDefProviders(getClient: () => LanguageClient | undefined): vscode.Disposable[] { const request = async ( method: string, document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken, extra: object = {} ): Promise<{ client: LanguageClient; result: T } | undefined> => { const client = getClient() if (!client || client.state !== State.Running) { return undefined } const result = await client.sendRequest(method, params(document, position, extra), token) return result ? { client, result } : undefined } return [ vscode.languages.registerDefinitionProvider(DEF_SELECTOR, { async provideDefinition(document, position, token) { const response = await request("nxPostSupport/def/definition", document, position, token) return response && response.client.protocol2CodeConverter.asDefinitionResult(response.result, token) } }), vscode.languages.registerHoverProvider(DEF_SELECTOR, { async provideHover(document, position, token) { const response = await request("nxPostSupport/def/hover", document, position, token) return response && response.client.protocol2CodeConverter.asHover(response.result) } }), vscode.languages.registerReferenceProvider(DEF_SELECTOR, { async provideReferences(document, position, context, token) { const response = await request("nxPostSupport/def/references", document, position, token, { includeDeclaration: context.includeDeclaration }) return response && response.client.protocol2CodeConverter.asReferences(response.result, token) } }), vscode.languages.registerRenameProvider(DEF_SELECTOR, { async prepareRename(document, position, token) { const response = await request<{ range: Range; placeholder: string }>( "nxPostSupport/def/prepareRename", document, position, token ) if (!response) { throw new Error("Only declared block templates and addresses can be renamed.") } return { range: response.client.protocol2CodeConverter.asRange(response.result.range), placeholder: response.result.placeholder } }, async provideRenameEdits(document, position, newName, token) { const response = await request("nxPostSupport/def/rename", document, position, token, { newName }) if (!response) { throw new Error(`"${newName}" is not a valid block template or address name.`) } return response.client.protocol2CodeConverter.asWorkspaceEdit(response.result, token) } }) ] }