1- import path = require( "path" ) ;
1+ import * as path from "path" ;
2+ import * as os from "os" ;
23import * as vscode from "vscode" ;
34import { Env } from "./client" ;
45import { log } from "./util" ;
@@ -187,6 +188,37 @@ export class Config {
187188 }
188189}
189190
191+ const VarRegex = new RegExp ( / \$ \{ ( .+ ?) \} / g) ;
192+
193+ export function substituteVSCodeVariableInString ( val : string ) : string {
194+ return val . replaceAll ( VarRegex , ( substring : string , varName ) => {
195+ if ( typeof varName === "string" ) {
196+ return computeVscodeVar ( varName ) || substring ;
197+ } else {
198+ return substring ;
199+ }
200+ } ) ;
201+ }
202+
203+ export function substituteVSCodeVariables ( resp : any ) : any {
204+ if ( typeof resp === "string" ) {
205+ return substituteVSCodeVariableInString ( resp ) ;
206+ } else if ( resp && Array . isArray ( resp ) ) {
207+ return resp . map ( ( val ) => {
208+ return substituteVSCodeVariables ( val ) ;
209+ } ) ;
210+ } else if ( resp && typeof resp === "object" ) {
211+ const res : { [ key : string ] : any } = { } ;
212+ for ( const key in resp ) {
213+ const val = resp [ key ] ;
214+ res [ key ] = substituteVSCodeVariables ( val ) ;
215+ }
216+ return res ;
217+ } else if ( typeof resp === "function" ) {
218+ return null ;
219+ }
220+ return resp ;
221+ }
190222export function substituteVariablesInEnv ( env : Env ) : Env {
191223 const missingDeps = new Set < string > ( ) ;
192224 // vscode uses `env:ENV_NAME` for env vars resolution, and it's easier
@@ -233,7 +265,7 @@ export function substituteVariablesInEnv(env: Env): Env {
233265 }
234266 } else {
235267 envWithDeps [ dep ] = {
236- value : computeVscodeVar ( dep ) ,
268+ value : computeVscodeVar ( dep ) || "${" + dep + "}" ,
237269 deps : [ ] ,
238270 } ;
239271 }
@@ -264,37 +296,34 @@ export function substituteVariablesInEnv(env: Env): Env {
264296 return resolvedEnv ;
265297}
266298
267- function computeVscodeVar ( varName : string ) : string {
299+ function computeVscodeVar ( varName : string ) : string | null {
300+ const workspaceFolder = ( ) => {
301+ const folders = vscode . workspace . workspaceFolders ?? [ ] ;
302+ if ( folders . length === 1 ) {
303+ // TODO: support for remote workspaces?
304+ return folders [ 0 ] . uri . fsPath ;
305+ } else if ( folders . length > 1 ) {
306+ // could use currently opened document to detect the correct
307+ // workspace. However, that would be determined by the document
308+ // user has opened on Editor startup. Could lead to
309+ // unpredictable workspace selection in practice.
310+ // It's better to pick the first one
311+ return folders [ 0 ] . uri . fsPath ;
312+ } else {
313+ // no workspace opened
314+ return "" ;
315+ }
316+ } ;
268317 // https://code.visualstudio.com/docs/editor/variables-reference
269318 const supportedVariables : { [ k : string ] : ( ) => string } = {
270- workspaceFolder : ( ) => {
271- const folders = vscode . workspace . workspaceFolders ?? [ ] ;
272- if ( folders . length === 1 ) {
273- // TODO: support for remote workspaces?
274- return folders [ 0 ] . uri . fsPath ;
275- } else if ( folders . length > 1 ) {
276- // could use currently opened document to detect the correct
277- // workspace. However, that would be determined by the document
278- // user has opened on Editor startup. Could lead to
279- // unpredictable workspace selection in practice.
280- // It's better to pick the first one
281- return folders [ 0 ] . uri . fsPath ;
282- } else {
283- // no workspace opened
284- return "" ;
285- }
286- } ,
319+ workspaceFolder,
287320
288321 workspaceFolderBasename : ( ) => {
289- const workspaceFolder = computeVscodeVar ( "workspaceFolder" ) ;
290- if ( workspaceFolder ) {
291- return path . basename ( workspaceFolder ) ;
292- } else {
293- return "" ;
294- }
322+ return path . basename ( workspaceFolder ( ) ) ;
295323 } ,
296324
297325 cwd : ( ) => process . cwd ( ) ,
326+ userHome : ( ) => os . homedir ( ) ,
298327
299328 // see
300329 // https://github.com/microsoft/vscode/blob/08ac1bb67ca2459496b272d8f4a908757f24f56f/src/vs/workbench/api/common/extHostVariableResolverService.ts#L81
@@ -308,7 +337,7 @@ function computeVscodeVar(varName: string): string {
308337 if ( varName in supportedVariables ) {
309338 return supportedVariables [ varName ] ( ) ;
310339 } else {
311- // can't resolve, keep the expression as is
312- return "${" + varName + "}" ;
340+ // return "${" + varName + "}";
341+ return null ;
313342 }
314343}
0 commit comments