@@ -303,7 +303,7 @@ export async function* expandGlob(
303303 let fixedRoot = isGlobAbsolute ? winRoot ?? "/" : absRoot ;
304304 while ( segments . length > 0 && ! isGlob ( segments [ 0 ] ! ) ) {
305305 const seg = segments . shift ( ) ! ;
306- fixedRoot = joinGlobs ( [ fixedRoot , seg ] , globOptions ) ;
306+ fixedRoot = joinGlobs ( [ fixedRoot , unescapeGlobSegment ( seg ) ] , globOptions ) ;
307307 }
308308
309309 let fixedRootInfo : WalkEntry ;
@@ -460,7 +460,7 @@ export function* expandGlobSync(
460460 let fixedRoot = isGlobAbsolute ? winRoot ?? "/" : absRoot ;
461461 while ( segments . length > 0 && ! isGlob ( segments [ 0 ] ! ) ) {
462462 const seg = segments . shift ( ) ! ;
463- fixedRoot = joinGlobs ( [ fixedRoot , seg ] , globOptions ) ;
463+ fixedRoot = joinGlobs ( [ fixedRoot , unescapeGlobSegment ( seg ) ] , globOptions ) ;
464464 }
465465
466466 let fixedRootInfo : WalkEntry ;
@@ -532,3 +532,29 @@ export function* expandGlobSync(
532532 }
533533 yield * currentMatches ;
534534}
535+
536+ const globEscapeChar = Deno . build . os === "windows" ? "`" : `\\` ;
537+ const globMetachars = "*?{}[]()|+@!" ;
538+ function unescapeGlobSegment ( segment : string ) : string {
539+ let result = "" ;
540+ let lastIndex = 0 ;
541+ for ( let i = 0 ; i < segment . length ; i ++ ) {
542+ const char = segment [ i ] ;
543+ if ( char === globEscapeChar ) {
544+ const nextChar = segment [ i + 1 ] ;
545+ if ( nextChar && globMetachars . includes ( nextChar ) ) {
546+ // append the slice before the escape char, then the metachar
547+ result += segment . slice ( lastIndex , i ) + nextChar ;
548+ i ++ ; // skip next char since we already processed it
549+ lastIndex = i + 1 ;
550+ }
551+ }
552+ }
553+ // no escaped, return the original segment
554+ if ( lastIndex === 0 ) {
555+ return segment ;
556+ }
557+ // append any remaining characters
558+ result += segment . slice ( lastIndex ) ;
559+ return result ;
560+ }
0 commit comments