Files
nx_post_support/client/src/extension.ts
T

238 lines
8.5 KiB
TypeScript

import * as vscode from "vscode"
import {
LanguageClient,
LanguageClientOptions,
ServerOptions,
TransportKind
} from "vscode-languageclient/node"
import {
formatCdlFile,
completionHandlerCdl,
hoverCdlHandler,
formatDefFile,
isFirstLineMachine,
diagnosticHandler,
cdlDocumentSymbolProvider,
defDocumentSymbolProvider
} from "./common/handlers"
import { registerLogger, traceError, traceLog, traceVerbose } from "./common/log/logging"
import {
checkVersion,
getInterpreterDetails,
initializePython,
onDidChangePythonInterpreter,
resolveInterpreter
} from "./common/python"
import { restartServer } from "./common/server"
import { checkIfConfigurationChanged, getInterpreterFromSetting } from "./common/settings"
import { loadServerDefaults } from "./common/setup"
import { getLSClientTraceLevel } from "./common/utilities"
import { createOutputChannel, onDidChangeConfiguration, registerCommand } from "./common/vscodeapi"
let client: LanguageClient
export async function activate(context: vscode.ExtensionContext) {
// This is required to get server name and module. This should be
// the first thing that we do in this extension.
const serverInfo = loadServerDefaults()
const serverName = serverInfo.name
const serverId = serverInfo.module
// Setup logging
const outputChannel = createOutputChannel(serverName)
context.subscriptions.push(outputChannel, registerLogger(outputChannel))
const changeLogLevel = async (c: vscode.LogLevel, g: vscode.LogLevel) => {
const level = getLSClientTraceLevel(c, g)
await client?.setTrace(level)
}
context.subscriptions.push(
outputChannel.onDidChangeLogLevel(async (e) => {
await changeLogLevel(e, vscode.env.logLevel)
}),
vscode.env.onDidChangeLogLevel(async (e) => {
await changeLogLevel(outputChannel.logLevel, e)
})
)
// Log Server information
traceLog(`Name: ${serverInfo.name}`)
traceLog(`Module: ${serverInfo.module}`)
traceVerbose(`Full Server Info: ${JSON.stringify(serverInfo)}`)
const runServer = async () => {
const interpreter = getInterpreterFromSetting(serverId)
if (interpreter && interpreter.length > 0) {
if (checkVersion(await resolveInterpreter(interpreter))) {
traceVerbose(
`Using interpreter from ${serverInfo.module}.interpreter: ${interpreter.join(" ")}`
)
client = await restartServer(serverId, serverName, outputChannel, client)
}
return
}
const interpreterDetails = await getInterpreterDetails()
if (interpreterDetails.path) {
traceVerbose(
`Using interpreter from Python extension: ${interpreterDetails.path.join(" ")}`
)
client = await restartServer(serverId, serverName, outputChannel, client)
return
}
traceError(
"Python interpreter missing:\r\n" +
"[Option 1] Select python interpreter using the ms-python.python.\r\n" +
`[Option 2] Set an interpreter using "${serverId}.interpreter" setting.\r\n` +
"Please use Python 3.8 or greater."
)
}
context.subscriptions.push(
onDidChangePythonInterpreter(async () => {
await runServer()
}),
onDidChangeConfiguration(async (e: vscode.ConfigurationChangeEvent) => {
if (checkIfConfigurationChanged(e, serverId)) {
await runServer()
}
}),
registerCommand(`${serverId}.restart`, async () => {
await runServer()
})
)
setImmediate(async () => {
const interpreter = getInterpreterFromSetting(serverId)
if (interpreter === undefined || interpreter.length === 0) {
traceLog(`Python extension loading`)
await initializePython(context.subscriptions)
traceLog(`Python extension loaded`)
} else {
await runServer()
}
})
//
const formatCdlProvider = vscode.languages.registerDocumentFormattingEditProvider(
{ scheme: "file", language: "cdl" },
{
provideDocumentFormattingEdits(document: vscode.TextDocument): vscode.TextEdit[] {
const text = document.getText()
const formattedText = formatCdlFile(text)
const fullRange = new vscode.Range(
document.positionAt(0),
document.positionAt(text.length)
)
return [vscode.TextEdit.replace(fullRange, formattedText)]
}
}
)
context.subscriptions.push(formatCdlProvider)
const completionCdlProvider = vscode.languages.registerCompletionItemProvider(
{ scheme: "file", language: "cdl" },
{
provideCompletionItems(
document: vscode.TextDocument,
position: vscode.Position,
token: vscode.CancellationToken,
context: vscode.CompletionContext
) {
return completionHandlerCdl(document, position)
}
},
" " // Trigger completion on space
)
context.subscriptions.push(completionCdlProvider)
const hoverCdlProvider = vscode.languages.registerHoverProvider(
{ scheme: "file", language: "cdl" },
{
provideHover(
document: vscode.TextDocument,
position: vscode.Position,
token: vscode.CancellationToken
) {
return hoverCdlHandler(document, position)
}
}
)
context.subscriptions.push(hoverCdlProvider)
const formatDefProvider = vscode.languages.registerDocumentFormattingEditProvider(
{ scheme: "file", language: "def" },
{
provideDocumentFormattingEdits(document: vscode.TextDocument): vscode.TextEdit[] {
const text = document.getText()
const formattedText = formatDefFile(text)
const fullRange = new vscode.Range(
document.positionAt(0),
document.positionAt(text.length)
)
return [vscode.TextEdit.replace(fullRange, formattedText)]
}
}
)
context.subscriptions.push(formatDefProvider)
const cdlSymbolProvider = vscode.languages.registerDocumentSymbolProvider(
{ scheme: "file", language: "cdl" },
{
provideDocumentSymbols(document: vscode.TextDocument) {
return cdlDocumentSymbolProvider(document)
}
}
)
context.subscriptions.push(cdlSymbolProvider)
// Outline now provided by the language server (Document Symbols). Removing TS provider.
const defSymbolProvider = vscode.languages.registerDocumentSymbolProvider(
{ scheme: "file", language: "def" },
{
provideDocumentSymbols(document: vscode.TextDocument) {
return defDocumentSymbolProvider(document)
}
}
)
context.subscriptions.push(defSymbolProvider)
// Diagnostics collection
const diagnosticCollectionCdl = vscode.languages.createDiagnosticCollection("cdl")
const diagnosticCollectionDef = vscode.languages.createDiagnosticCollection("def")
context.subscriptions.push(diagnosticCollectionCdl, diagnosticCollectionDef)
// Check if the first line of the CDL file contains "MACHINE"
vscode.workspace.onDidOpenTextDocument((document) => {
if (document.languageId === "cdl" || document.languageId === "def") {
if (document.languageId === "cdl") {
diagnosticCollectionCdl.set(document.uri, diagnosticHandler(document))
} else if (document.languageId === "def") {
diagnosticCollectionDef.set(document.uri, diagnosticHandler(document))
}
}
})
vscode.workspace.onDidChangeTextDocument((event) => {
const document = event.document
if (document.languageId === "cdl" || document.languageId === "def") {
if (document.languageId === "cdl") {
diagnosticCollectionCdl.set(document.uri, diagnosticHandler(document))
} else if (document.languageId === "def") {
diagnosticCollectionDef.set(document.uri, diagnosticHandler(document))
}
}
})
}
export function deactivate(): Thenable<void> | undefined {
if (!client) {
return undefined
}
return client.stop()
}