@@ -57,6 +57,7 @@ export class ExtensionState {
5757 public readonly codelensProvider = new AdaCodeLensProvider ( ) ;
5858 public readonly testController : vscode . TestController ;
5959 public readonly testData : Map < vscode . TestItem , object > = new Map ( ) ;
60+ public readonly statusBar : vscode . StatusBarItem ;
6061
6162 /**
6263 * The following fields are caches for ALS requests or costly properties.
@@ -107,6 +108,8 @@ export class ExtensionState {
107108 this . initialDebugConfigProvider = result . providerInitial ;
108109 this . dynamicDebugConfigProvider = result . providerDynamic ;
109110 this . testController = initializeTesting ( context ) ;
111+ this . statusBar = vscode . window . createStatusBarItem ( vscode . StatusBarAlignment . Left ) ;
112+ this . context . subscriptions . push ( this . statusBar ) ;
110113 }
111114
112115 public start = async ( ) => {
@@ -115,6 +118,7 @@ export class ExtensionState {
115118 this . context . subscriptions . push (
116119 vscode . languages . registerCodeLensProvider ( 'ada' , this . codelensProvider ) ,
117120 ) ;
121+ this . updateStatusBarVisibility ( undefined ) ;
118122 } ;
119123
120124 public dispose = ( ) => {
@@ -147,6 +151,139 @@ export class ExtensionState {
147151 ] ;
148152 } ;
149153
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+
150287 /**
151288 * Unregister all the task disposables needed by the extension (e.g: task providers,
152289 * listeners...).
0 commit comments