@@ -336,6 +336,7 @@ extension SplitArguments {
336336 /// value for `-f`, or `--foo name` where `name` is the value for `--foo`.
337337 /// If `--foo` expects a value, an input of `--foo --bar name` will return
338338 /// `nil`, since the option `--bar` comes before the value `name`.
339+ /// Also returns `nil` if there's a terminator between the origin and the target value.
339340 mutating func popNextElementIfValue( after origin: InputOrigin . Element ) -> (
340341 InputOrigin . Element , String
341342 ) ? {
@@ -353,26 +354,61 @@ extension SplitArguments {
353354 guard case . value( let value) = elements [ elementIndex] . value
354355 else { return nil }
355356
356- defer { remove ( at: elementIndex) }
357357 let matchedArgumentIndex = elements [ elementIndex] . index
358- return ( . argumentIndex( matchedArgumentIndex) , value)
358+ let targetOrigin = InputOrigin . Element. argumentIndex ( matchedArgumentIndex)
359+
360+ // Check if there's a terminator between the origin and target
361+ if hasTerminatorBetween ( origin, targetOrigin) {
362+ return nil
363+ }
364+
365+ defer { remove ( at: elementIndex) }
366+ return ( targetOrigin, value)
367+ }
368+
369+ /// Helper function to check if there's a terminator between two origins.
370+ private func hasTerminatorBetween(
371+ _ originElement: InputOrigin . Element ,
372+ _ targetOrigin: InputOrigin . Element
373+ ) -> Bool {
374+ guard case . argumentIndex( let currentIndex) = originElement,
375+ case . argumentIndex( let targetIndex) = targetOrigin
376+ else { return false }
377+
378+ // Check if there's a terminator between current position and target position
379+ let terminatorIndex = elements. firstIndex { element in
380+ element. isTerminator
381+ && element. index. inputIndex > currentIndex. inputIndex
382+ && element. index. inputIndex < targetIndex. inputIndex
383+ }
384+
385+ return terminatorIndex != nil
359386 }
360387
361388 /// Pops the next `.value` after the given index.
362389 ///
363390 /// This is used to get the next value in `-f -b name` where `name` is the value of `-f`.
391+ /// Also returns `nil` if there's a terminator between the origin and the target value.
364392 mutating func popNextValue(
365393 after origin: InputOrigin . Element
366394 ) -> ( InputOrigin . Element , String ) ? {
367395 guard let start = position ( after: origin) else { return nil }
368396 guard let resultIndex = elements [ start... ] . firstIndex ( where: { $0. isValue } )
369397 else { return nil }
370398
399+ let targetOrigin = InputOrigin . Element. argumentIndex (
400+ elements [ resultIndex] . index)
401+
402+ // Check if there's a terminator between the origin and target
403+ if hasTerminatorBetween ( origin, targetOrigin) {
404+ return nil
405+ }
406+
371407 defer { remove ( at: resultIndex) }
372408 // swift-format-ignore: NeverForceUnwrap
373409 // This is safe because we know `resultIndex` is refers to a value
374410 return (
375- . argumentIndex ( elements [ resultIndex ] . index ) ,
411+ targetOrigin ,
376412 elements [ resultIndex] . value. valueString!
377413 )
378414 }
@@ -384,6 +420,7 @@ extension SplitArguments {
384420 ///
385421 /// For an input such as `--a --b foo`, if passed the origin of `--a`,
386422 /// this will first pop the value `--b`, then the value `foo`.
423+ /// Also returns `nil` if there's a terminator between the origin and the target element.
387424 mutating func popNextElementAsValue( after origin: InputOrigin . Element ) -> (
388425 InputOrigin . Element , String
389426 ) ? {
@@ -395,11 +432,19 @@ extension SplitArguments {
395432 $0. index. subIndex == . complete
396433 } ) ? . index
397434 else { return nil }
435+
436+ let targetOrigin = InputOrigin . Element. argumentIndex ( nextIndex)
437+
438+ // Check if there's a terminator between the origin and target
439+ if hasTerminatorBetween ( origin, targetOrigin) {
440+ return nil
441+ }
442+
398443 // Remove all elements with this `InputIndex`:
399444 remove ( at: nextIndex)
400445 // Return the original input
401446 return (
402- . argumentIndex ( nextIndex ) , originalInput [ nextIndex. inputIndex. rawValue]
447+ targetOrigin , originalInput [ nextIndex. inputIndex. rawValue]
403448 )
404449 }
405450
0 commit comments