16
16
----------------------------------------------------------------------------*/
17
17
18
18
import * as vscode from 'vscode' ;
19
+ import commandExists = require( 'command-exists' ) ;
19
20
import { SymbolKind } from 'vscode' ;
20
21
21
22
/**
@@ -27,8 +28,8 @@ type ExtraArgCallback = () => Promise<string>;
27
28
* Tool description
28
29
*/
29
30
interface 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
32
33
extra : ExtraArgCallback | undefined ; // Dynamic argument callback if any
33
34
// Args and extra argument will be wrapped with getGnatArgs if this is set.
34
35
title : string ; // Title like 'Examine project'
@@ -94,73 +95,79 @@ const getGnatArgs = (args: string[]): string[] => {
94
95
*/
95
96
const knownTaskKinds : { [ id : string ] : TaskProperties } = {
96
97
examineProject : {
97
- tool : 'gnatprove' ,
98
- args : getGnatArgs ( [ '--mode=flow' ] ) ,
98
+ command : getGnatArgs ( [ 'gnatprove' , '--mode=flow' ] ) ,
99
99
extra : undefined ,
100
100
title : 'Examine project' ,
101
101
} ,
102
102
examineFile : {
103
- tool : 'gnatprove' ,
104
- args : getGnatArgs ( [ '--mode=flow' , '-u' , '${fileBasename}' ] ) ,
103
+ command : getGnatArgs ( [ 'gnatprove' , '--mode=flow' , '-u' , '${fileBasename}' ] ) ,
105
104
extra : undefined ,
106
105
title : 'Examine file' ,
107
106
} ,
108
107
examineSubprogram : {
109
- tool : 'gnatprove' ,
110
- args : [ '--mode=flow' ] ,
108
+ command : [ 'gnatprove' , '--mode=flow' ] ,
111
109
extra : limitSubp ,
112
110
title : 'Examine subprogram' ,
113
111
} ,
114
112
proveProject : {
115
- tool : 'gnatprove' ,
116
- args : getGnatArgs ( [ ] ) ,
113
+ command : getGnatArgs ( [ 'gnatprove' ] ) ,
117
114
extra : undefined ,
118
115
title : 'Prove project' ,
119
116
} ,
120
117
proveFile : {
121
- tool : 'gnatprove' ,
122
- args : getGnatArgs ( [ '-u' , '${fileBasename}' ] ) ,
118
+ command : getGnatArgs ( [ 'gnatprove' , '-u' , '${fileBasename}' ] ) ,
123
119
extra : undefined ,
124
120
title : 'Prove file' ,
125
121
} ,
126
122
proveSubprogram : {
127
- tool : 'gnatprove' ,
128
- args : [ ] ,
123
+ command : [ 'gnatprove' ] ,
129
124
extra : limitSubp ,
130
125
title : 'Prove subprogram' ,
131
126
} ,
132
127
proveRegion : {
133
- tool : 'gnatprove' ,
134
- args : [ '-u' , '${fileBasename}' ] ,
128
+ command : [ 'gnatprove' , '-u' , '${fileBasename}' ] ,
135
129
extra : limitRegion ,
136
130
title : 'Prove selected region' ,
137
131
} ,
138
132
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
+ ] ) ,
141
139
extra : undefined ,
142
140
title : 'Prove line' ,
143
141
} ,
144
142
buildProject : {
145
- tool : 'gprbuild' ,
146
- args : getGnatArgs ( [ ] ) ,
143
+ command : getGnatArgs ( [ 'gprbuild' ] ) ,
147
144
extra : undefined ,
148
145
title : 'Build current project' ,
149
146
} ,
150
147
checkFile : {
151
- tool : 'gprbuild' ,
152
- args : getGnatArgs ( [ '-q' , '-f' , '-c' , '-u' , '-gnatc' , '${fileBasename}' ] ) ,
148
+ command : getGnatArgs ( [ 'gprbuild' , '-q' , '-f' , '-c' , '-u' , '-gnatc' , '${fileBasename}' ] ) ,
153
149
extra : undefined ,
154
150
title : 'Check current file' ,
155
151
} ,
156
152
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
159
154
extra : undefined ,
160
155
title : 'Clean current project' ,
161
156
} ,
162
157
} ;
163
158
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
+
164
171
/**
165
172
* Task provider itself
166
173
*/
@@ -173,9 +180,12 @@ export default class GnatTaskProvider implements vscode.TaskProvider<vscode.Task
173
180
}
174
181
175
182
// 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 [ ] > {
177
184
if ( ! this . gnatTasks ) {
178
- this . gnatTasks = getTasks ( ) ;
185
+ return getTasks ( ) . then ( ( list ) => {
186
+ this . gnatTasks = list ;
187
+ return list ;
188
+ } ) ;
179
189
}
180
190
return this . gnatTasks ;
181
191
}
@@ -197,8 +207,25 @@ export default class GnatTaskProvider implements vscode.TaskProvider<vscode.Task
197
207
// We have a callback, evaluate it to get an extra argument and
198
208
// wrap all args with getGnatArgs
199
209
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 ) ) ;
202
229
return new vscode . Task (
203
230
definition ,
204
231
vscode . TaskScope . Workspace , // scope
@@ -208,16 +235,6 @@ export default class GnatTaskProvider implements vscode.TaskProvider<vscode.Task
208
235
'$ada' // problemMatchers
209
236
) ;
210
237
} ) ;
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
- ) ;
221
238
}
222
239
} else {
223
240
return task ;
@@ -228,25 +245,35 @@ export default class GnatTaskProvider implements vscode.TaskProvider<vscode.Task
228
245
/**
229
246
* Return all known tasks
230
247
*/
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 [ ] = [ ] ;
233
251
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
+ }
247
273
248
- return result ;
249
- } ;
274
+ return result ;
275
+ } ) ;
276
+ }
250
277
251
278
/**
252
279
* Return the DocumentSymbol associated to the subprogram enclosing the
0 commit comments