1414-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy --
1515-- of the license. --
1616----------------------------------------------------------------------------*/
17+ import { platform } from 'os' ;
18+ import * as path from 'path' ;
1719import * as vscode from 'vscode' ;
18- import * as path from 'path'
1920
2021/**
2122 * Substitue any variable reference present in the given string. VS Code
2223 * variable references are listed here:
2324 * https://code.visualstudio.com/docs/editor/variables-reference
24- * @param str
25- * @param recursive
26- * @returns
25+ * @param str - string to perform substitution on
26+ * @param recursive - whether to perform substitution recursively on the result
27+ * of each substitution until there are no variables to substitute.
28+ *
29+ * @returns string after applying substitutions
2730 */
28- export function substituteVariables ( str : string , recursive = false ) {
29-
30- let workspaces = vscode . workspace . workspaceFolders ?? [ ] ;
31- let workspace = workspaces . length ? workspaces [ 0 ] : null ;
32- let activeEditor = vscode . window . activeTextEditor
33- let activeFile = activeEditor ?. document ;
34- let absoluteFilePath = activeFile ?. uri . fsPath ?? ""
31+ export function substituteVariables ( str : string , recursive = false ) : string {
32+ const workspaces = vscode . workspace . workspaceFolders ?? [ ] ;
33+ const workspace = workspaces . length ? workspaces [ 0 ] : null ;
34+ const activeEditor = vscode . window . activeTextEditor ;
35+ const activeFile = activeEditor ?. document ;
36+ const absoluteFilePath = activeFile ?. uri . fsPath ?? '' ;
3537
3638 if ( workspace != null ) {
3739 str = str . replace ( / \$ { workspaceFolder} / g, workspace ?. uri . fsPath ) ;
@@ -41,43 +43,102 @@ export function substituteVariables(str: string, recursive = false) {
4143 str = str . replace ( / \$ { file} / g, absoluteFilePath ) ;
4244 let activeWorkspace = workspace ;
4345 let relativeFilePath = absoluteFilePath ;
44- for ( let workspace of workspaces ) {
46+ for ( const workspace of workspaces ) {
4547 if ( absoluteFilePath . replace ( workspace . uri . fsPath , '' ) !== absoluteFilePath ) {
4648 activeWorkspace = workspace ;
47- relativeFilePath = absoluteFilePath . replace ( workspace . uri . fsPath , '' ) . substr ( path . sep . length ) ;
49+ relativeFilePath = absoluteFilePath
50+ . replace ( workspace . uri . fsPath , '' )
51+ . substr ( path . sep . length ) ;
4852 break ;
4953 }
5054 }
51- let parsedPath = path . parse ( absoluteFilePath ) ;
55+ const parsedPath = path . parse ( absoluteFilePath ) ;
5256
5357 if ( activeWorkspace != null ) {
5458 str = str . replace ( / \$ { fileWorkspaceFolder} / g, activeWorkspace ?. uri . fsPath ) ;
5559 }
5660
5761 str = str . replace ( / \$ { relativeFile} / g, relativeFilePath ) ;
58- str = str . replace ( / \$ { relativeFileDirname} / g, relativeFilePath . substr ( 0 , relativeFilePath . lastIndexOf ( path . sep ) ) ) ;
62+ str = str . replace (
63+ / \$ { relativeFileDirname} / g,
64+ relativeFilePath . substr ( 0 , relativeFilePath . lastIndexOf ( path . sep ) )
65+ ) ;
5966 str = str . replace ( / \$ { fileBasename} / g, parsedPath . base ) ;
6067 str = str . replace ( / \$ { fileBasenameNoExtension} / g, parsedPath . name ) ;
6168 str = str . replace ( / \$ { fileExtname} / g, parsedPath . ext ) ;
62- str = str . replace ( / \$ { fileDirname} / g, parsedPath . dir . substr ( parsedPath . dir . lastIndexOf ( path . sep ) + 1 ) ) ;
69+ str = str . replace (
70+ / \$ { fileDirname} / g,
71+ parsedPath . dir . substr ( parsedPath . dir . lastIndexOf ( path . sep ) + 1 )
72+ ) ;
6373 str = str . replace ( / \$ { cwd} / g, parsedPath . dir ) ;
6474 str = str . replace ( / \$ { pathSeparator} / g, path . sep ) ;
6575
6676 if ( activeEditor != null ) {
6777 str = str . replace ( / \$ { lineNumber} / g, ( activeEditor . selection . start . line + 1 ) . toString ( ) ) ;
68- str = str . replace ( / \$ { selectedText} / g, activeEditor . document . getText ( new vscode . Range ( activeEditor . selection . start , activeEditor . selection . end ) ) ) ;
78+ str = str . replace (
79+ / \$ { selectedText} / g,
80+ activeEditor . document . getText (
81+ new vscode . Range ( activeEditor . selection . start , activeEditor . selection . end )
82+ )
83+ ) ;
6984 }
7085
7186 str = str . replace ( / \$ { env:( .* ?) } / g, function ( variable ) {
87+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
7288 return process . env [ variable . match ( / \$ { env:( .* ?) } / ) ! [ 1 ] ] || '' ;
7389 } ) ;
7490
7591 str = str . replace ( / \$ { config:( .* ?) } / g, function ( variable ) {
92+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
7693 return vscode . workspace . getConfiguration ( ) . get ( variable . match ( / \$ { config:( .* ?) } / ) ! [ 1 ] , '' ) ;
7794 } ) ;
7895
79- if ( recursive && str . match ( / \$ { ( w o r k s p a c e F o l d e r | w o r k s p a c e F o l d e r B a s e n a m e | f i l e W o r k s p a c e F o l d e r | r e l a t i v e F i l e | f i l e B a s e n a m e | f i l e B a s e n a m e N o E x t e n s i o n | f i l e E x t n a m e | f i l e D i r n a m e | c w d | p a t h S e p a r a t o r | l i n e N u m b e r | s e l e c t e d T e x t | e n v : ( .* ?) | c o n f i g : ( .* ?) ) } / ) ) {
96+ if (
97+ recursive &&
98+ str . match (
99+ // eslint-disable-next-line max-len
100+ / \$ { ( w o r k s p a c e F o l d e r | w o r k s p a c e F o l d e r B a s e n a m e | f i l e W o r k s p a c e F o l d e r | r e l a t i v e F i l e | f i l e B a s e n a m e | f i l e B a s e n a m e N o E x t e n s i o n | f i l e E x t n a m e | f i l e D i r n a m e | c w d | p a t h S e p a r a t o r | l i n e N u m b e r | s e l e c t e d T e x t | e n v : ( .* ?) | c o n f i g : ( .* ?) ) } /
101+ )
102+ ) {
80103 str = substituteVariables ( str , recursive ) ;
81104 }
82105 return str ;
83- }
106+ }
107+
108+ export function getCustomEnv ( ) {
109+ const user_platform = platform ( ) ;
110+ let env_config_name = 'terminal.integrated.env' ;
111+
112+ switch ( user_platform ) {
113+ case 'darwin' :
114+ env_config_name += '.osx' ;
115+ break ;
116+ case 'win32' :
117+ env_config_name += '.windows' ;
118+ break ;
119+ default :
120+ env_config_name += '.linux' ;
121+ }
122+
123+ const custom_env = vscode . workspace
124+ . getConfiguration ( )
125+ . get < { [ name : string ] : string } > ( env_config_name ) ;
126+
127+ return custom_env ;
128+ }
129+
130+ export function getEvaluatedCustomEnv ( ) {
131+ const custom_env = getCustomEnv ( ) ;
132+
133+ if ( custom_env ) {
134+ for ( const var_name in custom_env ) {
135+ // Substitute VS Code variable references that might be present
136+ // in the JSON settings configuration (e.g: "PATH": "${workspaceFolder}/obj")
137+ custom_env [ var_name ] = custom_env [ var_name ] . replace ( / ( \$ \{ .* \} ) / , ( substring ) =>
138+ substituteVariables ( substring , false )
139+ ) ;
140+ }
141+ }
142+
143+ return custom_env ;
144+ }
0 commit comments