From e2ea2b3f134442ce959952e4bae41da4866af5fa Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Sat, 21 Feb 2026 23:00:32 +0100 Subject: [PATCH 1/2] optimize performance --- .../scopeHandlers/BoundedScopeHandler.ts | 44 ++++++++++++++++--- 1 file changed, 37 insertions(+), 7 deletions(-) diff --git a/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/BoundedScopeHandler.ts b/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/BoundedScopeHandler.ts index 6f0eff3f9b..e81827dce1 100644 --- a/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/BoundedScopeHandler.ts +++ b/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/BoundedScopeHandler.ts @@ -1,6 +1,7 @@ import type { Direction, Position, + Range, ScopeType, TextEditor, } from "@cursorless/common"; @@ -100,18 +101,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 +127,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 +162,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 +186,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 +214,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"); } From 82dc7ba5d61888a4be6cc01a71d1b3b0357c0fd4 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Sat, 21 Feb 2026 23:04:59 +0100 Subject: [PATCH 2/2] Cleanup --- .../modifiers/scopeHandlers/BoundedScopeHandler.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/BoundedScopeHandler.ts b/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/BoundedScopeHandler.ts index e81827dce1..f11d2e8849 100644 --- a/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/BoundedScopeHandler.ts +++ b/packages/cursorless-engine/src/processTargets/modifiers/scopeHandlers/BoundedScopeHandler.ts @@ -1,7 +1,6 @@ import type { Direction, Position, - Range, ScopeType, TextEditor, } from "@cursorless/common";