Skip to content

Commit 289528f

Browse files
author
mergerepo
committed
Merge remote branch 'origin/master' into edge
(no-precommit-check no-tn-check)
2 parents a9fe83f + d274a05 commit 289528f

File tree

4 files changed

+93
-13
lines changed

4 files changed

+93
-13
lines changed

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,23 @@ specification. See [corresponding document](doc/README.md).
113113

114114
## How to use the VScode extension
115115

116+
### Current limitations and differences compared to GNAT Studio
117+
118+
The VSCode extension has a few limitations and some differences compared to [GNAT Studio](https://github.com/AdaCore/gnatstudio):
119+
120+
* **Indentation/formatting**: it does not support automatic indentation when adding a newline and range/document
121+
formatting might no succeed on incomplete/illegal code.
122+
123+
* **Toooling support**: we currently provide minimal support for *SPARK* (see *Prove/Examine* tasks in the [Auto-detected tasks](#auto-detected-tasks) section), but there is no support for tools such as *CodePeer*, *GNATcheck*, *GNATtest* or *GNATcoverage*.
124+
125+
* **Project support**: there is no `Scenario` view: users should configure scenarios via the *ada.scenarioVariables* setting (see the settings list available [here](doc/refactoring_tools.md)). You can execute the *Developper: Reload Window* command to reload your project after saving the new scenario values (use the *Ctrl+P* shortcut to invoke the **Command Palette**, allowing you to execute commands).
126+
127+
Source directories from imported projects should be added in a [workspace file](https://code.visualstudio.com/docs/editor/workspaces#_multiroot-workspaces). If you already have a workspace file, the extension will propose you to automatically add all the source directories coming from imported projects to your workspace automatically at startup.
128+
129+
* **Debugging**: some manual work is needed in order to debug Ada code. In particular, you will need a `launch.json` file that describes your debugging configuration. All the steps needed for debugging are described [here](https://github.com/AdaCore/ada_language_server/wiki/Getting-Started#debug-hello_worldadb).
130+
131+
132+
116133
### Getting started
117134

118135
[Tutorial: Using Ada in VS Code](https://github.com/AdaCore/ada_language_server/wiki/Getting-Started).

integration/vscode/ada/package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,10 @@
418418
{
419419
"command": "ada.otherFile",
420420
"title": "Go to other Ada file"
421+
},
422+
{
423+
"command": "ada.subprogramBox",
424+
"title": "Add subprogram box"
421425
}
422426
],
423427
"keybindings": [
@@ -461,4 +465,4 @@
461465
"vscode-languageclient": "7.0.0",
462466
"ws": "8.5.0"
463467
}
464-
}
468+
}

integration/vscode/ada/src/extension.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import * as process from 'process';
2727
import GPRTaskProvider from './gprTaskProvider';
2828
import cleanTaskProvider from './cleanTaskProvider';
2929
import gnatproveTaskProvider from './gnatproveTaskProvider';
30+
import { getSubprogramSymbol } from './gnatproveTaskProvider';
3031
import { alsCommandExecutor } from './alsExecuteCommand';
3132
import { ALSClientFeatures } from './alsClientFeatures';
3233
import { string } from 'fp-ts';
@@ -41,6 +42,47 @@ let alsTaskProvider: vscode.Disposable[] = [
4142
),
4243
];
4344

45+
/**
46+
* Add a subprogram box above the subprogram enclosing the cursor's position, if any.
47+
*
48+
* @example:
49+
*
50+
* -------
51+
* - Foo -
52+
* -------
53+
*
54+
* procedure Foo is
55+
*/
56+
function addSupbrogramBox() {
57+
const activeEditor = vscode.window.activeTextEditor;
58+
59+
getSubprogramSymbol(activeEditor)
60+
.then(symbol => {
61+
if (symbol !== null) {
62+
const name: string = symbol.name ?? ""
63+
const insertPos = new vscode.Position(symbol.range.start.line, 0);
64+
const indentationRange = new vscode.Range(insertPos, symbol.range.start)
65+
const indentation: string = activeEditor?.document.getText(indentationRange) ?? ""
66+
const eol: string = activeEditor?.document.eol == vscode.EndOfLine.CRLF ? "\r\n" : "\n";
67+
68+
// Generate the subprogram box after retrieving the indentation of the line of
69+
// the subprogram's body declaration.
70+
let text: string = indentation + "---" + '-'.repeat(name.length) + "---" + eol
71+
+ indentation + "-- " + name + " --" + eol
72+
+ indentation + "---" + '-'.repeat(name.length) + "---" + eol
73+
+ eol;
74+
75+
activeEditor?.document.eol.toString
76+
if (activeEditor) {
77+
78+
activeEditor.edit(editBuilder => {
79+
editBuilder.insert(insertPos, text);
80+
});
81+
}
82+
}
83+
})
84+
}
85+
4486
export function activate(context: vscode.ExtensionContext): void {
4587
function createClient(id: string, name: string, extra: string[], pattern: string) {
4688
let serverModule = context.asAbsolutePath(process.platform + '/ada_language_server');
@@ -125,6 +167,7 @@ export function activate(context: vscode.ExtensionContext): void {
125167

126168
context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(configChanged));
127169
context.subscriptions.push(vscode.commands.registerCommand('ada.otherFile', otherFileHandler));
170+
context.subscriptions.push(vscode.commands.registerCommand('ada.subprogramBox', addSupbrogramBox));
128171

129172
// Check if we need to add some source directories to the workspace (e.g: when imported projects'
130173
// source directories are not placed under the root project's directory).

integration/vscode/ada/src/gnatproveTaskProvider.ts

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515
-- of the license. --
1616
----------------------------------------------------------------------------*/
1717

18+
import { none } from 'fp-ts/lib/Option';
1819
import * as vscode from 'vscode';
1920
import { SymbolKind } from 'vscode';
21+
import { integer } from 'vscode-languageclient';
2022

2123
enum taskKinds {
2224
examineProject, // Examine the project
@@ -63,13 +65,19 @@ export default class gnatproveTaskProvider implements vscode.TaskProvider<vscode
6365
else if (definition.taskKind == taskKinds.examineSubprogram
6466
|| definition.taskKind == taskKinds.proveSubprogram)
6567
{
66-
return getSubprogram(vscode.window.activeTextEditor)
67-
.then(subprogram =>
68+
return getSubprogramSymbol(vscode.window.activeTextEditor)
69+
.then(Symbol =>
6870
{
69-
let args = (definition.taskKind == taskKinds.examineSubprogram) ? ['--mode=flow'] : [];
70-
args = getGnatproveArgs(args.concat(['-u', '${fileBasename}', '--limit-subp=${fileBasename}:' + subprogram]));
71-
const shell = new vscode.ShellExecution('gnatprove', args);
72-
return new vscode.Task(definition, vscode.TaskScope.Workspace, task.name, 'ada', shell, '$ada');
71+
if (Symbol) {
72+
const subprogram_line: string = (Symbol.range.start.line + 1).toString()
73+
let args = (definition.taskKind == taskKinds.examineSubprogram) ? ['--mode=flow'] : [];
74+
args = getGnatproveArgs(args.concat(['-u', '${fileBasename}', '--limit-subp=${fileBasename}:' + subprogram_line]));
75+
const shell = new vscode.ShellExecution('gnatprove', args);
76+
return new vscode.Task(definition, vscode.TaskScope.Workspace, task.name, 'ada', shell, '$ada');
77+
}
78+
else {
79+
return task;
80+
}
7381
});
7482
}
7583
else {
@@ -161,8 +169,16 @@ const getTasks = (): vscode.Task[] => {
161169
return result;
162170
};
163171

164-
const getSubprogram = async (editor: vscode.TextEditor | undefined): Promise<string> => {
165-
let subprogramLine = 0;
172+
/**
173+
* Return the DocumentSymbol associated to the subprogram enclosing the
174+
* the given editor's cursor position, if any.
175+
* @param {vscode.TextEditor | undefined} editor - The editor in which we want
176+
* to find the suprogram's body enclosing the cursor's position.
177+
* @return {vscode.DocumentSymbol | null} Return the symbol corresponding to the
178+
* enclosing subprogram or null if not found.
179+
*/
180+
export const getSubprogramSymbol = async (editor: vscode.TextEditor | undefined): Promise<vscode.DocumentSymbol|null> => {
181+
let subprogramLine = 0;
166182
if (editor) {
167183
const line = editor.selection.active.line;
168184

@@ -190,12 +206,12 @@ const getSubprogram = async (editor: vscode.TextEditor | undefined): Promise<str
190206
let scopeSymbols = subprograms.filter(sym => line >= sym.range.start.line && line <= sym.range.end.line);
191207
if (scopeSymbols.length > 0) {
192208
scopeSymbols.sort((a,b) => (a.range.end.line - a.range.start.line) - (b.range.end.line - b.range.start.line));
193-
subprogramLine = scopeSymbols[0].range.start.line;
209+
return scopeSymbols[0];
194210
};
195211
};
196-
// Line numbers start at 0 in VS Code, and at 1 in GNAT
197-
return (subprogramLine + 1).toString();
198-
};
212+
213+
return null;
214+
}
199215

200216
const getSelectedRegion = (editor: vscode.TextEditor | undefined): string => {
201217
if (editor) {

0 commit comments

Comments
 (0)