@@ -44,23 +44,24 @@ interface ProgressParams {
44
44
45
45
export async function activate ( context : ExtensionContext ) {
46
46
context . subscriptions . push ( configureLanguage ( ) ) ;
47
+ context . subscriptions . push ( ...registerCommands ( ) ) ;
47
48
48
- workspace . onDidOpenTextDocument ( doc => whenOpeningTextDocument ( doc , context ) ) ;
49
- workspace . textDocuments . forEach ( doc => whenOpeningTextDocument ( doc , context ) ) ;
50
- workspace . onDidChangeWorkspaceFolders ( e =>
51
- whenChangingWorkspaceFolders ( e , context ) ,
49
+ workspace . onDidOpenTextDocument ( doc => whenOpeningTextDocument ( doc ) ) ;
50
+ workspace . onDidChangeWorkspaceFolders ( e => whenChangingWorkspaceFolders ( e ) ) ;
51
+ window . onDidChangeActiveTextEditor (
52
+ ed => ed && whenOpeningTextDocument ( ed . document ) ,
52
53
) ;
54
+ // Installed listeners don't fire immediately for already opened files, so
55
+ // trigger an open event manually to fire up RLS instances where needed
56
+ workspace . textDocuments . forEach ( whenOpeningTextDocument ) ;
53
57
}
54
58
55
59
export async function deactivate ( ) {
56
60
return Promise . all ( [ ...workspaces . values ( ) ] . map ( ws => ws . stop ( ) ) ) ;
57
61
}
58
62
59
63
// Taken from https://github.com/Microsoft/vscode-extension-samples/blob/master/lsp-multi-server-sample/client/src/extension.ts
60
- function whenOpeningTextDocument (
61
- document : TextDocument ,
62
- context : ExtensionContext ,
63
- ) {
64
+ function whenOpeningTextDocument ( document : TextDocument ) {
64
65
if ( document . languageId !== 'rust' && document . languageId !== 'toml' ) {
65
66
return ;
66
67
}
@@ -96,7 +97,7 @@ function whenOpeningTextDocument(
96
97
const workspace = new ClientWorkspace ( folder ) ;
97
98
activeWorkspace = workspace ;
98
99
workspaces . set ( folderPath , workspace ) ;
99
- workspace . start ( context ) ;
100
+ workspace . start ( ) ;
100
101
} else {
101
102
const ws = workspaces . get ( folderPath ) ;
102
103
activeWorkspace = typeof ws === 'undefined' ? null : ws ;
@@ -140,10 +141,7 @@ function getOuterMostWorkspaceFolder(folder: WorkspaceFolder): WorkspaceFolder {
140
141
return folder ;
141
142
}
142
143
143
- function whenChangingWorkspaceFolders (
144
- e : WorkspaceFoldersChangeEvent ,
145
- context : ExtensionContext ,
146
- ) {
144
+ function whenChangingWorkspaceFolders ( e : WorkspaceFoldersChangeEvent ) {
147
145
_sortedWorkspaceFolders = undefined ;
148
146
149
147
// If a VSCode workspace has been added, check to see if it is part of an existing one, and
@@ -157,7 +155,7 @@ function whenChangingWorkspaceFolders(
157
155
if ( f === 'Cargo.toml' ) {
158
156
const workspace = new ClientWorkspace ( folder ) ;
159
157
workspaces . set ( folder . uri . toString ( ) , workspace ) ;
160
- workspace . start ( context ) ;
158
+ workspace . start ( ) ;
161
159
break ;
162
160
}
163
161
}
@@ -175,8 +173,6 @@ function whenChangingWorkspaceFolders(
175
173
176
174
// Don't use URI as it's unreliable the same path might not become the same URI.
177
175
const workspaces : Map < string , ClientWorkspace > = new Map ( ) ;
178
- let activeWorkspace : ClientWorkspace | null ;
179
- let commandsRegistered : boolean = false ;
180
176
181
177
// We run one RLS and one corresponding language client per workspace folder
182
178
// (VSCode workspace, not Cargo workspace). This class contains all the per-client
@@ -195,7 +191,7 @@ class ClientWorkspace {
195
191
this . disposables = [ ] ;
196
192
}
197
193
198
- public async start ( context : ExtensionContext ) {
194
+ public async start ( ) {
199
195
if ( ! this . config . multiProjectEnabled ) {
200
196
warnOnMissingCargoToml ( ) ;
201
197
}
@@ -213,13 +209,9 @@ class ClientWorkspace {
213
209
const isWin = process . platform === 'win32' ;
214
210
const windowsHack = isWin ? '**' : '' ;
215
211
216
- const pattern = this . config . multiProjectEnabled
217
- ? `${ windowsHack } ${ this . folder . uri . path } /**`
218
- : undefined ;
212
+ const pattern = `${ windowsHack } ${ this . folder . uri . path } /**` ;
219
213
220
- const collectionName = this . config . multiProjectEnabled
221
- ? `rust ${ this . folder . uri . toString ( ) } `
222
- : 'rust' ;
214
+ const collectionName = `rust (${ this . folder . uri . toString ( ) } )` ;
223
215
const clientOptions : LanguageClientOptions = {
224
216
// Register the server for Rust files
225
217
@@ -263,12 +255,9 @@ class ClientWorkspace {
263
255
clientOptions ,
264
256
) ;
265
257
266
- const selector = this . config . multiProjectEnabled
267
- ? { language : 'rust' , scheme : 'file' , pattern }
268
- : { language : 'rust' } ;
258
+ const selector = { language : 'rust' , scheme : 'file' , pattern } ;
269
259
270
260
this . setupProgressCounter ( ) ;
271
- this . registerCommands ( context , this . config . multiProjectEnabled ) ;
272
261
this . disposables . push ( activateTaskProvider ( this . folder ) ) ;
273
262
this . disposables . push ( this . lc . start ( ) ) ;
274
263
this . disposables . push (
@@ -287,47 +276,19 @@ class ClientWorkspace {
287
276
}
288
277
289
278
this . disposables . forEach ( d => d . dispose ( ) ) ;
290
- commandsRegistered = false ;
291
279
}
292
280
293
- private registerCommands (
294
- context : ExtensionContext ,
295
- multiProjectEnabled : boolean ,
296
- ) {
297
- if ( ! this . lc ) {
298
- return ;
299
- }
300
- if ( multiProjectEnabled && commandsRegistered ) {
301
- return ;
302
- }
281
+ public async restart ( ) {
282
+ await this . stop ( ) ;
283
+ return this . start ( ) ;
284
+ }
303
285
304
- commandsRegistered = true ;
305
- const rustupUpdateDisposable = commands . registerCommand (
306
- 'rls.update' ,
307
- ( ) => {
308
- const ws =
309
- multiProjectEnabled && activeWorkspace ? activeWorkspace : this ;
310
- return rustupUpdate ( ws . config . rustupConfig ( ) ) ;
311
- } ,
312
- ) ;
313
- this . disposables . push ( rustupUpdateDisposable ) ;
314
-
315
- const restartServer = commands . registerCommand ( 'rls.restart' , async ( ) => {
316
- const ws =
317
- multiProjectEnabled && activeWorkspace ? activeWorkspace : this ;
318
- await ws . stop ( ) ;
319
- commandsRegistered = true ;
320
- return ws . start ( context ) ;
321
- } ) ;
322
- this . disposables . push ( restartServer ) ;
286
+ public runRlsCommand ( cmd : Execution ) {
287
+ return runRlsCommand ( this . folder , cmd ) ;
288
+ }
323
289
324
- this . disposables . push (
325
- commands . registerCommand ( 'rls.run' , ( cmd : Execution ) => {
326
- const ws =
327
- multiProjectEnabled && activeWorkspace ? activeWorkspace : this ;
328
- runRlsCommand ( ws . folder , cmd ) ;
329
- } ) ,
330
- ) ;
290
+ public rustupUpdate ( ) {
291
+ return rustupUpdate ( this . config . rustupConfig ( ) ) ;
331
292
}
332
293
333
294
private async setupProgressCounter ( ) {
@@ -499,6 +460,34 @@ async function warnOnMissingCargoToml() {
499
460
}
500
461
}
501
462
463
+ /**
464
+ * Tracks the most current VSCode workspace as opened by the user. Used by the
465
+ * commands to know in which workspace these should be executed.
466
+ */
467
+ let activeWorkspace : ClientWorkspace | null ;
468
+
469
+ /**
470
+ * Registers the VSCode [commands] used by the extension.
471
+ *
472
+ * [commands]: https://code.visualstudio.com/api/extension-guides/command
473
+ */
474
+ function registerCommands ( ) : Disposable [ ] {
475
+ return [
476
+ commands . registerCommand (
477
+ 'rls.update' ,
478
+ ( ) => activeWorkspace && activeWorkspace . rustupUpdate ( ) ,
479
+ ) ,
480
+ commands . registerCommand (
481
+ 'rls.restart' ,
482
+ async ( ) => activeWorkspace && activeWorkspace . restart ( ) ,
483
+ ) ,
484
+ commands . registerCommand (
485
+ 'rls.run' ,
486
+ ( cmd : Execution ) => activeWorkspace && activeWorkspace . runRlsCommand ( cmd ) ,
487
+ ) ,
488
+ ] ;
489
+ }
490
+
502
491
/**
503
492
* Sets up additional language configuration that's impossible to do via a
504
493
* separate language-configuration.json file. See [1] for more information.
0 commit comments