diff --git a/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/BoundedScopeHandler.ts b/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/BoundedScopeHandler.ts index 6f0eff3f9b..f11d2e8849 100644 --- a/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/BoundedScopeHandler.ts +++ b/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/BoundedScopeHandler.ts @@ -100,18 +100,23 @@ abstract class BoundedBaseScopeHandler extends BaseScopeHandler { ), ); + if (interiorScopes.length === 0) { + yield* targetScopes; + return; + } + for (const targetScope of targetScopes) { - const allScopes: TargetScope[] = []; + let allScopes: TargetScope[] | undefined; for (const interiorScope of interiorScopes) { const domain = targetScope.domain.intersection(interiorScope.domain); if (domain != null && !domain.isEmpty) { - allScopes.push({ + (allScopes ??= []).push({ editor, domain, getTargets: (isReversed) => { return [ - this.getTargets( + this.createTarget( ensureSingleTarget(targetScope, isReversed), ensureSingleTarget(interiorScope, isReversed), ), @@ -121,6 +126,30 @@ abstract class BoundedBaseScopeHandler extends BaseScopeHandler { } } + if (allScopes == null) { + yield targetScope; + continue; + } + + if (allScopes.length === 1) { + const intersectionScope = allScopes[0]; + if ( + compareTargetScopes( + direction, + position, + intersectionScope, + targetScope, + ) <= 0 + ) { + yield intersectionScope; + yield targetScope; + } else { + yield targetScope; + yield intersectionScope; + } + continue; + } + // NB: We add the target scope last so that if it is identical to // one of our intersection scopes, we prefer that one so that rich ranges // function properly @@ -132,7 +161,7 @@ abstract class BoundedBaseScopeHandler extends BaseScopeHandler { } } - protected abstract getTargets(target: Target, interior: Target): Target; + protected abstract createTarget(target: Target, interior: Target): Target; } function ensureSingleTarget(scope: TargetScope, isReversed: boolean): Target { @@ -156,13 +185,13 @@ export class BoundedNonWhitespaceSequenceScopeHandler extends BoundedBaseScopeHa super(scopeHandlerFactory, languageId, { type: "nonWhitespaceSequence" }); } - protected getTargets(target: Target, interior: Target): Target { + protected createTarget(target: Target, interior: Target): Target { const contentRange = target.contentRange.intersection( interior.contentRange, ); if (contentRange == null || contentRange.isEmpty) { - throw Error("Expected non empty intersection"); + throw Error("Expected non-empty intersection"); } return new TokenTarget({ @@ -184,7 +213,7 @@ export class BoundedParagraphScopeHandler extends BoundedBaseScopeHandler { super(scopeHandlerFactory, languageId, { type: "paragraph" }); } - protected getTargets(target: Target, interior: InteriorTarget): Target { + protected createTarget(target: Target, interior: InteriorTarget): Target { if (!(target instanceof ParagraphTarget)) { throw Error("Expected ParagraphTarget"); }