@@ -2,6 +2,8 @@ import * as path from 'path';
2
2
import * as vscode from 'vscode' ;
3
3
import { ContextClients } from './clients' ;
4
4
import { getExecutables , getMains } from './helpers' ;
5
+ import assert from 'assert' ;
6
+ import { exec } from 'child_process' ;
5
7
6
8
/**
7
9
* Ada Configuration for a debug session
@@ -53,7 +55,7 @@ export function initializeDebugging(ctx: vscode.ExtensionContext, clients: Conte
53
55
/**
54
56
* Initialize a debug configuration based on 'cppdbg' for the given executable
55
57
* if specified. Otherwise the program field includes
56
- * ${command:ada.askForProgram } to prompt the User for an executable to debug.
58
+ * ${command:ada.getOrAskForProgram } to prompt the User for an executable to debug.
57
59
*
58
60
* @param program - the executable to debug (optional)
59
61
* @returns an AdaConfig
@@ -67,7 +69,7 @@ function initializeConfig(program?: string): AdaConfig {
67
69
request : 'launch' ,
68
70
targetArchitecture : process . arch ,
69
71
cwd : '${workspaceFolder}' ,
70
- program : '${workspaceFolder}/${command:ada.askForProgram }' ,
72
+ program : '${workspaceFolder}/${command:ada.getOrAskForProgram }' ,
71
73
stopAtEntry : false ,
72
74
externalConsole : false ,
73
75
args : [ ] ,
@@ -108,20 +110,33 @@ export class AdaDebugConfigProvider implements vscode.DebugConfigurationProvider
108
110
109
111
if ( folder != undefined ) {
110
112
// Offer a list of known Mains from the project
113
+ const mains = await getMains ( this . clients . adaClient ) ;
111
114
const execs = await getExecutables ( this . clients . adaClient ) ;
112
- const quickpick = execs . map ( ( e ) => ( {
113
- label : vscode . workspace . asRelativePath ( e ) ,
114
- description : 'Generate the associated configuration' ,
115
- } ) ) ;
115
+ assert (
116
+ execs . length == mains . length ,
117
+ `The ALS returned mains.length = ${ mains . length } and ` +
118
+ `execs.length = ${ execs . length } ` +
119
+ `when they should be equal`
120
+ ) ;
121
+ const quickpick = [ ] ;
122
+ for ( let i = 0 ; i < mains . length ; i ++ ) {
123
+ const exec = execs [ i ] ;
124
+ const main = mains [ i ] ;
125
+ quickpick . push ( {
126
+ label : vscode . workspace . asRelativePath ( main ) ,
127
+ description : 'Generate the associated launch configuration' ,
128
+ execPath : vscode . workspace . asRelativePath ( exec ) ,
129
+ } ) ;
130
+ }
116
131
const selectedProgram = await vscode . window . showQuickPick ( quickpick , {
117
- placeHolder : 'Select a program to debug ' ,
132
+ placeHolder : 'Select a main to create a launch configuration ' ,
118
133
} ) ;
119
134
if ( selectedProgram ) {
120
135
// The cppdbg debug configuration exepects the executable to be
121
136
// a full path rather than a path relative to the specified
122
137
// cwd. That is why we include ${workspaceFolder}.
123
138
const configuration = initializeConfig (
124
- `\${workspaceFolder}/${ selectedProgram . label } `
139
+ `\${workspaceFolder}/${ selectedProgram . execPath } `
125
140
) ;
126
141
configs . push ( configuration ) ;
127
142
} else {
@@ -156,75 +171,73 @@ export class AdaDebugConfigProvider implements vscode.DebugConfigurationProvider
156
171
return debugConfiguration ;
157
172
}
158
173
159
- // We are operating without a launch.json. So we try to determine the
160
- // program to debug dynamically. If the current editor matches one of
161
- // the Mains of the project, then debug the corresponding executable.
162
- const file = vscode . window . activeTextEditor ?. document . uri . path ;
163
- if ( file != undefined ) {
164
- const mains = await getMains ( this . clients . adaClient ) ;
165
- const execs = await getExecutables ( this . clients . adaClient ) ;
166
- for ( let i = 0 ; i < mains . length ; i ++ ) {
167
- if ( file == mains [ i ] ) {
168
- const config = initializeConfig ( execs [ i ] ) ;
169
- return config ;
170
- }
171
- }
172
- }
174
+ const exec = await this . getOrAskForProgram ( ) ;
173
175
174
- // There is no current file or it matches no known Main of the project,
175
- // so we offer all Main in a QuickPicker for the user to choose from.
176
- const quickpick = execs . map ( ( e ) => ( {
177
- label : vscode . workspace . asRelativePath ( e ) ,
178
- description : 'Run & Debug' ,
179
- fullPath : e ,
180
- } ) ) ;
181
- const selectedProgram = await vscode . window . showQuickPick ( quickpick , {
182
- placeHolder : 'Select an executable to debug' ,
183
- } ) ;
184
- if ( selectedProgram ) {
185
- // This is an in-memory configuration that will not be stored. It's
186
- // okay to use the full path directly instead of using
187
- // ${workspaceFolder}.
188
- const configuration = initializeConfig ( selectedProgram . fullPath ) ;
189
- return configuration ;
176
+ if ( exec ) {
177
+ return initializeConfig ( `\${workspaceFolder}/${ exec } ` ) ;
190
178
}
191
179
192
180
return undefined ;
193
181
}
194
182
195
183
/**
196
- * Consults the project for a list of Mains. If only one is defined, it is
197
- * returned immediately. If multiple ones are defines, a QuickPicker is
198
- * given to the User to choose and executable to debug or to specify in a
199
- * debug configuration.
184
+ * Get an executable based on the project and the current open file.
185
+ *
186
+ * If the project only defines one main, it is returned immediately.
187
+ *
188
+ * If the project defines multiple mains, and if the current open file
189
+ * matches one of the mains, the corresponding executable is returned.
200
190
*
201
- * @returns the path of the executable to debug relative to the workspace
191
+ * Otherwise, the list of mains is offered to the user as a QuickPicker to
192
+ * choose a main file. The executable corresponding to the selected main
193
+ * file is returned.
194
+ *
195
+ * Note that paths are returned relative to the workspace.
196
+ *
197
+ * @returns the path of the executable to debug *relative to the workspace*,
198
+ * or *undefined* if no selection was made.
202
199
*/
203
- async askForProgram ( ) : Promise < string | undefined > {
204
- const file = vscode . window . activeTextEditor ?. document . uri . path ;
200
+ async getOrAskForProgram ( ) : Promise < string | undefined > {
205
201
const mains = await getMains ( this . clients . adaClient ) ;
206
202
const execs = await getExecutables ( this . clients . adaClient ) ;
207
203
204
+ assert (
205
+ execs . length == mains . length ,
206
+ `The ALS returned mains.length = ${ mains . length } and ` +
207
+ `execs.length = ${ execs . length } ` +
208
+ `when they should be equal`
209
+ ) ;
210
+
208
211
if ( execs . length == 1 ) return vscode . workspace . asRelativePath ( execs [ 0 ] ) ;
209
212
213
+ // Check if the current file matches one of the mains of the project. If
214
+ // so, use it.
215
+ const file = vscode . window . activeTextEditor ?. document . uri . path ;
210
216
if ( file != undefined ) {
211
217
for ( let i = 0 ; i < mains . length ; i ++ ) {
212
218
if ( file == mains [ i ] ) {
213
- return execs [ i ] ;
219
+ return vscode . workspace . asRelativePath ( execs [ i ] ) ;
214
220
}
215
221
}
216
222
}
217
- const quickpick = mains . map ( ( e ) => ( {
218
- label : vscode . workspace . asRelativePath ( e ) ,
219
- description : 'Run & Debug' ,
220
- main : e ,
221
- } ) ) ;
223
+
224
+ // There is no current file or it matches no known Main of the project,
225
+ // so we offer all Mains in a QuickPicker for the user to choose from.
226
+ const quickpick = [ ] ;
227
+ for ( let i = 0 ; i < mains . length ; i ++ ) {
228
+ const exec = execs [ i ] ;
229
+ const main = mains [ i ] ;
230
+ quickpick . push ( {
231
+ label : vscode . workspace . asRelativePath ( main ) ,
232
+ description : 'Select for debugging' ,
233
+ execRelPath : vscode . workspace . asRelativePath ( exec ) ,
234
+ } ) ;
235
+ }
222
236
const selectedProgram = await vscode . window . showQuickPick ( quickpick , {
223
- placeHolder : 'Select a main file' ,
237
+ placeHolder : 'Select a main file to debug ' ,
224
238
} ) ;
225
239
if ( selectedProgram ) {
226
- const index = mains . indexOf ( selectedProgram . main ) ;
227
- return vscode . workspace . asRelativePath ( execs [ index ] ) ;
240
+ return selectedProgram . execRelPath ;
228
241
}
229
242
230
243
return undefined ;
0 commit comments