@@ -6,6 +6,8 @@ import { Config, substituteVariablesInEnv, substituteVSCodeVariables } from "./c
66import { createClient } from "./client" ;
77import { isRustEditor , log , RustEditor } from "./util" ;
88import { ServerStatusParams } from "./lsp_ext" ;
9+ import { PersistentState } from "./persistent_state" ;
10+ import { bootstrap } from "./bootstrap" ;
911
1012export type Workspace =
1113 | {
@@ -17,28 +19,18 @@ export type Workspace =
1719 } ;
1820
1921export class Ctx {
20- private client : lc . LanguageClient | undefined ;
21- readonly config : Config ;
22- serverPath : string ;
2322 readonly statusBar : vscode . StatusBarItem ;
23+ readonly config : Config ;
24+
25+ private client : lc . LanguageClient | undefined ;
2426
2527 traceOutputChannel : vscode . OutputChannel | undefined ;
2628 outputChannel : vscode . OutputChannel | undefined ;
27-
28- serverOptions :
29- | {
30- run : lc . Executable ;
31- debug : lc . Executable ;
32- }
33- | undefined ;
3429 workspace : Workspace ;
30+ state : PersistentState ;
31+ serverPath : string | undefined ;
3532
36- constructor (
37- readonly extCtx : vscode . ExtensionContext ,
38- config : Config ,
39- serverPath : string ,
40- workspace : Workspace
41- ) {
33+ constructor ( readonly extCtx : vscode . ExtensionContext , workspace : Workspace ) {
4234 this . statusBar = vscode . window . createStatusBarItem ( vscode . StatusBarAlignment . Left ) ;
4335 extCtx . subscriptions . push ( this . statusBar ) ;
4436 extCtx . subscriptions . push ( {
@@ -50,9 +42,10 @@ export class Ctx {
5042 this . statusBar . tooltip = "ready" ;
5143 this . statusBar . command = "rust-analyzer.analyzerStatus" ;
5244 this . statusBar . show ( ) ;
53- this . serverPath = serverPath ;
54- this . config = config ;
5545 this . workspace = workspace ;
46+
47+ this . state = new PersistentState ( extCtx . globalState ) ;
48+ this . config = new Config ( extCtx ) ;
5649 }
5750
5851 clientFetcher ( ) {
@@ -64,6 +57,7 @@ export class Ctx {
6457 }
6558
6659 async getClient ( ) {
60+ // if server path changes -> dispose
6761 if ( ! this . traceOutputChannel ) {
6862 this . traceOutputChannel = vscode . window . createOutputChannel (
6963 "Rust Analyzer Language Server Trace"
@@ -72,25 +66,32 @@ export class Ctx {
7266 if ( ! this . outputChannel ) {
7367 this . outputChannel = vscode . window . createOutputChannel ( "Rust Analyzer Language Server" ) ;
7468 }
75- if ( ! this . serverOptions ) {
76- log . info ( "Creating server options client" ) ;
69+
70+ if ( ! this . client ) {
71+ log . info ( "Creating language client" ) ;
72+
73+ this . serverPath = await bootstrap ( this . extCtx , this . config , this . state ) . catch ( ( err ) => {
74+ let message = "bootstrap error. " ;
75+
76+ message +=
77+ 'See the logs in "OUTPUT > Rust Analyzer Client" (should open automatically). ' ;
78+ message += 'To enable verbose logs use { "rust-analyzer.trace.extension": true }' ;
79+
80+ log . error ( "Bootstrap error" , err ) ;
81+ throw new Error ( message ) ;
82+ } ) ;
7783 const newEnv = substituteVariablesInEnv (
7884 Object . assign ( { } , process . env , this . config . serverExtraEnv )
7985 ) ;
8086 const run : lc . Executable = {
8187 command : this . serverPath ,
8288 options : { env : newEnv } ,
8389 } ;
84- this . serverOptions = {
90+ const serverOptions = {
8591 run,
8692 debug : run ,
8793 } ;
88- } else {
89- this . serverOptions . run . command = this . serverPath ;
90- this . serverOptions . debug . command = this . serverPath ;
91- }
92- if ( ! this . client ) {
93- log . info ( "Creating language client" ) ;
94+
9495 let rawInitializationOptions = vscode . workspace . getConfiguration ( "rust-analyzer" ) ;
9596
9697 if ( this . workspace . kind === "Detached Files" ) {
@@ -106,7 +107,7 @@ export class Ctx {
106107 this . traceOutputChannel ,
107108 this . outputChannel ,
108109 initializationOptions ,
109- this . serverOptions
110+ serverOptions
110111 ) ;
111112 this . client . onNotification ( ra . serverStatus , ( params ) => this . setServerStatus ( params ) ) ;
112113 }
@@ -128,6 +129,7 @@ export class Ctx {
128129 async disposeClient ( ) {
129130 log . info ( "Deactivating language client" ) ;
130131 await this . client ?. dispose ( ) ;
132+ this . serverPath = undefined ;
131133 this . client = undefined ;
132134 }
133135
0 commit comments