diff --git a/packages/app-web-docs/src/docs/user/languages/fixtures/csharp.json b/packages/app-web-docs/src/docs/user/languages/fixtures/csharp.json
index f8bb633e7b4..91c743a4cf4 100644
--- a/packages/app-web-docs/src/docs/user/languages/fixtures/csharp.json
+++ b/packages/app-web-docs/src/docs/user/languages/fixtures/csharp.json
@@ -1233,14 +1233,6 @@
],
"domain": "0:11-2:0"
},
- {
- "targets": [
- {
- "content": "1:4-1:25"
- }
- ],
- "domain": "1:0-1:25"
- },
{
"targets": [
{
diff --git a/packages/app-web-docs/src/docs/user/languages/fixtures/go.json b/packages/app-web-docs/src/docs/user/languages/fixtures/go.json
index f98497e5278..bee803acff0 100644
--- a/packages/app-web-docs/src/docs/user/languages/fixtures/go.json
+++ b/packages/app-web-docs/src/docs/user/languages/fixtures/go.json
@@ -836,14 +836,6 @@
],
"domain": "0:0-0:8"
},
- {
- "targets": [
- {
- "content": "0:0-0:16"
- }
- ],
- "domain": "0:0-0:16"
- },
{
"targets": [
{
diff --git a/packages/app-web-docs/src/docs/user/languages/fixtures/java.json b/packages/app-web-docs/src/docs/user/languages/fixtures/java.json
index 1906c13af39..3c4d5eaa15a 100644
--- a/packages/app-web-docs/src/docs/user/languages/fixtures/java.json
+++ b/packages/app-web-docs/src/docs/user/languages/fixtures/java.json
@@ -1251,14 +1251,6 @@
],
"domain": "0:18-2:0"
},
- {
- "targets": [
- {
- "content": "1:4-1:17"
- }
- ],
- "domain": "1:0-1:17"
- },
{
"targets": [
{
@@ -1291,14 +1283,6 @@
],
"domain": "1:16-3:4"
},
- {
- "targets": [
- {
- "content": "2:8-2:21"
- }
- ],
- "domain": "2:0-2:21"
- },
{
"targets": [
{
@@ -1326,18 +1310,42 @@
{
"targets": [
{
- "content": "1:4-1:47"
+ "content": "1:22-1:44"
}
],
- "domain": "1:0-1:47"
- },
+ "domain": "1:15-1:44"
+ }
+ ]
+ },
+ {
+ "name": "scopes/java/collectionItem.unenclosed.iteration4",
+ "languageId": "java",
+ "facet": "collectionItem.unenclosed.iteration",
+ "code": "sealed class Foo implements Bar, Baz {}",
+ "scopes": [
{
"targets": [
{
- "content": "1:22-1:44"
+ "content": "0:28-0:36"
}
],
- "domain": "1:15-1:44"
+ "domain": "0:17-0:36"
+ }
+ ]
+ },
+ {
+ "name": "scopes/java/collectionItem.unenclosed.iteration5",
+ "languageId": "java",
+ "facet": "collectionItem.unenclosed.iteration",
+ "code": "sealed interface Foo permits Bar, Baz {}",
+ "scopes": [
+ {
+ "targets": [
+ {
+ "content": "0:29-0:37"
+ }
+ ],
+ "domain": "0:21-0:37"
}
]
},
@@ -1482,6 +1490,76 @@
}
]
},
+ {
+ "name": "scopes/java/collectionItem.unenclosed.multiLine4",
+ "languageId": "java",
+ "facet": "collectionItem.unenclosed.multiLine",
+ "code": "sealed class Foo\n implements Bar,\n Baz {}",
+ "scopes": [
+ {
+ "targets": [
+ {
+ "content": "1:4-1:18",
+ "removal": "1:4-1:19"
+ }
+ ],
+ "domain": "1:4-1:18"
+ },
+ {
+ "targets": [
+ {
+ "content": "1:15-1:18",
+ "removal": "1:15-2:4"
+ }
+ ],
+ "domain": "1:15-1:18"
+ },
+ {
+ "targets": [
+ {
+ "content": "2:4-2:7",
+ "removal": "1:18-2:7"
+ }
+ ],
+ "domain": "2:4-2:7"
+ }
+ ]
+ },
+ {
+ "name": "scopes/java/collectionItem.unenclosed.multiLine5",
+ "languageId": "java",
+ "facet": "collectionItem.unenclosed.multiLine",
+ "code": "sealed interface Foo\n permits Bar,\n Baz {}",
+ "scopes": [
+ {
+ "targets": [
+ {
+ "content": "1:4-1:15",
+ "removal": "1:4-1:16"
+ }
+ ],
+ "domain": "1:4-1:15"
+ },
+ {
+ "targets": [
+ {
+ "content": "1:12-1:15",
+ "removal": "1:12-2:4"
+ }
+ ],
+ "domain": "1:12-1:15"
+ },
+ {
+ "targets": [
+ {
+ "content": "2:4-2:7",
+ "removal": "1:15-2:7"
+ }
+ ],
+ "domain": "2:4-2:7"
+ }
+ ]
+ },
{
"name": "scopes/java/collectionItem.unenclosed.singleLine",
"languageId": "java",
@@ -1623,6 +1701,94 @@
}
]
},
+ {
+ "name": "scopes/java/collectionItem.unenclosed.singleLine4",
+ "languageId": "java",
+ "facet": "collectionItem.unenclosed.singleLine",
+ "code": "sealed class Foo implements Bar, Baz {}",
+ "scopes": [
+ {
+ "targets": [
+ {
+ "content": "0:0-0:31",
+ "removal": "0:0-0:33"
+ }
+ ],
+ "domain": "0:0-0:31"
+ },
+ {
+ "targets": [
+ {
+ "content": "0:28-0:31",
+ "removal": "0:28-0:33"
+ }
+ ],
+ "domain": "0:28-0:31"
+ },
+ {
+ "targets": [
+ {
+ "content": "0:33-0:36",
+ "removal": "0:31-0:36"
+ }
+ ],
+ "domain": "0:33-0:36"
+ },
+ {
+ "targets": [
+ {
+ "content": "0:33-0:39",
+ "removal": "0:31-0:39"
+ }
+ ],
+ "domain": "0:33-0:39"
+ }
+ ]
+ },
+ {
+ "name": "scopes/java/collectionItem.unenclosed.singleLine5",
+ "languageId": "java",
+ "facet": "collectionItem.unenclosed.singleLine",
+ "code": "sealed interface Foo permits Bar, Baz {}",
+ "scopes": [
+ {
+ "targets": [
+ {
+ "content": "0:0-0:32",
+ "removal": "0:0-0:34"
+ }
+ ],
+ "domain": "0:0-0:32"
+ },
+ {
+ "targets": [
+ {
+ "content": "0:29-0:32",
+ "removal": "0:29-0:34"
+ }
+ ],
+ "domain": "0:29-0:32"
+ },
+ {
+ "targets": [
+ {
+ "content": "0:34-0:37",
+ "removal": "0:32-0:37"
+ }
+ ],
+ "domain": "0:34-0:37"
+ },
+ {
+ "targets": [
+ {
+ "content": "0:34-0:40",
+ "removal": "0:32-0:40"
+ }
+ ],
+ "domain": "0:34-0:40"
+ }
+ ]
+ },
{
"name": "scopes/java/comment.block",
"languageId": "java",
diff --git a/packages/app-web-docs/src/docs/user/languages/fixtures/lua.json b/packages/app-web-docs/src/docs/user/languages/fixtures/lua.json
index 8fb41679554..665256d6bd0 100644
--- a/packages/app-web-docs/src/docs/user/languages/fixtures/lua.json
+++ b/packages/app-web-docs/src/docs/user/languages/fixtures/lua.json
@@ -711,14 +711,6 @@
"facet": "collectionItem.unenclosed.iteration",
"code": "local a, b, c = 1, 2, 3",
"scopes": [
- {
- "targets": [
- {
- "content": "0:0-0:23"
- }
- ],
- "domain": "0:0-0:23"
- },
{
"targets": [
{
diff --git a/packages/app-web-docs/src/docs/user/languages/fixtures/python.json b/packages/app-web-docs/src/docs/user/languages/fixtures/python.json
index fb2f663d261..7a7d7f39056 100644
--- a/packages/app-web-docs/src/docs/user/languages/fixtures/python.json
+++ b/packages/app-web-docs/src/docs/user/languages/fixtures/python.json
@@ -1377,14 +1377,6 @@
"facet": "collectionItem.unenclosed.iteration",
"code": "def foo():\n global bar, baz",
"scopes": [
- {
- "targets": [
- {
- "content": "1:4-1:19"
- }
- ],
- "domain": "1:0-1:19"
- },
{
"targets": [
{
@@ -1401,14 +1393,6 @@
"facet": "collectionItem.unenclosed.iteration",
"code": "for key, value in map.items():\n pass",
"scopes": [
- {
- "targets": [
- {
- "content": "0:0-0:30"
- }
- ],
- "domain": "0:0-0:30"
- },
{
"targets": [
{
diff --git a/packages/app-web-docs/src/docs/user/languages/java.mdx b/packages/app-web-docs/src/docs/user/languages/java.mdx
index 895a4ccee79..3e2a1d24256 100644
--- a/packages/app-web-docs/src/docs/user/languages/java.mdx
+++ b/packages/app-web-docs/src/docs/user/languages/java.mdx
@@ -385,6 +385,10 @@ Below are visualizations of all our scope tests for this language. These were cr
+
+
+
+
#### 2. Collection item: Unenclosed single line
An item in a comma-separated single-line list without enclosing delimiters. This could be multi-variable declarations, import statements, etc.
@@ -395,6 +399,10 @@ Below are visualizations of all our scope tests for this language. These were cr
+
+
+
+
#### 3. Collection item: Unenclosed (iteration)
Iteration scope for items in a comma-separated list without enclosing delimiters
@@ -405,6 +413,10 @@ Below are visualizations of all our scope tests for this language. These were cr
+
+
+
+
### Comment
#### 1. Comment: Block
diff --git a/packages/app-web-docs/src/docs/user/scopes/collectionItem.mdx b/packages/app-web-docs/src/docs/user/scopes/collectionItem.mdx
index bf1b91aed59..f1e44760ac6 100644
--- a/packages/app-web-docs/src/docs/user/scopes/collectionItem.mdx
+++ b/packages/app-web-docs/src/docs/user/scopes/collectionItem.mdx
@@ -97,6 +97,10 @@ Default: `item`
+
+
+
+
##### JavaScript
@@ -151,6 +155,10 @@ Default: `item`
+
+
+
+
##### JavaScript
@@ -227,6 +235,10 @@ Default: `item`
+
+
+
+
##### JavaScript
diff --git a/packages/app-web-docs/src/docs/user/scopes/fixtures/collectionItem.json b/packages/app-web-docs/src/docs/user/scopes/fixtures/collectionItem.json
index 1de3d58c3ea..b052bfb74f3 100644
--- a/packages/app-web-docs/src/docs/user/scopes/fixtures/collectionItem.json
+++ b/packages/app-web-docs/src/docs/user/scopes/fixtures/collectionItem.json
@@ -124,14 +124,6 @@
],
"domain": "0:11-2:0"
},
- {
- "targets": [
- {
- "content": "1:4-1:25"
- }
- ],
- "domain": "1:0-1:25"
- },
{
"targets": [
{
@@ -469,14 +461,6 @@
],
"domain": "0:0-0:8"
},
- {
- "targets": [
- {
- "content": "0:0-0:16"
- }
- ],
- "domain": "0:0-0:16"
- },
{
"targets": [
{
@@ -607,14 +591,6 @@
],
"domain": "0:18-2:0"
},
- {
- "targets": [
- {
- "content": "1:4-1:17"
- }
- ],
- "domain": "1:0-1:17"
- },
{
"targets": [
{
@@ -647,14 +623,6 @@
],
"domain": "1:16-3:4"
},
- {
- "targets": [
- {
- "content": "2:8-2:21"
- }
- ],
- "domain": "2:0-2:21"
- },
{
"targets": [
{
@@ -682,18 +650,42 @@
{
"targets": [
{
- "content": "1:4-1:47"
+ "content": "1:22-1:44"
}
],
- "domain": "1:0-1:47"
- },
+ "domain": "1:15-1:44"
+ }
+ ]
+ },
+ {
+ "name": "scopes/java/collectionItem.unenclosed.iteration4",
+ "languageId": "java",
+ "facet": "collectionItem.unenclosed.iteration",
+ "code": "sealed class Foo implements Bar, Baz {}",
+ "scopes": [
{
"targets": [
{
- "content": "1:22-1:44"
+ "content": "0:28-0:36"
}
],
- "domain": "1:15-1:44"
+ "domain": "0:17-0:36"
+ }
+ ]
+ },
+ {
+ "name": "scopes/java/collectionItem.unenclosed.iteration5",
+ "languageId": "java",
+ "facet": "collectionItem.unenclosed.iteration",
+ "code": "sealed interface Foo permits Bar, Baz {}",
+ "scopes": [
+ {
+ "targets": [
+ {
+ "content": "0:29-0:37"
+ }
+ ],
+ "domain": "0:21-0:37"
}
]
},
@@ -838,6 +830,76 @@
}
]
},
+ {
+ "name": "scopes/java/collectionItem.unenclosed.multiLine4",
+ "languageId": "java",
+ "facet": "collectionItem.unenclosed.multiLine",
+ "code": "sealed class Foo\n implements Bar,\n Baz {}",
+ "scopes": [
+ {
+ "targets": [
+ {
+ "content": "1:4-1:18",
+ "removal": "1:4-1:19"
+ }
+ ],
+ "domain": "1:4-1:18"
+ },
+ {
+ "targets": [
+ {
+ "content": "1:15-1:18",
+ "removal": "1:15-2:4"
+ }
+ ],
+ "domain": "1:15-1:18"
+ },
+ {
+ "targets": [
+ {
+ "content": "2:4-2:7",
+ "removal": "1:18-2:7"
+ }
+ ],
+ "domain": "2:4-2:7"
+ }
+ ]
+ },
+ {
+ "name": "scopes/java/collectionItem.unenclosed.multiLine5",
+ "languageId": "java",
+ "facet": "collectionItem.unenclosed.multiLine",
+ "code": "sealed interface Foo\n permits Bar,\n Baz {}",
+ "scopes": [
+ {
+ "targets": [
+ {
+ "content": "1:4-1:15",
+ "removal": "1:4-1:16"
+ }
+ ],
+ "domain": "1:4-1:15"
+ },
+ {
+ "targets": [
+ {
+ "content": "1:12-1:15",
+ "removal": "1:12-2:4"
+ }
+ ],
+ "domain": "1:12-1:15"
+ },
+ {
+ "targets": [
+ {
+ "content": "2:4-2:7",
+ "removal": "1:15-2:7"
+ }
+ ],
+ "domain": "2:4-2:7"
+ }
+ ]
+ },
{
"name": "scopes/java/collectionItem.unenclosed.singleLine",
"languageId": "java",
@@ -979,6 +1041,94 @@
}
]
},
+ {
+ "name": "scopes/java/collectionItem.unenclosed.singleLine4",
+ "languageId": "java",
+ "facet": "collectionItem.unenclosed.singleLine",
+ "code": "sealed class Foo implements Bar, Baz {}",
+ "scopes": [
+ {
+ "targets": [
+ {
+ "content": "0:0-0:31",
+ "removal": "0:0-0:33"
+ }
+ ],
+ "domain": "0:0-0:31"
+ },
+ {
+ "targets": [
+ {
+ "content": "0:28-0:31",
+ "removal": "0:28-0:33"
+ }
+ ],
+ "domain": "0:28-0:31"
+ },
+ {
+ "targets": [
+ {
+ "content": "0:33-0:36",
+ "removal": "0:31-0:36"
+ }
+ ],
+ "domain": "0:33-0:36"
+ },
+ {
+ "targets": [
+ {
+ "content": "0:33-0:39",
+ "removal": "0:31-0:39"
+ }
+ ],
+ "domain": "0:33-0:39"
+ }
+ ]
+ },
+ {
+ "name": "scopes/java/collectionItem.unenclosed.singleLine5",
+ "languageId": "java",
+ "facet": "collectionItem.unenclosed.singleLine",
+ "code": "sealed interface Foo permits Bar, Baz {}",
+ "scopes": [
+ {
+ "targets": [
+ {
+ "content": "0:0-0:32",
+ "removal": "0:0-0:34"
+ }
+ ],
+ "domain": "0:0-0:32"
+ },
+ {
+ "targets": [
+ {
+ "content": "0:29-0:32",
+ "removal": "0:29-0:34"
+ }
+ ],
+ "domain": "0:29-0:32"
+ },
+ {
+ "targets": [
+ {
+ "content": "0:34-0:37",
+ "removal": "0:32-0:37"
+ }
+ ],
+ "domain": "0:34-0:37"
+ },
+ {
+ "targets": [
+ {
+ "content": "0:34-0:40",
+ "removal": "0:32-0:40"
+ }
+ ],
+ "domain": "0:34-0:40"
+ }
+ ]
+ },
{
"name": "scopes/javascript.core/collectionItem.unenclosed.iteration",
"languageId": "javascript.core",
@@ -1156,14 +1306,6 @@
"facet": "collectionItem.unenclosed.iteration",
"code": "local a, b, c = 1, 2, 3",
"scopes": [
- {
- "targets": [
- {
- "content": "0:0-0:23"
- }
- ],
- "domain": "0:0-0:23"
- },
{
"targets": [
{
@@ -2088,14 +2230,6 @@
"facet": "collectionItem.unenclosed.iteration",
"code": "def foo():\n global bar, baz",
"scopes": [
- {
- "targets": [
- {
- "content": "1:4-1:19"
- }
- ],
- "domain": "1:0-1:19"
- },
{
"targets": [
{
@@ -2112,14 +2246,6 @@
"facet": "collectionItem.unenclosed.iteration",
"code": "for key, value in map.items():\n pass",
"scopes": [
- {
- "targets": [
- {
- "content": "0:0-0:30"
- }
- ],
- "domain": "0:0-0:30"
- },
{
"targets": [
{
diff --git a/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/CollectionItemScopeHandler/CollectionItemCompoundScopeHandler.ts b/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/CollectionItemScopeHandler/CollectionItemCompoundScopeHandler.ts
new file mode 100644
index 00000000000..60c05f13440
--- /dev/null
+++ b/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/CollectionItemScopeHandler/CollectionItemCompoundScopeHandler.ts
@@ -0,0 +1,59 @@
+import type { Direction, Position } from "@cursorless/lib-common";
+import { ensureSingleTarget } from "../../../../util/targetUtils";
+import type { TargetScope } from "../scope.types";
+import type { CustomScopeType } from "../scopeHandler.types";
+import { SortedScopeHandler } from "../SortedScopeHandler";
+
+export class CollectionItemCompoundScopeHandler extends SortedScopeHandler {
+ private isIterator: boolean = false;
+
+ get iterationScopeType(): CustomScopeType {
+ if (this.iterationScopeHandler == null) {
+ const iterationScopeHandlers = this.scopeHandlers.map((s) =>
+ this.scopeHandlerFactory.create(s.iterationScopeType, this.languageId),
+ );
+ const iterationScopeHandler = new CollectionItemCompoundScopeHandler(
+ this.scopeHandlerFactory,
+ this.languageId,
+ iterationScopeHandlers,
+ );
+ iterationScopeHandler.isIterator = true;
+ this.iterationScopeHandler = iterationScopeHandler;
+ }
+ return {
+ type: "custom",
+ scopeHandler: this.iterationScopeHandler,
+ };
+ }
+
+ protected override compareScopes(
+ direction: Direction,
+ position: Position,
+ a: TargetScope,
+ b: TargetScope,
+ ): number {
+ if (!this.isIterator) {
+ return super.compareScopes(direction, position, a, b);
+ }
+
+ const intersection = a.domain.intersection(b.domain);
+
+ if (intersection == null || intersection.isEmpty) {
+ return super.compareScopes(direction, position, a, b);
+ }
+
+ const aIsLine = isLine(a);
+ const bIsLine = isLine(b);
+
+ // Prefer non-line targets over line targets
+ if (aIsLine !== bIsLine) {
+ return Number(aIsLine) - Number(bIsLine);
+ }
+
+ return super.compareScopes(direction, position, a, b);
+ }
+}
+
+function isLine(scope: TargetScope): boolean {
+ return ensureSingleTarget(scope.getTargets(false)).textualType === "line";
+}
diff --git a/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/CollectionItemScopeHandler/CollectionItemScopeHandler.ts b/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/CollectionItemScopeHandler/CollectionItemScopeHandler.ts
index c904cff8541..cdb95ec3cef 100644
--- a/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/CollectionItemScopeHandler/CollectionItemScopeHandler.ts
+++ b/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/CollectionItemScopeHandler/CollectionItemScopeHandler.ts
@@ -13,7 +13,7 @@ import type {
ScopeIteratorRequirements,
} from "../scopeHandler.types";
import type { ScopeHandlerFactory } from "../ScopeHandlerFactory";
-import { SortedScopeHandler } from "../SortedScopeHandler";
+import { CollectionItemCompoundScopeHandler } from "./CollectionItemCompoundScopeHandler";
import { CollectionItemTextualScopeHandler } from "./CollectionItemTextualScopeHandler";
export class CollectionItemScopeHandler extends BaseScopeHandler {
@@ -46,10 +46,11 @@ export class CollectionItemScopeHandler extends BaseScopeHandler {
return textualScopeHandler;
}
- return new SortedScopeHandler(scopeHandlerFactory, languageId, [
- languageScopeHandler,
- textualScopeHandler,
- ]);
+ return new CollectionItemCompoundScopeHandler(
+ scopeHandlerFactory,
+ languageId,
+ [languageScopeHandler, textualScopeHandler],
+ );
})();
}
diff --git a/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/CollectionItemScopeHandler/collectionItemTextualIterationScopeHandler.ts b/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/CollectionItemScopeHandler/collectionItemTextualIterationScopeHandler.ts
index 555a629de37..a1d1ddfbc7e 100644
--- a/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/CollectionItemScopeHandler/collectionItemTextualIterationScopeHandler.ts
+++ b/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/CollectionItemScopeHandler/collectionItemTextualIterationScopeHandler.ts
@@ -1,8 +1,8 @@
import { testRegex } from "@cursorless/lib-common";
-import type { ComplexScopeType } from "../scopeHandler.types";
+import type { FallbackScopeType } from "../scopeHandler.types";
import { separatorRegex } from "./getSeparatorOccurrences";
-export const collectionItemTextualIterationScopeHandler: ComplexScopeType = {
+export const collectionItemTextualIterationScopeHandler: FallbackScopeType = {
type: "fallback",
scopeTypes: [
{
diff --git a/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/SortedScopeHandler.ts b/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/SortedScopeHandler.ts
index 028368d204e..b257fe4e21f 100644
--- a/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/SortedScopeHandler.ts
+++ b/packages/lib-engine/src/processTargets/modifiers/scopeHandlers/SortedScopeHandler.ts
@@ -14,7 +14,7 @@ import type { ScopeHandlerFactory } from "./ScopeHandlerFactory";
export class SortedScopeHandler extends BaseScopeHandler {
protected isHierarchical = true;
public scopeType = undefined;
- private iterationScopeHandler: SortedScopeHandler | undefined;
+ protected iterationScopeHandler: SortedScopeHandler | undefined;
private lastYieldedIndex: number | undefined;
static maybeCreate(
@@ -46,9 +46,9 @@ export class SortedScopeHandler extends BaseScopeHandler {
}
constructor(
- private scopeHandlerFactory: ScopeHandlerFactory,
- private languageId: string,
- private scopeHandlers: ScopeHandler[],
+ protected scopeHandlerFactory: ScopeHandlerFactory,
+ protected languageId: string,
+ protected scopeHandlers: ScopeHandler[],
) {
super();
}
@@ -98,7 +98,7 @@ export class SortedScopeHandler extends BaseScopeHandler {
while (iteratorInfos.length > 0) {
iteratorInfos.sort((a, b) =>
- compareTargetScopes(direction, position, a.value, b.value),
+ this.compareScopes(direction, position, a.value, b.value),
);
// Pick minimum scope according to canonical scope ordering
@@ -112,8 +112,17 @@ export class SortedScopeHandler extends BaseScopeHandler {
iteratorInfos = advanceIteratorsUntil(
iteratorInfos,
(scope) =>
- compareTargetScopes(direction, position, currentScope, scope) < 0,
+ this.compareScopes(direction, position, currentScope, scope) < 0,
);
}
}
+
+ protected compareScopes(
+ direction: Direction,
+ position: Position,
+ a: TargetScope,
+ b: TargetScope,
+ ): number {
+ return compareTargetScopes(direction, position, a, b);
+ }
}
diff --git a/resources/fixtures/recorded/modifiers/everyScope/changeEveryItem.yml b/resources/fixtures/recorded/modifiers/everyScope/changeEveryItem.yml
new file mode 100644
index 00000000000..1a0f88a857f
--- /dev/null
+++ b/resources/fixtures/recorded/modifiers/everyScope/changeEveryItem.yml
@@ -0,0 +1,31 @@
+languageId: java
+command:
+ version: 7
+ spokenForm: change every item
+ action:
+ name: clearAndSetSelection
+ target:
+ type: primitive
+ modifiers:
+ - type: everyScope
+ scopeType: {type: collectionItem}
+ usePrePhraseSnapshot: false
+initialState:
+ documentContents: |-
+ sealed interface Foo
+ permits Bar,
+ Baz {}
+ selections:
+ - anchor: {line: 1, character: 14}
+ active: {line: 1, character: 14}
+ marks: {}
+finalState:
+ documentContents: |-
+ sealed interface Foo
+ permits ,
+ {}
+ selections:
+ - anchor: {line: 1, character: 12}
+ active: {line: 1, character: 12}
+ - anchor: {line: 2, character: 4}
+ active: {line: 2, character: 4}
diff --git a/resources/fixtures/scopes/csharp/collectionItem.unenclosed.iteration2.scope b/resources/fixtures/scopes/csharp/collectionItem.unenclosed.iteration2.scope
index 531c2a98647..68f7087baae 100644
--- a/resources/fixtures/scopes/csharp/collectionItem.unenclosed.iteration2.scope
+++ b/resources/fixtures/scopes/csharp/collectionItem.unenclosed.iteration2.scope
@@ -15,19 +15,10 @@ class Foo {
<
-[#2 Content] = 1:4-1:25
- >---------------------<
-1| private int bar, baz;
-
-[#2 Domain] = 1:0-1:25
- >-------------------------<
-1| private int bar, baz;
-
-
-[#3 Content] = 1:16-1:24
+[#2 Content] = 1:16-1:24
>--------<
1| private int bar, baz;
-[#3 Domain] = 1:4-1:25
+[#2 Domain] = 1:4-1:25
>---------------------<
1| private int bar, baz;
diff --git a/resources/fixtures/scopes/go/collectionItem.unenclosed.iteration.scope b/resources/fixtures/scopes/go/collectionItem.unenclosed.iteration.scope
index dfd6e14f6c2..367bc50efe2 100644
--- a/resources/fixtures/scopes/go/collectionItem.unenclosed.iteration.scope
+++ b/resources/fixtures/scopes/go/collectionItem.unenclosed.iteration.scope
@@ -8,12 +8,6 @@ foo, bar := 1, 2
[#2 Content] =
-[#2 Domain] = 0:0-0:16
- >----------------<
-0| foo, bar := 1, 2
-
-
-[#3 Content] =
-[#3 Domain] = 0:12-0:16
+[#2 Domain] = 0:12-0:16
>----<
0| foo, bar := 1, 2
diff --git a/resources/fixtures/scopes/java/collectionItem.unenclosed.iteration.scope b/resources/fixtures/scopes/java/collectionItem.unenclosed.iteration.scope
index b29f3941ca5..c04adac099d 100644
--- a/resources/fixtures/scopes/java/collectionItem.unenclosed.iteration.scope
+++ b/resources/fixtures/scopes/java/collectionItem.unenclosed.iteration.scope
@@ -15,19 +15,10 @@ public class Foo {
<
-[#2 Content] = 1:4-1:17
- >-------------<
-1| int aaa, bbb;
-
-[#2 Domain] = 1:0-1:17
- >-----------------<
-1| int aaa, bbb;
-
-
-[#3 Content] = 1:8-1:16
+[#2 Content] = 1:8-1:16
>--------<
1| int aaa, bbb;
-[#3 Domain] = 1:4-1:17
+[#2 Domain] = 1:4-1:17
>-------------<
1| int aaa, bbb;
diff --git a/resources/fixtures/scopes/java/collectionItem.unenclosed.iteration2.scope b/resources/fixtures/scopes/java/collectionItem.unenclosed.iteration2.scope
index c03d91de48b..b6e0bd39021 100644
--- a/resources/fixtures/scopes/java/collectionItem.unenclosed.iteration2.scope
+++ b/resources/fixtures/scopes/java/collectionItem.unenclosed.iteration2.scope
@@ -34,19 +34,10 @@ class Foo {
----<
-[#3 Content] = 2:8-2:21
- >-------------<
-2| int aaa, bbb;
-
-[#3 Domain] = 2:0-2:21
- >---------------------<
-2| int aaa, bbb;
-
-
-[#4 Content] = 2:12-2:20
+[#3 Content] = 2:12-2:20
>--------<
2| int aaa, bbb;
-[#4 Domain] = 2:8-2:21
+[#3 Domain] = 2:8-2:21
>-------------<
2| int aaa, bbb;
diff --git a/resources/fixtures/scopes/java/collectionItem.unenclosed.iteration3.scope b/resources/fixtures/scopes/java/collectionItem.unenclosed.iteration3.scope
index 9f5f3c49580..3339e8e8233 100644
--- a/resources/fixtures/scopes/java/collectionItem.unenclosed.iteration3.scope
+++ b/resources/fixtures/scopes/java/collectionItem.unenclosed.iteration3.scope
@@ -15,19 +15,10 @@ class Foo {
<
-[#2 Content] = 1:4-1:47
- >-------------------------------------------<
-1| void bar() throws AException, BException {}
-
-[#2 Domain] = 1:0-1:47
- >-----------------------------------------------<
-1| void bar() throws AException, BException {}
-
-
-[#3 Content] = 1:22-1:44
+[#2 Content] = 1:22-1:44
>----------------------<
1| void bar() throws AException, BException {}
-[#3 Domain] = 1:15-1:44
+[#2 Domain] = 1:15-1:44
>-----------------------------<
1| void bar() throws AException, BException {}
diff --git a/resources/fixtures/scopes/java/collectionItem.unenclosed.iteration4.scope b/resources/fixtures/scopes/java/collectionItem.unenclosed.iteration4.scope
new file mode 100644
index 00000000000..b39f3b0cf96
--- /dev/null
+++ b/resources/fixtures/scopes/java/collectionItem.unenclosed.iteration4.scope
@@ -0,0 +1,10 @@
+sealed class Foo implements Bar, Baz {}
+---
+
+[Content] = 0:28-0:36
+ >--------<
+0| sealed class Foo implements Bar, Baz {}
+
+[Domain] = 0:17-0:36
+ >-------------------<
+0| sealed class Foo implements Bar, Baz {}
diff --git a/resources/fixtures/scopes/java/collectionItem.unenclosed.iteration5.scope b/resources/fixtures/scopes/java/collectionItem.unenclosed.iteration5.scope
new file mode 100644
index 00000000000..b595d5b96b3
--- /dev/null
+++ b/resources/fixtures/scopes/java/collectionItem.unenclosed.iteration5.scope
@@ -0,0 +1,10 @@
+sealed interface Foo permits Bar, Baz {}
+---
+
+[Content] = 0:29-0:37
+ >--------<
+0| sealed interface Foo permits Bar, Baz {}
+
+[Domain] = 0:21-0:37
+ >----------------<
+0| sealed interface Foo permits Bar, Baz {}
diff --git a/resources/fixtures/scopes/java/collectionItem.unenclosed.multiLine4.scope b/resources/fixtures/scopes/java/collectionItem.unenclosed.multiLine4.scope
new file mode 100644
index 00000000000..f2f77c2a7ef
--- /dev/null
+++ b/resources/fixtures/scopes/java/collectionItem.unenclosed.multiLine4.scope
@@ -0,0 +1,59 @@
+sealed class Foo
+ implements Bar,
+ Baz {}
+---
+
+[#1 Content] =
+[#1 Domain] = 1:4-1:18
+ >--------------<
+1| implements Bar,
+
+[#1 Removal] = 1:4-1:19
+ >---------------<
+1| implements Bar,
+
+[#1 Trailing delimiter] = 1:18-1:19
+ >-<
+1| implements Bar,
+
+[#1 Insertion delimiter] = ", "
+
+
+[#2 Content] =
+[#2 Domain] = 1:15-1:18
+ >---<
+1| implements Bar,
+
+[#2 Removal] = 1:15-2:4
+ >----
+1| implements Bar,
+2| Baz {}
+ ----<
+
+[#2 Trailing delimiter] = 1:18-2:4
+ >-
+1| implements Bar,
+2| Baz {}
+ ----<
+
+[#2 Insertion delimiter] = ",\n"
+
+
+[#3 Content] =
+[#3 Domain] = 2:4-2:7
+ >---<
+2| Baz {}
+
+[#3 Removal] = 1:18-2:7
+ >-
+1| implements Bar,
+2| Baz {}
+ -------<
+
+[#3 Leading delimiter] = 1:18-2:4
+ >-
+1| implements Bar,
+2| Baz {}
+ ----<
+
+[#3 Insertion delimiter] = ",\n"
diff --git a/resources/fixtures/scopes/java/collectionItem.unenclosed.multiLine5.scope b/resources/fixtures/scopes/java/collectionItem.unenclosed.multiLine5.scope
new file mode 100644
index 00000000000..dbf105f5893
--- /dev/null
+++ b/resources/fixtures/scopes/java/collectionItem.unenclosed.multiLine5.scope
@@ -0,0 +1,59 @@
+sealed interface Foo
+ permits Bar,
+ Baz {}
+---
+
+[#1 Content] =
+[#1 Domain] = 1:4-1:15
+ >-----------<
+1| permits Bar,
+
+[#1 Removal] = 1:4-1:16
+ >------------<
+1| permits Bar,
+
+[#1 Trailing delimiter] = 1:15-1:16
+ >-<
+1| permits Bar,
+
+[#1 Insertion delimiter] = ", "
+
+
+[#2 Content] =
+[#2 Domain] = 1:12-1:15
+ >---<
+1| permits Bar,
+
+[#2 Removal] = 1:12-2:4
+ >----
+1| permits Bar,
+2| Baz {}
+ ----<
+
+[#2 Trailing delimiter] = 1:15-2:4
+ >-
+1| permits Bar,
+2| Baz {}
+ ----<
+
+[#2 Insertion delimiter] = ",\n"
+
+
+[#3 Content] =
+[#3 Domain] = 2:4-2:7
+ >---<
+2| Baz {}
+
+[#3 Removal] = 1:15-2:7
+ >-
+1| permits Bar,
+2| Baz {}
+ -------<
+
+[#3 Leading delimiter] = 1:15-2:4
+ >-
+1| permits Bar,
+2| Baz {}
+ ----<
+
+[#3 Insertion delimiter] = ",\n"
diff --git a/resources/fixtures/scopes/java/collectionItem.unenclosed.singleLine4.scope b/resources/fixtures/scopes/java/collectionItem.unenclosed.singleLine4.scope
new file mode 100644
index 00000000000..b5c9394123d
--- /dev/null
+++ b/resources/fixtures/scopes/java/collectionItem.unenclosed.singleLine4.scope
@@ -0,0 +1,65 @@
+sealed class Foo implements Bar, Baz {}
+---
+
+[#1 Content] =
+[#1 Domain] = 0:0-0:31
+ >-------------------------------<
+0| sealed class Foo implements Bar, Baz {}
+
+[#1 Removal] = 0:0-0:33
+ >---------------------------------<
+0| sealed class Foo implements Bar, Baz {}
+
+[#1 Trailing delimiter] = 0:31-0:33
+ >--<
+0| sealed class Foo implements Bar, Baz {}
+
+[#1 Insertion delimiter] = ", "
+
+
+[#2 Content] =
+[#2 Domain] = 0:28-0:31
+ >---<
+0| sealed class Foo implements Bar, Baz {}
+
+[#2 Removal] = 0:28-0:33
+ >-----<
+0| sealed class Foo implements Bar, Baz {}
+
+[#2 Trailing delimiter] = 0:31-0:33
+ >--<
+0| sealed class Foo implements Bar, Baz {}
+
+[#2 Insertion delimiter] = ", "
+
+
+[#3 Content] =
+[#3 Domain] = 0:33-0:36
+ >---<
+0| sealed class Foo implements Bar, Baz {}
+
+[#3 Removal] = 0:31-0:36
+ >-----<
+0| sealed class Foo implements Bar, Baz {}
+
+[#3 Leading delimiter] = 0:31-0:33
+ >--<
+0| sealed class Foo implements Bar, Baz {}
+
+[#3 Insertion delimiter] = ", "
+
+
+[#4 Content] =
+[#4 Domain] = 0:33-0:39
+ >------<
+0| sealed class Foo implements Bar, Baz {}
+
+[#4 Removal] = 0:31-0:39
+ >--------<
+0| sealed class Foo implements Bar, Baz {}
+
+[#4 Leading delimiter] = 0:31-0:33
+ >--<
+0| sealed class Foo implements Bar, Baz {}
+
+[#4 Insertion delimiter] = ", "
diff --git a/resources/fixtures/scopes/java/collectionItem.unenclosed.singleLine5.scope b/resources/fixtures/scopes/java/collectionItem.unenclosed.singleLine5.scope
new file mode 100644
index 00000000000..27ed9c8f383
--- /dev/null
+++ b/resources/fixtures/scopes/java/collectionItem.unenclosed.singleLine5.scope
@@ -0,0 +1,65 @@
+sealed interface Foo permits Bar, Baz {}
+---
+
+[#1 Content] =
+[#1 Domain] = 0:0-0:32
+ >--------------------------------<
+0| sealed interface Foo permits Bar, Baz {}
+
+[#1 Removal] = 0:0-0:34
+ >----------------------------------<
+0| sealed interface Foo permits Bar, Baz {}
+
+[#1 Trailing delimiter] = 0:32-0:34
+ >--<
+0| sealed interface Foo permits Bar, Baz {}
+
+[#1 Insertion delimiter] = ", "
+
+
+[#2 Content] =
+[#2 Domain] = 0:29-0:32
+ >---<
+0| sealed interface Foo permits Bar, Baz {}
+
+[#2 Removal] = 0:29-0:34
+ >-----<
+0| sealed interface Foo permits Bar, Baz {}
+
+[#2 Trailing delimiter] = 0:32-0:34
+ >--<
+0| sealed interface Foo permits Bar, Baz {}
+
+[#2 Insertion delimiter] = ", "
+
+
+[#3 Content] =
+[#3 Domain] = 0:34-0:37
+ >---<
+0| sealed interface Foo permits Bar, Baz {}
+
+[#3 Removal] = 0:32-0:37
+ >-----<
+0| sealed interface Foo permits Bar, Baz {}
+
+[#3 Leading delimiter] = 0:32-0:34
+ >--<
+0| sealed interface Foo permits Bar, Baz {}
+
+[#3 Insertion delimiter] = ", "
+
+
+[#4 Content] =
+[#4 Domain] = 0:34-0:40
+ >------<
+0| sealed interface Foo permits Bar, Baz {}
+
+[#4 Removal] = 0:32-0:40
+ >--------<
+0| sealed interface Foo permits Bar, Baz {}
+
+[#4 Leading delimiter] = 0:32-0:34
+ >--<
+0| sealed interface Foo permits Bar, Baz {}
+
+[#4 Insertion delimiter] = ", "
diff --git a/resources/fixtures/scopes/lua/collectionItem.unenclosed.iteration.scope b/resources/fixtures/scopes/lua/collectionItem.unenclosed.iteration.scope
index f776cb2a9dd..6379864dd7f 100644
--- a/resources/fixtures/scopes/lua/collectionItem.unenclosed.iteration.scope
+++ b/resources/fixtures/scopes/lua/collectionItem.unenclosed.iteration.scope
@@ -2,18 +2,12 @@ local a, b, c = 1, 2, 3
---
[#1 Content] =
-[#1 Domain] = 0:0-0:23
- >-----------------------<
-0| local a, b, c = 1, 2, 3
-
-
-[#2 Content] =
-[#2 Domain] = 0:6-0:13
+[#1 Domain] = 0:6-0:13
>-------<
0| local a, b, c = 1, 2, 3
-[#3 Content] =
-[#3 Domain] = 0:16-0:23
+[#2 Content] =
+[#2 Domain] = 0:16-0:23
>-------<
0| local a, b, c = 1, 2, 3
diff --git a/resources/fixtures/scopes/python/collectionItem/collectionItem.unenclosed.iteration3.scope b/resources/fixtures/scopes/python/collectionItem/collectionItem.unenclosed.iteration3.scope
index dca32858f25..2752d9ca21c 100644
--- a/resources/fixtures/scopes/python/collectionItem/collectionItem.unenclosed.iteration3.scope
+++ b/resources/fixtures/scopes/python/collectionItem/collectionItem.unenclosed.iteration3.scope
@@ -2,19 +2,10 @@ def foo():
global bar, baz
---
-[#1 Content] = 1:4-1:19
- >---------------<
-1| global bar, baz
-
-[#1 Domain] = 1:0-1:19
- >-------------------<
-1| global bar, baz
-
-
-[#2 Content] = 1:11-1:19
+[Content] = 1:11-1:19
>--------<
1| global bar, baz
-[#2 Domain] = 1:4-1:19
+[Domain] = 1:4-1:19
>---------------<
1| global bar, baz
diff --git a/resources/fixtures/scopes/python/collectionItem/collectionItem.unenclosed.iteration4.scope b/resources/fixtures/scopes/python/collectionItem/collectionItem.unenclosed.iteration4.scope
index 465717220c1..16abf29cce4 100644
--- a/resources/fixtures/scopes/python/collectionItem/collectionItem.unenclosed.iteration4.scope
+++ b/resources/fixtures/scopes/python/collectionItem/collectionItem.unenclosed.iteration4.scope
@@ -2,13 +2,7 @@ for key, value in map.items():
pass
---
-[#1 Content] =
-[#1 Domain] = 0:0-0:30
- >------------------------------<
-0| for key, value in map.items():
-
-
-[#2 Content] =
-[#2 Domain] = 0:4-0:14
+[Content] =
+[Domain] = 0:4-0:14
>----------<
0| for key, value in map.items():
diff --git a/resources/queries/java.scm b/resources/queries/java.scm
index 46590c0cba8..df21527f476 100644
--- a/resources/queries/java.scm
+++ b/resources/queries/java.scm
@@ -521,6 +521,29 @@
.
) @collectionItem.iteration.domain
+;;!! class Foo implements Bar, Baz {}
+;;! ^^^ ^^^
+;;!! interface Foo permits Bar, Baz {}
+;;! ^^^ ^^^
+(_
+ (type_list
+ (_)? @_.leading.endOf
+ .
+ (_) @collectionItem
+ .
+ (_)? @_.trailing.startOf
+ ) @_dummy
+ (#single-or-multi-line-delimiter! @collectionItem @_dummy ", " ",\n")
+)
+
+;;!! class Foo implements Bar, Baz {}
+;;! ^^^^^^^^
+;;!! interface Foo permits Bar, Baz {}
+;;! ^^^^^^^^
+(_
+ (type_list) @collectionItem.iteration
+) @collectionItem.iteration.domain
+
;;!! value = 1;
;;! ^
;;! xxxx