Skip to content

Commit 4046598

Browse files
Merge branch 'topic/#1520' into 'master'
Add status bar displaying project status + commands See merge request eng/ide/ada_language_server!1956
2 parents c8a91f9 + fa19110 commit 4046598

File tree

2 files changed

+150
-1
lines changed

2 files changed

+150
-1
lines changed

integration/vscode/ada/src/ExtensionState.ts

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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...).

integration/vscode/ada/src/extension.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,23 @@ async function activateExtension(context: vscode.ExtensionContext) {
145145
adaExtState = new ExtensionState(context);
146146
context.subscriptions.push(adaExtState);
147147

148-
// Subscribe to the didChangeConfiguration event
148+
// Subscribe to the didChangeConfiguration event to react to changes
149+
// in settings
149150
context.subscriptions.push(
150151
vscode.workspace.onDidChangeConfiguration(adaExtState.configChanged),
151152
);
152153

154+
// Subscribe to the didChangeActiveTextEditor event to update the status bar
155+
// item's visibility
156+
context.subscriptions.push(
157+
vscode.window.onDidChangeActiveTextEditor(adaExtState.updateStatusBarVisibility),
158+
);
159+
160+
// Subscribe to the didChangeDiagnostics event to update the status bar item's content
161+
context.subscriptions.push(
162+
vscode.languages.onDidChangeDiagnostics(adaExtState.updateStatusBarItem),
163+
);
164+
153165
const alsMiddleware: Middleware = {
154166
executeCommand: alsCommandExecutor(adaExtState.adaClient),
155167
};

0 commit comments

Comments
 (0)