222 lines
7.9 KiB
TypeScript
222 lines
7.9 KiB
TypeScript
import * as vscode from "vscode"
|
|
import {
|
|
LanguageClient,
|
|
LanguageClientOptions,
|
|
ServerOptions,
|
|
TransportKind
|
|
} from "vscode-languageclient/node"
|
|
import {
|
|
formatCdlFile,
|
|
completionHandlerCdl,
|
|
hoverCdlHandler,
|
|
formatDefFile,
|
|
isFirstLineMachine,
|
|
diagnosticHandler,
|
|
tclDocumentSymbolProvider
|
|
} 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 tclOutlineProvider = vscode.languages.registerDocumentSymbolProvider(
|
|
{ scheme: "file", language: "tcl" },
|
|
{ provideDocumentSymbols: tclDocumentSymbolProvider }
|
|
)
|
|
context.subscriptions.push(tclOutlineProvider)
|
|
|
|
// 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()
|
|
}
|