1616----------------------------------------------------------------------------*/
1717
1818import * as vscode from 'vscode' ;
19+ import commandExists = require( 'command-exists' ) ;
1920import { SymbolKind } from 'vscode' ;
2021
2122/**
@@ -27,8 +28,8 @@ type ExtraArgCallback = () => Promise<string>;
2728 * Tool description
2829 */
2930interface TaskProperties {
30- tool : string ; // Executable like gprbuild, gprclean, gnatprove, etc.
31- args : string [ ] ; // Static list of arguments
31+ command : string [ ] ; // Executable like gprbuild, gprclean, gnatprove,
32+ // etc. and static list of arguments
3233 extra : ExtraArgCallback | undefined ; // Dynamic argument callback if any
3334 // Args and extra argument will be wrapped with getGnatArgs if this is set.
3435 title : string ; // Title like 'Examine project'
@@ -94,73 +95,79 @@ const getGnatArgs = (args: string[]): string[] => {
9495 */
9596const knownTaskKinds : { [ id : string ] : TaskProperties } = {
9697 examineProject : {
97- tool : 'gnatprove' ,
98- args : getGnatArgs ( [ '--mode=flow' ] ) ,
98+ command : getGnatArgs ( [ 'gnatprove' , '--mode=flow' ] ) ,
9999 extra : undefined ,
100100 title : 'Examine project' ,
101101 } ,
102102 examineFile : {
103- tool : 'gnatprove' ,
104- args : getGnatArgs ( [ '--mode=flow' , '-u' , '${fileBasename}' ] ) ,
103+ command : getGnatArgs ( [ 'gnatprove' , '--mode=flow' , '-u' , '${fileBasename}' ] ) ,
105104 extra : undefined ,
106105 title : 'Examine file' ,
107106 } ,
108107 examineSubprogram : {
109- tool : 'gnatprove' ,
110- args : [ '--mode=flow' ] ,
108+ command : [ 'gnatprove' , '--mode=flow' ] ,
111109 extra : limitSubp ,
112110 title : 'Examine subprogram' ,
113111 } ,
114112 proveProject : {
115- tool : 'gnatprove' ,
116- args : getGnatArgs ( [ ] ) ,
113+ command : getGnatArgs ( [ 'gnatprove' ] ) ,
117114 extra : undefined ,
118115 title : 'Prove project' ,
119116 } ,
120117 proveFile : {
121- tool : 'gnatprove' ,
122- args : getGnatArgs ( [ '-u' , '${fileBasename}' ] ) ,
118+ command : getGnatArgs ( [ 'gnatprove' , '-u' , '${fileBasename}' ] ) ,
123119 extra : undefined ,
124120 title : 'Prove file' ,
125121 } ,
126122 proveSubprogram : {
127- tool : 'gnatprove' ,
128- args : [ ] ,
123+ command : [ 'gnatprove' ] ,
129124 extra : limitSubp ,
130125 title : 'Prove subprogram' ,
131126 } ,
132127 proveRegion : {
133- tool : 'gnatprove' ,
134- args : [ '-u' , '${fileBasename}' ] ,
128+ command : [ 'gnatprove' , '-u' , '${fileBasename}' ] ,
135129 extra : limitRegion ,
136130 title : 'Prove selected region' ,
137131 } ,
138132 proveLine : {
139- tool : 'gnatprove' ,
140- args : getGnatArgs ( [ '-u' , '${fileBasename}' , '--limit-line=${fileBasename}:${lineNumber}' ] ) ,
133+ command : getGnatArgs ( [
134+ 'gnatprove' ,
135+ '-u' ,
136+ '${fileBasename}' ,
137+ '--limit-line=${fileBasename}:${lineNumber}' ,
138+ ] ) ,
141139 extra : undefined ,
142140 title : 'Prove line' ,
143141 } ,
144142 buildProject : {
145- tool : 'gprbuild' ,
146- args : getGnatArgs ( [ ] ) ,
143+ command : getGnatArgs ( [ 'gprbuild' ] ) ,
147144 extra : undefined ,
148145 title : 'Build current project' ,
149146 } ,
150147 checkFile : {
151- tool : 'gprbuild' ,
152- args : getGnatArgs ( [ '-q' , '-f' , '-c' , '-u' , '-gnatc' , '${fileBasename}' ] ) ,
148+ command : getGnatArgs ( [ 'gprbuild' , '-q' , '-f' , '-c' , '-u' , '-gnatc' , '${fileBasename}' ] ) ,
153149 extra : undefined ,
154150 title : 'Check current file' ,
155151 } ,
156152 cleanProject : {
157- tool : 'gprclean' ,
158- args : commonArgs ( [ ] ) , // No -cargs -gnatef is accepted by gprclean
153+ command : commonArgs ( [ 'gprbuild' ] ) , // No -cargs -gnatef is accepted by gprclean
159154 extra : undefined ,
160155 title : 'Clean current project' ,
161156 } ,
162157} ;
163158
159+ // Alire `exec` command if we have `alr` installed and `alire.toml`
160+ async function alire ( ) : Promise < string [ ] > {
161+ return vscode . workspace . findFiles ( 'alire.toml' ) . then ( ( found ) =>
162+ found . length == 0
163+ ? [ ] // not alire.toml found, return no command
164+ : // if alire.toml found, search for `alr`
165+ commandExists ( 'alr' )
166+ . then ( ( ) => [ 'alr' , 'exec' , '--' ] )
167+ . catch ( ( ) => [ ] )
168+ ) ;
169+ }
170+
164171/**
165172 * Task provider itself
166173 */
@@ -173,9 +180,12 @@ export default class GnatTaskProvider implements vscode.TaskProvider<vscode.Task
173180 }
174181
175182 // eslint-disable-next-line @typescript-eslint/no-unused-vars
176- provideTasks ( _token : vscode . CancellationToken ) : vscode . Task [ ] {
183+ provideTasks ( _token : vscode . CancellationToken ) : vscode . ProviderResult < vscode . Task [ ] > {
177184 if ( ! this . gnatTasks ) {
178- this . gnatTasks = getTasks ( ) ;
185+ return getTasks ( ) . then ( ( list ) => {
186+ this . gnatTasks = list ;
187+ return list ;
188+ } ) ;
179189 }
180190 return this . gnatTasks ;
181191 }
@@ -197,8 +207,25 @@ export default class GnatTaskProvider implements vscode.TaskProvider<vscode.Task
197207 // We have a callback, evaluate it to get an extra argument and
198208 // wrap all args with getGnatArgs
199209 return item . extra ( ) . then ( ( extra ) => {
200- const args = getGnatArgs ( item . args . concat ( extraArgs , extra ? [ extra ] : [ ] ) ) ;
201- const shell = new vscode . ShellExecution ( item . tool , args ) ;
210+ return alire ( ) . then ( ( alr ) => {
211+ const cmd = getGnatArgs (
212+ alr . concat ( item . command , extraArgs , extra ? [ extra ] : [ ] )
213+ ) ;
214+ const shell = new vscode . ShellExecution ( cmd [ 0 ] , cmd . slice ( 1 ) ) ;
215+ return new vscode . Task (
216+ definition ,
217+ vscode . TaskScope . Workspace , // scope
218+ task . name ,
219+ 'ada' , // source
220+ shell ,
221+ '$ada' // problemMatchers
222+ ) ;
223+ } ) ;
224+ } ) ;
225+ } else {
226+ return alire ( ) . then ( ( alr ) => {
227+ const cmd = alr . concat ( item . command , extraArgs ) ;
228+ const shell = new vscode . ShellExecution ( cmd [ 0 ] , cmd . slice ( 1 ) ) ;
202229 return new vscode . Task (
203230 definition ,
204231 vscode . TaskScope . Workspace , // scope
@@ -208,16 +235,6 @@ export default class GnatTaskProvider implements vscode.TaskProvider<vscode.Task
208235 '$ada' // problemMatchers
209236 ) ;
210237 } ) ;
211- } else {
212- const shell = new vscode . ShellExecution ( item . tool , item . args . concat ( extraArgs ) ) ;
213- return new vscode . Task (
214- definition ,
215- vscode . TaskScope . Workspace , // scope
216- task . name ,
217- 'ada' , // source
218- shell ,
219- '$ada' // problemMatchers
220- ) ;
221238 }
222239 } else {
223240 return task ;
@@ -228,25 +245,35 @@ export default class GnatTaskProvider implements vscode.TaskProvider<vscode.Task
228245/**
229246 * Return all known tasks
230247 */
231- const getTasks = ( ) : vscode . Task [ ] => {
232- const result : vscode . Task [ ] = [ ] ;
248+ async function getTasks ( ) : Promise < vscode . Task [ ] > {
249+ return alire ( ) . then ( ( alr ) => {
250+ const result : vscode . Task [ ] = [ ] ;
233251
234- for ( const taskKind in knownTaskKinds ) {
235- const item : TaskProperties = knownTaskKinds [ taskKind ] ;
236- const title : string = item . title ;
237- const kind = {
238- type : GnatTaskProvider . gnatType ,
239- projectFile : '${config:ada.projectFile}' ,
240- taskKind : taskKind ,
241- } ;
242- const shell = new vscode . ShellExecution ( item . tool , item . args ) ;
243- const task = new vscode . Task ( kind , vscode . TaskScope . Workspace , title , 'ada' , shell , '$ada' ) ;
244- task . group = vscode . TaskGroup . Build ;
245- result . push ( task ) ;
246- }
252+ for ( const taskKind in knownTaskKinds ) {
253+ const item : TaskProperties = knownTaskKinds [ taskKind ] ;
254+ const title : string = item . title ;
255+ const kind = {
256+ type : GnatTaskProvider . gnatType ,
257+ projectFile : '${config:ada.projectFile}' ,
258+ taskKind : taskKind ,
259+ } ;
260+ const cmd = alr . concat ( item . command ) ;
261+ const shell = new vscode . ShellExecution ( cmd [ 0 ] , cmd . slice ( 1 ) ) ;
262+ const task = new vscode . Task (
263+ kind ,
264+ vscode . TaskScope . Workspace ,
265+ title ,
266+ 'ada' ,
267+ shell ,
268+ '$ada'
269+ ) ;
270+ task . group = vscode . TaskGroup . Build ;
271+ result . push ( task ) ;
272+ }
247273
248- return result ;
249- } ;
274+ return result ;
275+ } ) ;
276+ }
250277
251278/**
252279 * Return the DocumentSymbol associated to the subprogram enclosing the
0 commit comments