@@ -27,7 +27,6 @@ export interface PathConfig extends StringIndexedObject {
2727
2828export class PathResource extends Resource < PathConfig > {
2929 private readonly PATH_DECLARATION_REGEX = / ( ( e x p o r t P A T H = ) | ( p a t h + = \( ) | ( p a t h = \( ) ) ( .+ ?) [ \n ; ] / g;
30- private readonly PATH_REGEX = / (?< = [ = " ' : ( ] ) ( [ ^ " ' \n \r ] + ?) (? = [ " ' : ) \n ; ] ) / g
3130 private readonly filePaths = Utils . getShellRcFiles ( )
3231
3332 getSettings ( ) : ResourceSettings < PathConfig > {
@@ -237,24 +236,61 @@ export class PathResource extends Resource<PathConfig> {
237236
238237 for ( const declaration of pathDeclarations ) {
239238 const trimmedDeclaration = declaration [ 0 ] ;
240- const paths = trimmedDeclaration . matchAll ( this . PATH_REGEX ) ;
239+ // Extract the value portion after the = or ( and strip surrounding quotes/parens
240+ const valueMatch = trimmedDeclaration . match ( / (?: e x p o r t P A T H = | p a t h \+ = \( | p a t h = \( ) ( [ " ' ] ? ) ( .+ ?) \1[ \n ; ) ] / s) ;
241+ if ( ! valueMatch ) {
242+ continue ;
243+ }
244+ const value = valueMatch [ 2 ] ;
245+ const paths = this . splitPathValue ( value ) ;
241246
242- for ( const path of paths ) {
243- const trimmedPath = path [ 0 ] ;
244- if ( trimmedPath === '$PATH' ) {
247+ for ( const p of paths ) {
248+ if ( ! p || p . trim ( ) === '' || p === '$PATH' ) {
245249 continue ;
246250 }
247251
248252 results . push ( {
249253 declaration : trimmedDeclaration . trim ( ) ,
250- path : trimmedPath ,
254+ path : p ,
251255 } ) ;
252256 }
253257 }
254258
255259 return results ;
256260 }
257261
262+ // Split a PATH value by ':' but treat ':' inside ${...} as literal
263+ private splitPathValue ( value : string ) : string [ ] {
264+ const segments : string [ ] = [ ] ;
265+ let current = '' ;
266+ let depth = 0 ;
267+
268+ for ( let i = 0 ; i < value . length ; i ++ ) {
269+ const ch = value [ i ] ;
270+ if ( ch === '$' && value [ i + 1 ] === '{' ) {
271+ // Skip the '$', let the '{' handler increment depth
272+ current += ch ;
273+ } else if ( ch === '{' ) {
274+ depth ++ ;
275+ current += ch ;
276+ } else if ( ch === '}' && depth > 0 ) {
277+ depth -- ;
278+ current += ch ;
279+ } else if ( ch === ':' && depth === 0 ) {
280+ segments . push ( current ) ;
281+ current = '' ;
282+ } else {
283+ current += ch ;
284+ }
285+ }
286+
287+ if ( current ) {
288+ segments . push ( current ) ;
289+ }
290+
291+ return segments ;
292+ }
293+
258294 private async resolvePathWithVariables ( pathWithVariables : string ) : Promise < string > {
259295 const $ = getPty ( ) ;
260296 const { data } = await $ . spawnSafe ( `echo ${ pathWithVariables } ` ) ;
0 commit comments