diff --git a/src/RunDebugCodeLens.ts b/src/RunDebugCodeLens.ts new file mode 100644 index 0000000..c7da3f9 --- /dev/null +++ b/src/RunDebugCodeLens.ts @@ -0,0 +1,37 @@ +import * as vscode from 'vscode'; + + +export class RunDebugCodeLens implements vscode.CodeLensProvider { + async provideCodeLenses(document: vscode.TextDocument, token: vscode.CancellationToken): Promise { + const mainInfo = await vscode.commands.executeCommand("kotlin.resolveMain", document.uri.toString()) as MainInfo + + if(mainInfo && mainInfo.mainClass) { + return [ + new vscode.CodeLens( + mainInfo.range, + { + title: "Run", + command: "kotlin.runMain", + arguments: [mainInfo.mainClass, mainInfo.projectRoot] + } + ), + new vscode.CodeLens( + mainInfo.range, + { + title: "Debug", + command: "kotlin.debugMain", + arguments: [mainInfo.mainClass, mainInfo.projectRoot] + } + ) + ] + } + + return [] + } +} + +interface MainInfo { + mainClass: String, + projectRoot: String, + range: vscode.Range +} diff --git a/src/languageSetup.ts b/src/languageSetup.ts index 5e85e62..76b1683 100644 --- a/src/languageSetup.ts +++ b/src/languageSetup.ts @@ -11,6 +11,8 @@ import { Status } from "./util/status"; import { JarClassContentProvider } from "./jarClassContentProvider"; import { KotlinApi } from "./lspExtensions"; import { fsExists } from "./util/fsUtils"; +import { RunDebugCodeLens } from "./RunDebugCodeLens"; +import { MainClassRequest } from "./lspExtensions"; /** Downloads and starts the language server. */ export async function activateLanguageServer(context: vscode.ExtensionContext, status: Status, config: vscode.WorkspaceConfiguration): Promise { @@ -89,6 +91,40 @@ export async function activateLanguageServer(context: vscode.ExtensionContext, s context.subscriptions.push(languageClientDisposable); })); + // Activating run/debug code lens if the debug adapter is enabled + const kotlinConfig = vscode.workspace.getConfiguration("kotlin"); + const debugAdapterEnabled = kotlinConfig.get("debugAdapter.enabled"); + if(debugAdapterEnabled) { + vscode.languages.registerCodeLensProvider("kotlin", new RunDebugCodeLens()) + + vscode.commands.registerCommand("kotlin.resolveMain", async(fileUri) => { + return await languageClient.sendRequest(MainClassRequest.type, { + uri: fileUri + }) + }) + + vscode.commands.registerCommand("kotlin.runMain", async(mainClass, projectRoot) => { + vscode.debug.startDebugging(vscode.workspace.getWorkspaceFolder(vscode.Uri.file(projectRoot)), { + type: "kotlin", + name: "Run Kotlin main", + request: "launch", + noDebug: true, + mainClass, + projectRoot, + }) + }); + + vscode.commands.registerCommand("kotlin.debugMain", async(mainClass, projectRoot) => { + vscode.debug.startDebugging(vscode.workspace.getWorkspaceFolder(vscode.Uri.file(projectRoot)), { + type: "kotlin", + name: "Debug Kotlin main", + request: "launch", + mainClass, + projectRoot, + }) + }); + } + await languageClient.onReady(); return new KotlinApi(languageClient); diff --git a/src/lspExtensions.ts b/src/lspExtensions.ts index 2d26a48..09735a7 100644 --- a/src/lspExtensions.ts +++ b/src/lspExtensions.ts @@ -6,6 +6,10 @@ export namespace JarClassContentsRequest { export const type = new RequestType("kotlin/jarClassContents"); } +export namespace MainClassRequest { + export const type = new RequestType("kotlin/mainClass") +} + export namespace BuildOutputLocationRequest { export const type = new RequestType0("kotlin/buildOutputLocation"); }