@@ -30,6 +30,7 @@ import { checkForRls, ensureToolchain, rustupUpdate } from './rustup';
30
30
import { startSpinner , stopSpinner } from './spinner' ;
31
31
import { activateTaskProvider , Execution , runRlsCommand } from './tasks' ;
32
32
import { withWsl } from './utils/child_process' ;
33
+ import { Observable , Observer } from './utils/observable' ;
33
34
import { nearestParentWorkspace } from './utils/workspace' ;
34
35
import { uriWindowsToWsl , uriWslToWindows } from './utils/wslpath' ;
35
36
@@ -102,15 +103,32 @@ function whenOpeningTextDocument(document: TextDocument) {
102
103
clientWorkspaceForUri ( document . uri , { startIfMissing : true } ) ;
103
104
}
104
105
106
+ /** Tracks dynamically updated progress for the active client workspace for UI purposes. */
107
+ const progressObserver : Observer < { message : string } | null > = new Observer ( ) ;
108
+
105
109
function onDidChangeActiveTextEditor ( editor : TextEditor | undefined ) {
106
110
if ( ! editor ) {
107
111
return ;
108
112
}
109
113
110
114
const workspace = clientWorkspaceForUri ( editor . document . uri ) ;
111
- if ( workspace ) {
112
- activeWorkspace = workspace ;
115
+ if ( ! workspace ) {
116
+ return ;
113
117
}
118
+
119
+ activeWorkspace = workspace ;
120
+
121
+ const updateProgress = ( progress : { message : string } | null ) => {
122
+ if ( progress ) {
123
+ startSpinner ( `[${ workspace . folder . name } ] ${ progress . message } ` ) ;
124
+ } else {
125
+ stopSpinner ( `[${ workspace . folder . name } ]` ) ;
126
+ }
127
+ } ;
128
+
129
+ progressObserver . bind ( activeWorkspace . progress , updateProgress ) ;
130
+ // Update UI ourselves immediately and don't wait for value update callbacks
131
+ updateProgress ( activeWorkspace . progress . value ) ;
114
132
}
115
133
116
134
function whenChangingWorkspaceFolders ( e : WorkspaceFoldersChangeEvent ) {
@@ -159,21 +177,26 @@ function clientWorkspaceForUri(
159
177
// (VSCode workspace, not Cargo workspace). This class contains all the per-client
160
178
// and per-workspace stuff.
161
179
class ClientWorkspace {
180
+ public readonly folder : WorkspaceFolder ;
162
181
// FIXME(#233): Don't only rely on lazily initializing it once on startup,
163
182
// handle possible `rust-client.*` value changes while extension is running
164
183
private readonly config : RLSConfiguration ;
165
184
private lc : LanguageClient | null = null ;
166
- private readonly folder : WorkspaceFolder ;
167
185
private disposables : Disposable [ ] ;
186
+ private _progress : Observable < { message : string } | null > ;
187
+ get progress ( ) {
188
+ return this . _progress ;
189
+ }
168
190
169
191
constructor ( folder : WorkspaceFolder ) {
170
192
this . config = RLSConfiguration . loadFromWorkspace ( folder . uri . fsPath ) ;
171
193
this . folder = folder ;
172
194
this . disposables = [ ] ;
195
+ this . _progress = new Observable < { message : string } | null > ( null ) ;
173
196
}
174
197
175
198
public async start ( ) {
176
- startSpinner ( 'Starting' ) ;
199
+ this . _progress . value = { message : 'Starting' } ;
177
200
178
201
const serverOptions : ServerOptions = async ( ) => {
179
202
await this . autoUpdate ( ) ;
@@ -274,7 +297,6 @@ class ClientWorkspace {
274
297
275
298
const runningProgress : Set < string > = new Set ( ) ;
276
299
await this . lc . onReady ( ) ;
277
- stopSpinner ( ) ;
278
300
279
301
this . lc . onNotification (
280
302
new NotificationType < ProgressParams , void > ( 'window/progress' ) ,
@@ -293,9 +315,9 @@ class ClientWorkspace {
293
315
} else if ( progress . title ) {
294
316
status = `[${ progress . title . toLowerCase ( ) } ]` ;
295
317
}
296
- startSpinner ( status ) ;
318
+ this . _progress . value = { message : status } ;
297
319
} else {
298
- stopSpinner ( ) ;
320
+ this . _progress . value = null ;
299
321
}
300
322
} ,
301
323
) ;
0 commit comments