@@ -6,6 +6,8 @@ import { Config, substituteVariablesInEnv, substituteVSCodeVariables } from "./c
6
6
import { createClient } from "./client" ;
7
7
import { isRustEditor , log , RustEditor } from "./util" ;
8
8
import { ServerStatusParams } from "./lsp_ext" ;
9
+ import { PersistentState } from "./persistent_state" ;
10
+ import { bootstrap } from "./bootstrap" ;
9
11
10
12
export type Workspace =
11
13
| {
@@ -17,28 +19,18 @@ export type Workspace =
17
19
} ;
18
20
19
21
export class Ctx {
20
- private client : lc . LanguageClient | undefined ;
21
- readonly config : Config ;
22
- serverPath : string ;
23
22
readonly statusBar : vscode . StatusBarItem ;
23
+ readonly config : Config ;
24
+
25
+ private client : lc . LanguageClient | undefined ;
24
26
25
27
traceOutputChannel : vscode . OutputChannel | undefined ;
26
28
outputChannel : vscode . OutputChannel | undefined ;
27
-
28
- serverOptions :
29
- | {
30
- run : lc . Executable ;
31
- debug : lc . Executable ;
32
- }
33
- | undefined ;
34
29
workspace : Workspace ;
30
+ state : PersistentState ;
31
+ serverPath : string | undefined ;
35
32
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 ) {
42
34
this . statusBar = vscode . window . createStatusBarItem ( vscode . StatusBarAlignment . Left ) ;
43
35
extCtx . subscriptions . push ( this . statusBar ) ;
44
36
extCtx . subscriptions . push ( {
@@ -50,9 +42,10 @@ export class Ctx {
50
42
this . statusBar . tooltip = "ready" ;
51
43
this . statusBar . command = "rust-analyzer.analyzerStatus" ;
52
44
this . statusBar . show ( ) ;
53
- this . serverPath = serverPath ;
54
- this . config = config ;
55
45
this . workspace = workspace ;
46
+
47
+ this . state = new PersistentState ( extCtx . globalState ) ;
48
+ this . config = new Config ( extCtx ) ;
56
49
}
57
50
58
51
clientFetcher ( ) {
@@ -64,6 +57,7 @@ export class Ctx {
64
57
}
65
58
66
59
async getClient ( ) {
60
+ // if server path changes -> dispose
67
61
if ( ! this . traceOutputChannel ) {
68
62
this . traceOutputChannel = vscode . window . createOutputChannel (
69
63
"Rust Analyzer Language Server Trace"
@@ -72,25 +66,32 @@ export class Ctx {
72
66
if ( ! this . outputChannel ) {
73
67
this . outputChannel = vscode . window . createOutputChannel ( "Rust Analyzer Language Server" ) ;
74
68
}
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
+ } ) ;
77
83
const newEnv = substituteVariablesInEnv (
78
84
Object . assign ( { } , process . env , this . config . serverExtraEnv )
79
85
) ;
80
86
const run : lc . Executable = {
81
87
command : this . serverPath ,
82
88
options : { env : newEnv } ,
83
89
} ;
84
- this . serverOptions = {
90
+ const serverOptions = {
85
91
run,
86
92
debug : run ,
87
93
} ;
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
+
94
95
let rawInitializationOptions = vscode . workspace . getConfiguration ( "rust-analyzer" ) ;
95
96
96
97
if ( this . workspace . kind === "Detached Files" ) {
@@ -106,7 +107,7 @@ export class Ctx {
106
107
this . traceOutputChannel ,
107
108
this . outputChannel ,
108
109
initializationOptions ,
109
- this . serverOptions
110
+ serverOptions
110
111
) ;
111
112
this . client . onNotification ( ra . serverStatus , ( params ) => this . setServerStatus ( params ) ) ;
112
113
}
@@ -128,6 +129,7 @@ export class Ctx {
128
129
async disposeClient ( ) {
129
130
log . info ( "Deactivating language client" ) ;
130
131
await this . client ?. dispose ( ) ;
132
+ this . serverPath = undefined ;
131
133
this . client = undefined ;
132
134
}
133
135
0 commit comments