@@ -57,6 +57,7 @@ export class ExtensionState {
57
57
public readonly codelensProvider = new AdaCodeLensProvider ( ) ;
58
58
public readonly testController : vscode . TestController ;
59
59
public readonly testData : Map < vscode . TestItem , object > = new Map ( ) ;
60
+ public readonly statusBar : vscode . StatusBarItem ;
60
61
61
62
/**
62
63
* The following fields are caches for ALS requests or costly properties.
@@ -107,6 +108,8 @@ export class ExtensionState {
107
108
this . initialDebugConfigProvider = result . providerInitial ;
108
109
this . dynamicDebugConfigProvider = result . providerDynamic ;
109
110
this . testController = initializeTesting ( context ) ;
111
+ this . statusBar = vscode . window . createStatusBarItem ( vscode . StatusBarAlignment . Left ) ;
112
+ this . context . subscriptions . push ( this . statusBar ) ;
110
113
}
111
114
112
115
public start = async ( ) => {
@@ -115,6 +118,7 @@ export class ExtensionState {
115
118
this . context . subscriptions . push (
116
119
vscode . languages . registerCodeLensProvider ( 'ada' , this . codelensProvider ) ,
117
120
) ;
121
+ this . updateStatusBarVisibility ( undefined ) ;
118
122
} ;
119
123
120
124
public dispose = ( ) => {
@@ -147,6 +151,139 @@ export class ExtensionState {
147
151
] ;
148
152
} ;
149
153
154
+ /**
155
+ * Update the status bar item's visibility according to the current context.
156
+ */
157
+ public updateStatusBarVisibility = ( editor : vscode . TextEditor | undefined ) => {
158
+ const activeEditor = editor ?? vscode . window . activeTextEditor ;
159
+
160
+ // Show the status bar if the active editor is on an Ada or a GPR source, or
161
+ // if it's the Output view that is focused (i.e: when the active editor's
162
+ // document scheme is set to 'output') and showing Ada & SPARK extension's logs.
163
+ if (
164
+ activeEditor &&
165
+ ( ( activeEditor . document . uri . scheme == 'output' &&
166
+ activeEditor . document . fileName . includes ( 'AdaCore' ) ) ||
167
+ [ 'ada' , 'gpr' ] . includes ( activeEditor . document . languageId ) )
168
+ ) {
169
+ this . statusBar . show ( ) ;
170
+ } else {
171
+ this . statusBar . hide ( ) ;
172
+ }
173
+ } ;
174
+
175
+ /**
176
+ * Update the status bar item's content according to currently displayed
177
+ * diagnostics.
178
+ */
179
+ public updateStatusBarItem = ( ) => {
180
+ // Use markdown for the status bar item tiooltip. This allows to have
181
+ // hyperlinks that run actual commands.
182
+ this . statusBar . tooltip = new vscode . MarkdownString ( '' , true ) ;
183
+ this . statusBar . tooltip . isTrusted = true ;
184
+
185
+ // Show the Problems view by default when clicking on the status
186
+ // bar item.
187
+ this . statusBar . command = 'workbench.panel.markers.view.focus' ;
188
+ let alireProjectLoaded = false ;
189
+
190
+ // Monitor diagnostics related to project-loading in general, including
191
+ // potential issues reported by Alire.
192
+ const PROJECT_DIAGS_SOURCE = 'ada.project' ;
193
+ const ALIRE_DIAGS_SOURCE = 'ada.alire' ;
194
+ const diagnosticSources = [ PROJECT_DIAGS_SOURCE , ALIRE_DIAGS_SOURCE ] ;
195
+
196
+ // Gather all the diagnostics from the interesting ALS diagnostics' sources.
197
+ // For the status bar we are interested only in project-related diagnostics.
198
+ const alsDiagnostics : vscode . Diagnostic [ ] = vscode . languages
199
+ . getDiagnostics ( )
200
+ . flatMap ( ( [ , diagnostics ] ) => diagnostics )
201
+ . filter ( ( diag ) => diagnosticSources . includes ( diag . source ?? '' ) ) ;
202
+
203
+ // Update the status bar according to the ALS project-related diagnostics
204
+ if ( alsDiagnostics . length > 0 ) {
205
+ // Get the highest severity of the currently displayed project-diagnostics, to
206
+ // update the status bar's colors accordingly.
207
+ const statusBarSeverity : vscode . DiagnosticSeverity = alsDiagnostics
208
+ . map ( ( a ) => a . severity )
209
+ . reduce ( ( a , b ) => ( a < b ? a : b ) ) ;
210
+ this . statusBar . text = 'Ada & SPARK' ;
211
+
212
+ switch ( statusBarSeverity ) {
213
+ case vscode . DiagnosticSeverity . Error :
214
+ this . statusBar . tooltip . appendMarkdown (
215
+ 'Project loading has issued errors, see the [Problems]' +
216
+ '(command:workbench.panel.markers.view.focus) view' +
217
+ ' for more information.' ,
218
+ ) ;
219
+ this . statusBar . backgroundColor = new vscode . ThemeColor (
220
+ 'statusBarItem.errorBackground' ,
221
+ ) ;
222
+ this . statusBar . color = new vscode . ThemeColor ( 'statusBarItem.errorForeground' ) ;
223
+ break ;
224
+
225
+ case vscode . DiagnosticSeverity . Warning :
226
+ this . statusBar . tooltip . appendMarkdown (
227
+ 'Project loading has issued warnings, see the [Problems]' +
228
+ '(command:workbench.panel.markers.view.focus) view' +
229
+ ' for more information.' ,
230
+ ) ;
231
+ this . statusBar . backgroundColor = new vscode . ThemeColor (
232
+ 'statusBarItem.warningBackground' ,
233
+ ) ;
234
+ this . statusBar . color = new vscode . ThemeColor ( 'statusBarItem.warningForeground' ) ;
235
+ break ;
236
+
237
+ default :
238
+ this . statusBar . backgroundColor = undefined ;
239
+ this . statusBar . color = undefined ;
240
+
241
+ // Check if we have successfully loaded the project through Alire
242
+ // and adapt the status bar item's text contents if it's the case, to
243
+ // mention that Alire was used for project-loading.
244
+ alireProjectLoaded = alsDiagnostics . some (
245
+ ( diagnostic ) =>
246
+ diagnostic . source == PROJECT_DIAGS_SOURCE &&
247
+ diagnostic . message . includes ( 'Alire' ) ,
248
+ ) ;
249
+
250
+ if ( alireProjectLoaded ) {
251
+ this . statusBar . text += ' (Alire)' ;
252
+ this . statusBar . tooltip . appendMarkdown (
253
+ 'Project was loaded successfully through Alire' ,
254
+ ) ;
255
+ } else {
256
+ this . statusBar . tooltip . appendMarkdown ( 'Project was loaded successfully.' ) ;
257
+ }
258
+ }
259
+ } else {
260
+ // We don't have any project-related diagnostics, just clear any color/background color
261
+ // of the status bar.
262
+ this . statusBar . tooltip . appendMarkdown ( 'Project was loaded successfully.' ) ;
263
+ this . statusBar . backgroundColor = undefined ;
264
+ this . statusBar . color = undefined ;
265
+ }
266
+
267
+ if ( this . statusBar . tooltip . value ) {
268
+ this . statusBar . tooltip . appendMarkdown ( '\n\n---\n\n' ) ;
269
+ }
270
+ this . statusBar . tooltip . appendMarkdown (
271
+ `[$(terminal) Open Extension Logs](command:ada.showExtensionOutput
272
+ "Show Ada Extension Output")
273
+
274
+ [$(terminal) Open Logs for Ada & SPARK](command:ada.showAdaLSOutput
275
+ "Show Ada Language Server for Ada & SPARK Output")
276
+
277
+ [$(terminal) Open Logs for GPR](command:ada.showGprLSOutput
278
+ "Show Ada Language Server for GPR Output")
279
+
280
+ [$(refresh) Reload Project](command:als-reload-project "Reload Project")
281
+
282
+ [$(debug-restart) Restart Language Servers](command:ada.restartLanguageServers
283
+ "Restart Ada Language Servers")` ,
284
+ ) ;
285
+ } ;
286
+
150
287
/**
151
288
* Unregister all the task disposables needed by the extension (e.g: task providers,
152
289
* listeners...).
0 commit comments