22
33import { inspect } from "node:util" ;
44import { sync as commandExistsSync } from "command-exists" ;
5- import {
6- type Disposable ,
7- type ExtensionContext ,
8- env ,
9- Uri ,
10- window ,
11- workspace ,
12- } from "vscode" ;
5+ import { type Disposable , type ExtensionContext , env , Uri , window , workspace } from "vscode" ;
136import type {
147 CancellationToken ,
158 ConfigurationParams ,
169 LanguageClientOptions ,
1710 LSPArray ,
1811 MessageSignature ,
1912} from "vscode-languageclient" ;
20- import {
21- type Executable ,
22- LanguageClient ,
23- type ServerOptions ,
24- } from "vscode-languageclient/node" ;
13+ import { type Executable , LanguageClient , type ServerOptions } from "vscode-languageclient/node" ;
2514import { config , type UriMessageItem } from "./configuration" ;
2615
2716class Client extends LanguageClient {
@@ -35,18 +24,10 @@ class Client extends LanguageClient {
3524 showNotification ?: boolean ,
3625 ) : T {
3726 if ( config . hiddenErrorKinds . includes ( type . method ) ) {
38- this . outputChannel . appendLine (
39- `Suppressing failed ${ inspect ( type . method ) } notification` ,
40- ) ;
27+ this . outputChannel . appendLine ( `Suppressing failed ${ inspect ( type . method ) } notification` ) ;
4128 return super . handleFailedRequest ( type , token , error , defaultValue , false ) ;
4229 }
43- return super . handleFailedRequest (
44- type ,
45- token ,
46- error ,
47- defaultValue ,
48- showNotification ,
49- ) ;
30+ return super . handleFailedRequest ( type , token , error , defaultValue , showNotification ) ;
5031 }
5132
5233 override dispose ( timeout ?: number ) : Promise < void > {
@@ -70,25 +51,39 @@ class Client extends LanguageClient {
7051
7152let client : Client ;
7253
54+ const defaultServerCandidates = [ [ "nixd" ] , [ "nil" ] ] ;
55+
56+ function resolveServerPath ( ) : Array < string > {
57+ const configured = config . serverPath ;
58+ if ( configured . length > 0 ) {
59+ return configured ;
60+ }
61+
62+ for ( const candidate of defaultServerCandidates ) {
63+ if ( commandExistsSync ( candidate [ 0 ] ) ) {
64+ return candidate ;
65+ }
66+ }
67+
68+ return [ "nixd" ] ;
69+ }
70+
7371export async function activate ( context : ExtensionContext ) : Promise < void > {
74- if ( ! commandExistsSync ( config . serverPath [ 0 ] ) ) {
75- const selection = await window . showErrorMessage < UriMessageItem > (
76- `Command ${ config . serverPath } not found in $PATH` ,
77- {
78- title : "Install language server" ,
79- uri : Uri . parse (
80- "https://github.com/nix-community/vscode-nix-ide?tab=readme-ov-file#language-servers" ,
81- ) ,
82- } ,
83- ) ;
72+ const serverPath = resolveServerPath ( ) ;
73+
74+ if ( ! commandExistsSync ( serverPath [ 0 ] ) ) {
75+ const selection = await window . showErrorMessage < UriMessageItem > ( `Command ${ serverPath } not found in $PATH` , {
76+ title : "Install language server" ,
77+ uri : Uri . parse ( "https://github.com/nix-community/vscode-nix-ide?tab=readme-ov-file#language-servers" ) ,
78+ } ) ;
8479 if ( selection ?. uri !== undefined ) {
8580 await env . openExternal ( selection ?. uri ) ;
8681 return ;
8782 }
8883 }
8984 const serverExecutable : Executable = {
90- command : config . serverPath [ 0 ] ,
91- args : config . serverPath . slice ( 1 ) ,
85+ command : serverPath [ 0 ] ,
86+ args : serverPath . slice ( 1 ) ,
9287 } ;
9388 const serverOptions : ServerOptions = serverExecutable ;
9489
@@ -117,12 +112,9 @@ export async function activate(context: ExtensionContext): Promise<void> {
117112 if ( ! item ?. section ) {
118113 continue ;
119114 }
120- const sectionSettings =
121- settings [ item . section as keyof typeof settings ] ;
115+ const sectionSettings = settings [ item . section as keyof typeof settings ] ;
122116 if ( ! sectionSettings ) {
123- client . warn (
124- `failed to find "${ item . section } " in "nix.serverSettings"` ,
125- ) ;
117+ client . warn ( `failed to find "${ item . section } " in "nix.serverSettings"` ) ;
126118 }
127119 res . push ( sectionSettings ?? null ) ;
128120 }
@@ -149,9 +141,7 @@ export async function deactivate(): Promise<void> {
149141}
150142
151143export async function restart ( context : ExtensionContext ) : Promise < void > {
152- const restartingMsg = window . setStatusBarMessage (
153- "$(loading~spin) Restarting Nix language server" ,
154- ) ;
144+ const restartingMsg = window . setStatusBarMessage ( "$(loading~spin) Restarting Nix language server" ) ;
155145
156146 try {
157147 await deactivate ( ) ;
0 commit comments