66
77import * as vscode from 'vscode' ;
88import * as which from 'which' ;
9+ import { window , type OutputChannel } from 'vscode' ;
910
1011import {
1112 LanguageClient ,
1213 LanguageClientOptions ,
1314 ServerOptions ,
15+ Trace ,
1416} from 'vscode-languageclient/node' ;
15- import { time } from 'console' ;
1617
1718let client : LanguageClient ;
19+ let outputChannel : OutputChannel ; // Trace channel
20+ let serverOutputChannel : OutputChannel ; // Server logs channel (single instance)
1821
1922function findNushellExecutable ( ) : string | null {
2023 try {
@@ -48,6 +51,24 @@ function startLanguageServer(
4851 context : vscode . ExtensionContext ,
4952 found_nushell_path : string ,
5053) : void {
54+ // Prevent duplicate clients/channels
55+ if ( client ) {
56+ vscode . window . showInformationMessage (
57+ 'Nushell Language Server is already running.' ,
58+ ) ;
59+ return ;
60+ }
61+ // Channel to receive detailed JSON-RPC trace between VS Code and the LSP server
62+ if ( outputChannel ) {
63+ try {
64+ outputChannel . dispose ( ) ;
65+ } catch {
66+ // ignore
67+ }
68+ }
69+ outputChannel = window . createOutputChannel ( 'Nushell LSP Trace' ) ;
70+ context . subscriptions . push ( outputChannel ) ;
71+
5172 // Use Nushell's native LSP server
5273 const serverOptions : ServerOptions = {
5374 run : {
@@ -60,8 +81,22 @@ function startLanguageServer(
6081 } ,
6182 } ;
6283
84+ // Ensure a single server output channel exists and is reused
85+ if ( ! serverOutputChannel ) {
86+ serverOutputChannel = window . createOutputChannel ( 'Nushell Language Server' ) ;
87+ context . subscriptions . push ( serverOutputChannel ) ;
88+ }
89+
6390 // Options to control the language client
6491 const clientOptions : LanguageClientOptions = {
92+ // Route general server logs to a single, reusable channel
93+ outputChannel : serverOutputChannel ,
94+ // Send JSON-RPC trace to a dedicated channel visible in the Output panel
95+ traceOutputChannel : outputChannel ,
96+ markdown : {
97+ isTrusted : true ,
98+ supportHtml : true ,
99+ } ,
65100 initializationOptions : {
66101 timeout : 10000 , // 10 seconds
67102 } ,
@@ -81,6 +116,43 @@ function startLanguageServer(
81116 clientOptions ,
82117 ) ;
83118
119+ // Initialize trace level from settings and react to changes
120+ const applyTraceFromConfig = ( ) => {
121+ const configured = vscode . workspace
122+ . getConfiguration ( 'nushellLanguageServer' )
123+ . get < 'off' | 'messages' | 'verbose' > ( 'trace.server' ) ;
124+ const level : 'off' | 'messages' | 'verbose' = configured ?? 'messages' ;
125+ const map : Record < 'off' | 'messages' | 'verbose' , Trace > = {
126+ off : Trace . Off ,
127+ messages : Trace . Messages ,
128+ verbose : Trace . Verbose ,
129+ } ;
130+ client . setTrace ( map [ level ] ) ;
131+ try {
132+ outputChannel . appendLine ( `[Nushell] JSON-RPC tracing set to: ${ level } ` ) ;
133+ if ( level !== 'off' ) {
134+ outputChannel . show ( true ) ;
135+ }
136+ } catch {
137+ // ignore
138+ }
139+ } ;
140+ applyTraceFromConfig ( ) ;
141+ const cfgDisp = vscode . workspace . onDidChangeConfiguration ( ( e ) => {
142+ if ( e . affectsConfiguration ( 'nushellLanguageServer.trace.server' ) ) {
143+ applyTraceFromConfig ( ) ;
144+ }
145+ } ) ;
146+ context . subscriptions . push ( cfgDisp ) ;
147+ // Log client lifecycle
148+ client . onDidChangeState ( ( e ) => {
149+ try {
150+ outputChannel . appendLine ( `[Nushell] Client state changed: ${ e . newState } ` ) ;
151+ } catch {
152+ // ignore
153+ }
154+ } ) ;
155+
84156 // Start the language client and register a disposable that stops it when disposed
85157 client . start ( ) . catch ( ( error ) => {
86158 vscode . window . showErrorMessage (
@@ -168,6 +240,9 @@ export function activate(context: vscode.ExtensionContext) {
168240 return ;
169241 }
170242
243+ console . log ( `Found nushell executable at: ${ found_nushell_path } ` ) ;
244+ console . log ( 'Activating Nushell Language Server extension.' ) ;
245+
171246 // Start the language server when the extension is activated
172247 startLanguageServer ( context , found_nushell_path ) ;
173248
0 commit comments