13
13
//===----------------------------------------------------------------------===//
14
14
15
15
import * as vscode from "vscode" ;
16
+ import * as os from "os" ;
17
+ import * as path from "path" ;
16
18
17
19
export type DebugAdapters = "auto" | "lldb-dap" | "CodeLLDB" ;
18
20
export type SetupCodeLLDBOptions =
@@ -106,14 +108,17 @@ const configuration = {
106
108
get lsp ( ) : LSPConfiguration {
107
109
return {
108
110
get serverPath ( ) : string {
109
- return vscode . workspace
110
- . getConfiguration ( "swift.sourcekit-lsp" )
111
- . get < string > ( "serverPath" , "" ) ;
111
+ return substituteVariablesInString (
112
+ vscode . workspace
113
+ . getConfiguration ( "swift.sourcekit-lsp" )
114
+ . get < string > ( "serverPath" , "" )
115
+ ) ;
112
116
} ,
113
117
get serverArguments ( ) : string [ ] {
114
118
return vscode . workspace
115
119
. getConfiguration ( "swift.sourcekit-lsp" )
116
- . get < string [ ] > ( "serverArguments" , [ ] ) ;
120
+ . get < string [ ] > ( "serverArguments" , [ ] )
121
+ . map ( substituteVariablesInString ) ;
117
122
} ,
118
123
get inlayHintsEnabled ( ) : boolean {
119
124
return vscode . workspace
@@ -192,7 +197,8 @@ const configuration = {
192
197
get additionalTestArguments ( ) : string [ ] {
193
198
return vscode . workspace
194
199
. getConfiguration ( "swift" , workspaceFolder )
195
- . get < string [ ] > ( "additionalTestArguments" , [ ] ) ;
200
+ . get < string [ ] > ( "additionalTestArguments" , [ ] )
201
+ . map ( substituteVariablesInString ) ;
196
202
} ,
197
203
/** auto-generate launch.json configurations */
198
204
get autoGenerateLaunchConfigurations ( ) : boolean {
@@ -213,9 +219,11 @@ const configuration = {
213
219
. get < boolean > ( "searchSubfoldersForPackages" , false ) ;
214
220
} ,
215
221
get attachmentsPath ( ) : string {
216
- return vscode . workspace
217
- . getConfiguration ( "swift" , workspaceFolder )
218
- . get < string > ( "attachmentsPath" , "./.build/attachments" ) ;
222
+ return substituteVariablesInString (
223
+ vscode . workspace
224
+ . getConfiguration ( "swift" , workspaceFolder )
225
+ . get < string > ( "attachmentsPath" , "./.build/attachments" )
226
+ ) ;
219
227
} ,
220
228
pluginPermissions ( pluginId ?: string ) : PluginPermissionConfiguration {
221
229
return pluginSetting ( "pluginPermissions" , pluginId , false ) ?? { } ;
@@ -256,7 +264,9 @@ const configuration = {
256
264
}
257
265
} ,
258
266
get customDebugAdapterPath ( ) : string {
259
- return vscode . workspace . getConfiguration ( "swift.debugger" ) . get < string > ( "path" , "" ) ;
267
+ return substituteVariablesInString (
268
+ vscode . workspace . getConfiguration ( "swift.debugger" ) . get < string > ( "path" , "" )
269
+ ) ;
260
270
} ,
261
271
get disable ( ) : boolean {
262
272
return vscode . workspace
@@ -274,7 +284,8 @@ const configuration = {
274
284
get excludeFromCodeCoverage ( ) : string [ ] {
275
285
return vscode . workspace
276
286
. getConfiguration ( "swift" )
277
- . get < string [ ] > ( "excludeFromCodeCoverage" , [ ] ) ;
287
+ . get < string [ ] > ( "excludeFromCodeCoverage" , [ ] )
288
+ . map ( substituteVariablesInString ) ;
278
289
} ,
279
290
/** Files and directories to exclude from the Package Dependencies view. */
280
291
get excludePathsFromPackageDependencies ( ) : string [ ] {
@@ -284,15 +295,21 @@ const configuration = {
284
295
} ,
285
296
/** Path to folder that include swift executable */
286
297
get path ( ) : string {
287
- return vscode . workspace . getConfiguration ( "swift" ) . get < string > ( "path" , "" ) ;
298
+ return substituteVariablesInString (
299
+ vscode . workspace . getConfiguration ( "swift" ) . get < string > ( "path" , "" )
300
+ ) ;
288
301
} ,
289
302
/** Path to folder that include swift runtime */
290
303
get runtimePath ( ) : string {
291
- return vscode . workspace . getConfiguration ( "swift" ) . get < string > ( "runtimePath" , "" ) ;
304
+ return substituteVariablesInString (
305
+ vscode . workspace . getConfiguration ( "swift" ) . get < string > ( "runtimePath" , "" )
306
+ ) ;
292
307
} ,
293
308
/** Path to custom --sdk */
294
309
get sdk ( ) : string {
295
- return vscode . workspace . getConfiguration ( "swift" ) . get < string > ( "SDK" , "" ) ;
310
+ return substituteVariablesInString (
311
+ vscode . workspace . getConfiguration ( "swift" ) . get < string > ( "SDK" , "" )
312
+ ) ;
296
313
} ,
297
314
set sdk ( value : string | undefined ) {
298
315
vscode . workspace . getConfiguration ( "swift" ) . update ( "SDK" , value ) ;
@@ -306,18 +323,26 @@ const configuration = {
306
323
} ,
307
324
/** swift build arguments */
308
325
get buildArguments ( ) : string [ ] {
309
- return vscode . workspace . getConfiguration ( "swift" ) . get < string [ ] > ( "buildArguments" , [ ] ) ;
326
+ return vscode . workspace
327
+ . getConfiguration ( "swift" )
328
+ . get < string [ ] > ( "buildArguments" , [ ] )
329
+ . map ( substituteVariablesInString ) ;
310
330
} ,
311
331
/** swift package arguments */
312
332
get packageArguments ( ) : string [ ] {
313
- return vscode . workspace . getConfiguration ( "swift" ) . get < string [ ] > ( "packageArguments" , [ ] ) ;
333
+ return vscode . workspace
334
+ . getConfiguration ( "swift" )
335
+ . get < string [ ] > ( "packageArguments" , [ ] )
336
+ . map ( substituteVariablesInString ) ;
314
337
} ,
315
338
/** thread/address sanitizer */
316
339
get sanitizer ( ) : string {
317
340
return vscode . workspace . getConfiguration ( "swift" ) . get < string > ( "sanitizer" , "off" ) ;
318
341
} ,
319
342
get buildPath ( ) : string {
320
- return vscode . workspace . getConfiguration ( "swift" ) . get < string > ( "buildPath" , "" ) ;
343
+ return substituteVariablesInString (
344
+ vscode . workspace . getConfiguration ( "swift" ) . get < string > ( "buildPath" , "" )
345
+ ) ;
321
346
} ,
322
347
get disableSwiftPMIntegration ( ) : boolean {
323
348
return vscode . workspace
@@ -437,4 +462,45 @@ const configuration = {
437
462
} ,
438
463
} ;
439
464
465
+ const vsCodeVariableRegex = new RegExp ( / \$ \{ ( .+ ?) \} / g) ;
466
+ function substituteVariablesInString ( val : string ) : string {
467
+ return val . replace ( vsCodeVariableRegex , ( substring : string , varName : string ) =>
468
+ typeof varName === "string" ? computeVscodeVar ( varName ) || substring : substring
469
+ ) ;
470
+ }
471
+
472
+ function computeVscodeVar ( varName : string ) : string | null {
473
+ const workspaceFolder = ( ) => {
474
+ const activeEditor = vscode . window . activeTextEditor ;
475
+ if ( activeEditor ) {
476
+ const documentUri = activeEditor . document . uri ;
477
+ const folder = vscode . workspace . getWorkspaceFolder ( documentUri ) ;
478
+ if ( folder ) {
479
+ return folder . uri . fsPath ;
480
+ }
481
+ }
482
+
483
+ // If there is no active editor then return the first workspace folder
484
+ return vscode . workspace . workspaceFolders ?. at ( 0 ) ?. uri . fsPath ?? "" ;
485
+ } ;
486
+
487
+ // https://code.visualstudio.com/docs/editor/variables-reference
488
+ // Variables to be substituted should be added here.
489
+ const supportedVariables : { [ k : string ] : ( ) => string } = {
490
+ workspaceFolder,
491
+ workspaceFolderBasename : ( ) => path . basename ( workspaceFolder ( ) ) ,
492
+ cwd : ( ) => process . cwd ( ) ,
493
+ userHome : ( ) => os . homedir ( ) ,
494
+ pathSeparator : ( ) => path . sep ,
495
+
496
+ // see
497
+ // https://github.com/microsoft/vscode/blob/08ac1bb67ca2459496b272d8f4a908757f24f56f/src/vs/workbench/api/common/extHostVariableResolverService.ts#L81
498
+ // or
499
+ // https://github.com/microsoft/vscode/blob/29eb316bb9f154b7870eb5204ec7f2e7cf649bec/src/vs/server/node/remoteTerminalChannel.ts#L56
500
+ execPath : ( ) => process . env . VSCODE_EXEC_PATH ?? process . execPath ,
501
+ } ;
502
+
503
+ return varName in supportedVariables ? supportedVariables [ varName ] ( ) : null ;
504
+ }
505
+
440
506
export default configuration ;
0 commit comments