diff --git a/cursorless-talon/src/modifiers/simple_scope_modifier.py b/cursorless-talon/src/modifiers/simple_scope_modifier.py index 46f04ff930..309919b729 100644 --- a/cursorless-talon/src/modifiers/simple_scope_modifier.py +++ b/cursorless-talon/src/modifiers/simple_scope_modifier.py @@ -24,7 +24,7 @@ @mod.capture( rule=( - "[{user.cursorless_every_scope_modifier} | {user.cursorless_ancestor_scope_modifier}] " + "[{user.cursorless_every_scope_modifier} | {user.cursorless_ancestor_scope_modifier}+] " "" ), ) @@ -40,7 +40,7 @@ def cursorless_simple_scope_modifier(m) -> dict[str, Any]: return { "type": "containingScope", "scopeType": m.cursorless_scope_type, - "ancestorIndex": 1, + "ancestorIndex": len(m.cursorless_ancestor_scope_modifier_list), } if settings.get("user.private_cursorless_use_preferred_scope"): diff --git a/data/fixtures/recorded/containingScope/changeGrandGrandState.yml b/data/fixtures/recorded/containingScope/changeGrandGrandState.yml new file mode 100644 index 0000000000..a773a552bc --- /dev/null +++ b/data/fixtures/recorded/containingScope/changeGrandGrandState.yml @@ -0,0 +1,29 @@ +languageId: javascript +command: + version: 7 + spokenForm: change grand grand state + action: + name: clearAndSetSelection + target: + type: primitive + modifiers: + - type: containingScope + scopeType: {type: statement} + ancestorIndex: 2 + usePrePhraseSnapshot: false +initialState: + documentContents: |- + class MyClass { + myFunk() { + console.log(""); + } + } + selections: + - anchor: {line: 2, character: 8} + active: {line: 2, character: 8} + marks: {} +finalState: + documentContents: "" + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} diff --git a/packages/cursorless-engine/src/generateSpokenForm/primitiveTargetToSpokenForm.ts b/packages/cursorless-engine/src/generateSpokenForm/primitiveTargetToSpokenForm.ts index ca22cfc0da..a2046e7838 100644 --- a/packages/cursorless-engine/src/generateSpokenForm/primitiveTargetToSpokenForm.ts +++ b/packages/cursorless-engine/src/generateSpokenForm/primitiveTargetToSpokenForm.ts @@ -52,15 +52,12 @@ export class PrimitiveTargetSpokenFormGenerator { if (modifier.ancestorIndex == null || modifier.ancestorIndex === 0) { return this.handleScopeType(modifier.scopeType); } - if (modifier.ancestorIndex === 1) { - return [ + return [ + new Array(modifier.ancestorIndex).fill( this.spokenFormMap.modifierExtra.ancestor, - this.handleScopeType(modifier.scopeType), - ]; - } - throw new NoSpokenFormError( - `Modifier '${modifier.type}' with ancestor index ${modifier.ancestorIndex}`, - ); + ), + this.handleScopeType(modifier.scopeType), + ]; case "everyScope": return [ diff --git a/packages/cursorless-org-docs/src/docs/user/README.md b/packages/cursorless-org-docs/src/docs/user/README.md index a6b43c6a45..89be87f7d5 100644 --- a/packages/cursorless-org-docs/src/docs/user/README.md +++ b/packages/cursorless-org-docs/src/docs/user/README.md @@ -233,7 +233,11 @@ The modifier `"grand"` can be used to select the parent of the containing syntac - `"take grand statement air"` - `"take grand funk air"` -For example, the command `"take grand statement [blue] air"` will select that parent statement of the statement containing the token with a blue hat over the letter 'a'. +For example, the command `"take grand statement [blue] air"` will select the parent statement of the statement containing the token with a blue hat over the letter 'a'. + +You can also repeat `"grand"` multiple times. + +For example, the command `"take grand grand statement [blue] air"` will select the parent statement of the parent statement of the statement containing the token with a blue hat over the letter 'a'. ##### Sub-token modifiers