diff --git a/client/src/extension.ts b/client/src/extension.ts index 728e7b5..df67c33 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -6,15 +6,18 @@ import * as vscode from 'vscode'; import * as which from 'which'; +import { window, type OutputChannel } from 'vscode'; import { LanguageClient, LanguageClientOptions, ServerOptions, + Trace, } from 'vscode-languageclient/node'; -import { time } from 'console'; let client: LanguageClient; +let outputChannel: OutputChannel; // Trace channel +let serverOutputChannel: OutputChannel; // Server logs channel (single instance) function findNushellExecutable(): string | null { try { @@ -48,6 +51,24 @@ function startLanguageServer( context: vscode.ExtensionContext, found_nushell_path: string, ): void { + // Prevent duplicate clients/channels + if (client) { + vscode.window.showInformationMessage( + 'Nushell Language Server is already running.', + ); + return; + } + // Channel to receive detailed JSON-RPC trace between VS Code and the LSP server + if (outputChannel) { + try { + outputChannel.dispose(); + } catch { + // ignore + } + } + outputChannel = window.createOutputChannel('Nushell LSP Trace'); + context.subscriptions.push(outputChannel); + // Use Nushell's native LSP server const serverOptions: ServerOptions = { run: { @@ -60,8 +81,22 @@ function startLanguageServer( }, }; + // Ensure a single server output channel exists and is reused + if (!serverOutputChannel) { + serverOutputChannel = window.createOutputChannel('Nushell Language Server'); + context.subscriptions.push(serverOutputChannel); + } + // Options to control the language client const clientOptions: LanguageClientOptions = { + // Route general server logs to a single, reusable channel + outputChannel: serverOutputChannel, + // Send JSON-RPC trace to a dedicated channel visible in the Output panel + traceOutputChannel: outputChannel, + markdown: { + isTrusted: true, + supportHtml: true, + }, initializationOptions: { timeout: 10000, // 10 seconds }, @@ -81,6 +116,43 @@ function startLanguageServer( clientOptions, ); + // Initialize trace level from settings and react to changes + const applyTraceFromConfig = () => { + const configured = vscode.workspace + .getConfiguration('nushellLanguageServer') + .get<'off' | 'messages' | 'verbose'>('trace.server'); + const level: 'off' | 'messages' | 'verbose' = configured ?? 'messages'; + const map: Record<'off' | 'messages' | 'verbose', Trace> = { + off: Trace.Off, + messages: Trace.Messages, + verbose: Trace.Verbose, + }; + client.setTrace(map[level]); + try { + outputChannel.appendLine(`[Nushell] JSON-RPC tracing set to: ${level}`); + if (level !== 'off') { + outputChannel.show(true); + } + } catch { + // ignore + } + }; + applyTraceFromConfig(); + const cfgDisp = vscode.workspace.onDidChangeConfiguration((e) => { + if (e.affectsConfiguration('nushellLanguageServer.trace.server')) { + applyTraceFromConfig(); + } + }); + context.subscriptions.push(cfgDisp); + // Log client lifecycle + client.onDidChangeState((e) => { + try { + outputChannel.appendLine(`[Nushell] Client state changed: ${e.newState}`); + } catch { + // ignore + } + }); + // Start the language client and register a disposable that stops it when disposed client.start().catch((error) => { vscode.window.showErrorMessage( @@ -168,6 +240,9 @@ export function activate(context: vscode.ExtensionContext) { return; } + console.log(`Found nushell executable at: ${found_nushell_path}`); + console.log('Activating Nushell Language Server extension.'); + // Start the language server when the extension is activated startLanguageServer(context, found_nushell_path); diff --git a/package-lock.json b/package-lock.json index e54ce78..098705d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "vscode-nushell-lang", - "version": "2.0.1", + "version": "2.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "vscode-nushell-lang", - "version": "2.0.1", + "version": "2.0.2", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index da59a55..6f1fcde 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "vscode-nushell-lang", "description": "nushell language for vscode", "author": "The Nushell Project Developers", - "version": "2.0.1", + "version": "2.0.2", "preview": false, "license": "MIT", "publisher": "TheNuProjectContributors", @@ -109,7 +109,7 @@ "messages", "verbose" ], - "default": "off", + "default": "messages", "description": "Traces the communication between VS Code and the language server." }, "nushellLanguageServer.hints.showInferredTypes": {