@@ -100,19 +100,21 @@ function onDidChangeActiveTextEditor(editor: TextEditor | undefined) {
100
100
const { languageId, uri } = editor . document ;
101
101
102
102
const workspace = clientWorkspaceForUri ( uri , {
103
- startIfMissing : languageId === 'rust' || languageId === 'toml' ,
103
+ initializeIfMissing : languageId === 'rust' || languageId === 'toml' ,
104
104
} ) ;
105
105
if ( ! workspace ) {
106
106
return ;
107
107
}
108
108
109
109
activeWorkspace = workspace ;
110
110
111
- const updateProgress = ( progress : { message : string } | null ) => {
112
- if ( progress ) {
111
+ const updateProgress = ( progress : WorkspaceProgress ) => {
112
+ if ( progress . state === 'progress' ) {
113
113
startSpinner ( `[${ workspace . folder . name } ] ${ progress . message } ` ) ;
114
114
} else {
115
- stopSpinner ( `[${ workspace . folder . name } ]` ) ;
115
+ const readySymbol =
116
+ progress . state === 'standby' ? '$(debug-stop)' : '$(debug-start)' ;
117
+ stopSpinner ( `[${ workspace . folder . name } ] ${ readySymbol } ` ) ;
116
118
}
117
119
} ;
118
120
@@ -139,12 +141,12 @@ function whenChangingWorkspaceFolders(e: WorkspaceFoldersChangeEvent) {
139
141
const workspaces : Map < string , ClientWorkspace > = new Map ( ) ;
140
142
141
143
/**
142
- * Fetches a `ClientWorkspace` for a given URI. If missing and `startIfMissing `
144
+ * Fetches a `ClientWorkspace` for a given URI. If missing and `initializeIfMissing `
143
145
* option was provided, it is additionally initialized beforehand, if applicable.
144
146
*/
145
147
function clientWorkspaceForUri (
146
148
uri : Uri ,
147
- options ?: { startIfMissing : boolean } ,
149
+ options ?: { initializeIfMissing : boolean } ,
148
150
) : ClientWorkspace | undefined {
149
151
const rootFolder = workspace . getWorkspaceFolder ( uri ) ;
150
152
if ( ! rootFolder ) {
@@ -157,15 +159,20 @@ function clientWorkspaceForUri(
157
159
}
158
160
159
161
const existing = workspaces . get ( folder . uri . toString ( ) ) ;
160
- if ( ! existing && options && options . startIfMissing ) {
162
+ if ( ! existing && options && options . initializeIfMissing ) {
161
163
const workspace = new ClientWorkspace ( folder ) ;
162
164
workspaces . set ( folder . uri . toString ( ) , workspace ) ;
163
- workspace . start ( ) ;
165
+ workspace . autoStart ( ) ;
164
166
}
165
167
166
168
return workspaces . get ( folder . uri . toString ( ) ) ;
167
169
}
168
170
171
+ /** Denotes the state or progress the workspace is currently in. */
172
+ type WorkspaceProgress =
173
+ | { state : 'progress' ; message : string }
174
+ | { state : 'ready' | 'standby' } ;
175
+
169
176
// We run one RLS and one corresponding language client per workspace folder
170
177
// (VSCode workspace, not Cargo workspace). This class contains all the per-client
171
178
// and per-workspace stuff.
@@ -176,7 +183,7 @@ class ClientWorkspace {
176
183
private readonly config : RLSConfiguration ;
177
184
private lc : LanguageClient | null = null ;
178
185
private disposables : Disposable [ ] ;
179
- private _progress : Observable < { message : string } | null > ;
186
+ private _progress : Observable < WorkspaceProgress > ;
180
187
get progress ( ) {
181
188
return this . _progress ;
182
189
}
@@ -185,11 +192,20 @@ class ClientWorkspace {
185
192
this . config = RLSConfiguration . loadFromWorkspace ( folder . uri . fsPath ) ;
186
193
this . folder = folder ;
187
194
this . disposables = [ ] ;
188
- this . _progress = new Observable < { message : string } | null > ( null ) ;
195
+ this . _progress = new Observable < WorkspaceProgress > ( { state : 'standby' } ) ;
196
+ }
197
+
198
+ /**
199
+ * Attempts to start a server instance, if not configured otherwise via
200
+ * applicable `rust-client.autoStartRls` setting.
201
+ * @returns whether the server has started.
202
+ */
203
+ public async autoStart ( ) {
204
+ return this . config . autoStartRls && this . start ( ) . then ( ( ) => true ) ;
189
205
}
190
206
191
207
public async start ( ) {
192
- this . _progress . value = { message : 'Starting' } ;
208
+ this . _progress . value = { state : 'progress' , message : 'Starting' } ;
193
209
194
210
const serverOptions : ServerOptions = async ( ) => {
195
211
await this . autoUpdate ( ) ;
@@ -265,6 +281,8 @@ class ClientWorkspace {
265
281
public async stop ( ) {
266
282
if ( this . lc ) {
267
283
await this . lc . stop ( ) ;
284
+ this . lc = null ;
285
+ this . _progress . value = { state : 'standby' } ;
268
286
}
269
287
270
288
this . disposables . forEach ( d => d . dispose ( ) ) ;
@@ -308,9 +326,9 @@ class ClientWorkspace {
308
326
} else if ( progress . title ) {
309
327
status = `[${ progress . title . toLowerCase ( ) } ]` ;
310
328
}
311
- this . _progress . value = { message : status } ;
329
+ this . _progress . value = { state : 'progress' , message : status } ;
312
330
} else {
313
- this . _progress . value = null ;
331
+ this . _progress . value = { state : 'ready' } ;
314
332
}
315
333
} ,
316
334
) ;
@@ -466,6 +484,14 @@ function registerCommands(): Disposable[] {
466
484
'rls.run' ,
467
485
( cmd : Execution ) => activeWorkspace && activeWorkspace . runRlsCommand ( cmd ) ,
468
486
) ,
487
+ commands . registerCommand (
488
+ 'rls.start' ,
489
+ ( ) => activeWorkspace && activeWorkspace . start ( ) ,
490
+ ) ,
491
+ commands . registerCommand (
492
+ 'rls.stop' ,
493
+ ( ) => activeWorkspace && activeWorkspace . stop ( ) ,
494
+ ) ,
469
495
] ;
470
496
}
471
497
0 commit comments