Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@
"command": "kotlin.overrideMember",
"title": "Override member(s)",
"category": "Kotlin"
},
{
"command": "kotlin.restartLanguageServer",
"title": "Kotlin: Restart Language Server"
}
],
"menus": {
Expand Down Expand Up @@ -297,7 +301,12 @@
"kotlin.diagnostics.level": {
"type": "string",
"default": "hint",
"enum": ["error", "warning", "information", "hint"],
"enum": [
"error",
"warning",
"information",
"hint"
],
"description": "The minimum severity of diagnostics to emit."
},
"kotlin.diagnostics.debounceTime": {
Expand Down Expand Up @@ -413,4 +422,4 @@
"vscode-debugprotocol": "^1.47.0",
"vscode-languageclient": "8.0.2-next.5"
}
}
}
50 changes: 29 additions & 21 deletions src/languageSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ import { MainClassRequest, OverrideMemberRequest } from "./lspExtensions";
export async function activateLanguageServer({ context, status, config, javaInstallation, javaOpts }: ServerSetupParams): Promise<KotlinApi> {
LOG.info('Activating Kotlin Language Server...');
status.update("Activating Kotlin Language Server...");

// Prepare language server
const langServerInstallDir = path.join(context.globalStorageUri.fsPath, "langServerInstall");
const customPath: string = config.get("languageServer.path");

if (!customPath) {
const langServerDownloader = new ServerDownloader("Kotlin Language Server", "kotlin-language-server", "server.zip", "server", langServerInstallDir);

try {
await langServerDownloader.downloadServerIfNeeded(status);
} catch (error) {
Expand All @@ -37,7 +37,7 @@ export async function activateLanguageServer({ context, status, config, javaInst

const outputChannel = vscode.window.createOutputChannel("Kotlin");
context.subscriptions.push(outputChannel);

const transportLayer = config.get("languageServer.transport");
let tcpPort: number = null;
let env: any = { ...process.env };
Expand All @@ -52,7 +52,7 @@ export async function activateLanguageServer({ context, status, config, javaInst

if (transportLayer == "tcp") {
tcpPort = config.get("languageServer.port");

LOG.info(`Connecting via TCP, port: ${tcpPort}`);
} else if (transportLayer == "stdio") {
LOG.info("Connecting via Stdio.");
Expand All @@ -67,7 +67,7 @@ export async function activateLanguageServer({ context, status, config, javaInst
}

status.dispose();

const startScriptPath = customPath || path.resolve(langServerInstallDir, "server", "bin", correctScriptName("kotlin-language-server"));

const storagePath = context.storageUri.fsPath
Expand All @@ -90,13 +90,13 @@ export async function activateLanguageServer({ context, status, config, javaInst

// Create the language client and start the client.
let languageClientPromise = languageClient.start();

// Register a content provider for the 'kls' scheme
const contentProvider = new JarClassContentProvider(languageClient);
context.subscriptions.push(vscode.workspace.registerTextDocumentContentProvider("kls", contentProvider));

// register override members command
vscode.commands.registerCommand("kotlin.overrideMember", async() => {
vscode.commands.registerCommand("kotlin.overrideMember", async () => {
const activeEditor = vscode.window.activeTextEditor;
const currentDocument = activeEditor?.document;
// TODO: seems like we cant interact with the inner edit-fields as if it were a WorkspaceEdit object?? See if there is a way to solve this
Expand All @@ -108,11 +108,11 @@ export async function activateLanguageServer({ context, status, config, javaInst
});

// show an error message if nothing is found
if(0 == overrideOptions.length) {
if (0 == overrideOptions.length) {
vscode.window.showWarningMessage("No overrides found for class");
return;
}

const selected = await vscode.window.showQuickPick(overrideOptions.map(elem => ({
label: elem.title,
data: elem.edit.changes[currentDocument.uri.toString()]
Expand All @@ -131,39 +131,47 @@ export async function activateLanguageServer({ context, status, config, javaInst
});
});

vscode.commands.registerCommand("kotlin.restartLanguageServer", async () => {
if (languageClient) {
await languageClient.stop();
await languageClient.start();
vscode.window.showInformationMessage('Kotlin Language Server restarted');
}
});

// Activating run/debug code lens if the debug adapter is enabled
// and we are using 'kotlin-language-server' (other language servers
// might not support the non-standard 'kotlin/mainClass' request)
const debugAdapterEnabled = config.get("debugAdapter.enabled");
const usesStandardLanguageServer = startScriptPath.endsWith("kotlin-language-server");
if (debugAdapterEnabled && usesStandardLanguageServer) {
vscode.languages.registerCodeLensProvider("kotlin", new RunDebugCodeLens())
vscode.commands.registerCommand("kotlin.resolveMain", async(fileUri) => {

vscode.commands.registerCommand("kotlin.resolveMain", async (fileUri) => {
return await languageClient.sendRequest(MainClassRequest.type, {
uri: fileUri
})
});
vscode.commands.registerCommand("kotlin.runMain", async(mainClass, projectRoot) => {

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.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,
})
})
});
}

Expand Down Expand Up @@ -206,15 +214,15 @@ function createLanguageClient(options: {
storagePath: options.storagePath
}
}

// Ensure that start script can be executed
if (isOSUnixoid()) {
child_process.exec(`chmod +x ${options.startScriptPath}`);
}

// Start the child Java process
let serverOptions: ServerOptions;

if (options.tcpPort) {
serverOptions = () => spawnLanguageServerProcessAndConnectViaTcp(options);
} else {
Expand Down Expand Up @@ -250,7 +258,7 @@ export function spawnLanguageServerProcessAndConnectViaTcp(options: {
const tcpPort = (server.address() as net.AddressInfo).port.toString();
const proc = child_process.spawn(options.startScriptPath, ["--tcpClientPort", tcpPort], { shell: isOSWindows() });
LOG.info("Creating client at {} via TCP port {}", options.startScriptPath, tcpPort);

const outputCallback = data => options.outputChannel.append(`${data}`);
proc.stdout.on("data", outputCallback);
proc.stderr.on("data", outputCallback);
Expand Down