diff --git a/package.json b/package.json index 7c7c34000d..7b02b4fb56 100644 --- a/package.json +++ b/package.json @@ -546,6 +546,7 @@ "@types/vscode": "~1.61.0", "@typescript-eslint/eslint-plugin": "^5.20.0", "@typescript-eslint/parser": "^5.20.0", + "@vscode/test-electron": "^2.1.3", "esbuild": "^0.11.12", "eslint": "^8.13.0", "eslint-config-prettier": "^8.5.0", @@ -558,8 +559,7 @@ "semver": "^7.3.7", "sinon": "^11.1.1", "ts-unused-exports": "8.0.0", - "typescript": "^4.5.5", - "@vscode/test-electron": "^2.1.3" + "typescript": "^4.5.5" }, "dependencies": { "@types/lodash": "^4.14.168", diff --git a/src/actions/EditNew/EditNew.ts b/src/actions/EditNew/EditNew.ts index 7ffa466f9e..d26ff28720 100644 --- a/src/actions/EditNew/EditNew.ts +++ b/src/actions/EditNew/EditNew.ts @@ -1,4 +1,4 @@ -import { weakContainingLineStage } from "../../processTargets/modifiers/commonWeakContainingScopeStages"; +import { containingLineIfUntypedStage } from "../../processTargets/modifiers/commonContainingScopeIfUntypedStages"; import PositionStage from "../../processTargets/modifiers/PositionStage"; import { ModifierStage } from "../../processTargets/PipelineStages.types"; import { Target } from "../../typings/target.types"; @@ -14,7 +14,7 @@ import { runEditTargets } from "./runEditTargets"; export class EditNew implements Action { getFinalStages(): ModifierStage[] { - return [weakContainingLineStage]; + return [containingLineIfUntypedStage]; } constructor(private graph: Graph) { diff --git a/src/actions/InsertCopy.ts b/src/actions/InsertCopy.ts index 4e0e518449..be66b88a2a 100644 --- a/src/actions/InsertCopy.ts +++ b/src/actions/InsertCopy.ts @@ -1,7 +1,7 @@ import { flatten, zip } from "lodash"; import { DecorationRangeBehavior, Selection, TextEditor } from "vscode"; import { performEditsAndUpdateSelectionsWithBehavior } from "../core/updateSelections/updateSelections"; -import { weakContainingLineStage } from "../processTargets/modifiers/commonWeakContainingScopeStages"; +import { containingLineIfUntypedStage } from "../processTargets/modifiers/commonContainingScopeIfUntypedStages"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; import { setSelectionsWithoutFocusingEditor } from "../util/setSelectionsAndFocusEditor"; @@ -9,7 +9,7 @@ import { createThatMark, runOnTargetsForEachEditor } from "../util/targetUtils"; import { Action, ActionReturnValue } from "./actions.types"; class InsertCopy implements Action { - getFinalStages = () => [weakContainingLineStage]; + getFinalStages = () => [containingLineIfUntypedStage]; constructor(private graph: Graph, private isBefore: boolean) { this.run = this.run.bind(this); diff --git a/src/actions/InsertSnippet.ts b/src/actions/InsertSnippet.ts index b3fa8886db..d9d157624c 100644 --- a/src/actions/InsertSnippet.ts +++ b/src/actions/InsertSnippet.ts @@ -4,7 +4,7 @@ import { callFunctionAndUpdateSelectionInfos, getSelectionInfo, } from "../core/updateSelections/updateSelections"; -import ModifyIfWeakStage from "../processTargets/modifiers/ModifyIfWeakStage"; +import ModifyIfUntypedStage from "../processTargets/modifiers/ModifyIfUntypedStage"; import { Snippet, SnippetDefinition } from "../typings/snippet"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; @@ -29,8 +29,8 @@ export default class InsertSnippet implements Action { } return [ - new ModifyIfWeakStage({ - type: "modifyIfWeak", + new ModifyIfUntypedStage({ + type: "modifyIfUntyped", modifier: { type: "cascading", modifiers: defaultScopeTypes.map((scopeType) => ({ diff --git a/src/actions/Rewrap.ts b/src/actions/Rewrap.ts index 8146b04f88..e27f1a8bb2 100644 --- a/src/actions/Rewrap.ts +++ b/src/actions/Rewrap.ts @@ -1,12 +1,12 @@ import { performEditsAndUpdateRanges } from "../core/updateSelections/updateSelections"; -import { weakContainingSurroundingPairStage } from "../processTargets/modifiers/commonWeakContainingScopeStages"; +import { containingSurroundingPairIfUntypedStage } from "../processTargets/modifiers/commonContainingScopeIfUntypedStages"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; import { createThatMark, runOnTargetsForEachEditor } from "../util/targetUtils"; import { Action, ActionReturnValue } from "./actions.types"; export default class Rewrap implements Action { - getFinalStages = () => [weakContainingSurroundingPairStage]; + getFinalStages = () => [containingSurroundingPairIfUntypedStage]; constructor(private graph: Graph) { this.run = this.run.bind(this); diff --git a/src/actions/ToggleBreakpoint.ts b/src/actions/ToggleBreakpoint.ts index 1261a82bac..fca47a8a7c 100644 --- a/src/actions/ToggleBreakpoint.ts +++ b/src/actions/ToggleBreakpoint.ts @@ -6,7 +6,7 @@ import { SourceBreakpoint, Uri, } from "vscode"; -import { weakContainingLineStage } from "../processTargets/modifiers/commonWeakContainingScopeStages"; +import { containingLineIfUntypedStage } from "../processTargets/modifiers/commonContainingScopeIfUntypedStages"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; import { createThatMark } from "../util/targetUtils"; @@ -22,7 +22,7 @@ function getBreakpoints(uri: Uri, range: Range) { } export default class ToggleBreakpoint implements Action { - getFinalStages = () => [weakContainingLineStage]; + getFinalStages = () => [containingLineIfUntypedStage]; constructor(private graph: Graph) { this.run = this.run.bind(this); diff --git a/src/actions/WrapWithSnippet.ts b/src/actions/WrapWithSnippet.ts index 52a0c4ba64..03e63877f9 100644 --- a/src/actions/WrapWithSnippet.ts +++ b/src/actions/WrapWithSnippet.ts @@ -1,6 +1,6 @@ import { commands } from "vscode"; import { callFunctionAndUpdateSelections } from "../core/updateSelections/updateSelections"; -import ModifyIfWeakStage from "../processTargets/modifiers/ModifyIfWeakStage"; +import ModifyIfUntypedStage from "../processTargets/modifiers/ModifyIfUntypedStage"; import { Target } from "../typings/target.types"; import { Graph } from "../typings/Types"; import { @@ -28,8 +28,8 @@ export default class WrapWithSnippet implements Action { } return [ - new ModifyIfWeakStage({ - type: "modifyIfWeak", + new ModifyIfUntypedStage({ + type: "modifyIfUntyped", modifier: { type: "containingScope", scopeType: { diff --git a/src/processTargets/getMarkStage.ts b/src/processTargets/getMarkStage.ts index 400cd5595c..5339542be7 100644 --- a/src/processTargets/getMarkStage.ts +++ b/src/processTargets/getMarkStage.ts @@ -3,8 +3,7 @@ import CursorStage from "./marks/CursorStage"; import DecoratedSymbolStage from "./marks/DecoratedSymbolStage"; import LineNumberStage from "./marks/LineNumberStage"; import NothingStage from "./marks/NothingStage"; -import SourceStage from "./marks/SourceStage"; -import ThatStage from "./marks/ThatStage"; +import { SourceStage, ThatStage } from "./marks/ThatStage"; import { MarkStage } from "./PipelineStages.types"; export default (mark: Mark): MarkStage => { diff --git a/src/processTargets/getModifierStage.ts b/src/processTargets/getModifierStage.ts index b7af447cbb..5e3f3aac73 100644 --- a/src/processTargets/getModifierStage.ts +++ b/src/processTargets/getModifierStage.ts @@ -12,7 +12,7 @@ import { } from "./modifiers/InteriorStage"; import ItemStage from "./modifiers/ItemStage"; import { LeadingStage, TrailingStage } from "./modifiers/LeadingTrailingStages"; -import ModifyIfWeakStage from "./modifiers/ModifyIfWeakStage"; +import ModifyIfUntypedStage from "./modifiers/ModifyIfUntypedStage"; import OrdinalRangeSubTokenStage, { OrdinalRangeSubTokenModifier, } from "./modifiers/OrdinalRangeSubTokenStage"; @@ -70,8 +70,8 @@ export default (modifier: Modifier): ModifierStage => { ); case "cascading": return new CascadingStage(modifier); - case "modifyIfWeak": - return new ModifyIfWeakStage(modifier); + case "modifyIfUntyped": + return new ModifyIfUntypedStage(modifier); } }; diff --git a/src/processTargets/marks/CursorStage.ts b/src/processTargets/marks/CursorStage.ts index 11f797bb5e..25c9996a6a 100644 --- a/src/processTargets/marks/CursorStage.ts +++ b/src/processTargets/marks/CursorStage.ts @@ -3,24 +3,20 @@ import type { CursorMark } from "../../typings/targetDescriptor.types"; import { ProcessedTargetsContext } from "../../typings/Types"; import { isReversed } from "../../util/selectionUtils"; import { MarkStage } from "../PipelineStages.types"; -import WeakTarget from "../targets/WeakTarget"; -import TokenTarget from "../targets/TokenTarget"; +import UntypedTarget from "../targets/UntypedTarget"; export default class CursorStage implements MarkStage { - constructor(_modifier: CursorMark) { - // takes mark for consistency and does nothing - } + constructor(private modifier: CursorMark) {} run(context: ProcessedTargetsContext): Target[] { - return context.currentSelections.map((selection) => { - const parameters = { - editor: selection.editor, - isReversed: isReversed(selection.selection), - contentRange: selection.selection, - }; - return selection.selection.isEmpty - ? new WeakTarget(parameters) - : new TokenTarget(parameters); - }); + return context.currentSelections.map( + (selection) => + new UntypedTarget({ + editor: selection.editor, + isReversed: isReversed(selection.selection), + contentRange: selection.selection, + hasExplicitRange: !selection.selection.isEmpty, + }) + ); } } diff --git a/src/processTargets/marks/DecoratedSymbolStage.ts b/src/processTargets/marks/DecoratedSymbolStage.ts index 59b25dacd6..171a6bd180 100644 --- a/src/processTargets/marks/DecoratedSymbolStage.ts +++ b/src/processTargets/marks/DecoratedSymbolStage.ts @@ -2,7 +2,7 @@ import { Target } from "../../typings/target.types"; import { DecoratedSymbolMark } from "../../typings/targetDescriptor.types"; import { ProcessedTargetsContext } from "../../typings/Types"; import { MarkStage } from "../PipelineStages.types"; -import { WeakTarget } from "../targets"; +import { UntypedTarget } from "../targets"; export default class implements MarkStage { constructor(private modifier: DecoratedSymbolMark) {} @@ -20,10 +20,11 @@ export default class implements MarkStage { } return [ - new WeakTarget({ + new UntypedTarget({ editor: token.editor, contentRange: token.range, isReversed: false, + hasExplicitRange: false, }), ]; } diff --git a/src/processTargets/marks/SourceStage.ts b/src/processTargets/marks/SourceStage.ts deleted file mode 100644 index c57e4f0136..0000000000 --- a/src/processTargets/marks/SourceStage.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Target } from "../../typings/target.types"; -import { SourceMark } from "../../typings/targetDescriptor.types"; -import { ProcessedTargetsContext } from "../../typings/Types"; -import { isReversed } from "../../util/selectionUtils"; -import { MarkStage } from "../PipelineStages.types"; -import WeakTarget from "../targets/WeakTarget"; - -export default class implements MarkStage { - constructor(private modifier: SourceMark) {} - - run(context: ProcessedTargetsContext): Target[] { - if (context.sourceMark.length === 0) { - throw Error("No available source marks"); - } - return context.sourceMark.map((selection) => { - return new WeakTarget({ - editor: selection.editor, - isReversed: isReversed(selection.selection), - contentRange: selection.selection, - }); - }); - } -} diff --git a/src/processTargets/marks/ThatStage.ts b/src/processTargets/marks/ThatStage.ts index 0dbd05518f..11d6c80a6f 100644 --- a/src/processTargets/marks/ThatStage.ts +++ b/src/processTargets/marks/ThatStage.ts @@ -1,23 +1,45 @@ import { Target } from "../../typings/target.types"; -import { ThatMark } from "../../typings/targetDescriptor.types"; -import { ProcessedTargetsContext } from "../../typings/Types"; +import { SourceMark, ThatMark } from "../../typings/targetDescriptor.types"; +import { + ProcessedTargetsContext, + SelectionWithEditor, +} from "../../typings/Types"; import { isReversed } from "../../util/selectionUtils"; import { MarkStage } from "../PipelineStages.types"; -import WeakTarget from "../targets/WeakTarget"; +import { UntypedTarget } from "../targets"; -export default class implements MarkStage { +export class ThatStage implements MarkStage { constructor(private modifier: ThatMark) {} run(context: ProcessedTargetsContext): Target[] { if (context.thatMark.length === 0) { throw Error("No available that marks"); } - return context.thatMark.map((selection) => { - return new WeakTarget({ + + return selectionsToTarget(context.thatMark); + } +} + +export class SourceStage implements MarkStage { + constructor(private modifier: SourceMark) {} + + run(context: ProcessedTargetsContext): Target[] { + if (context.sourceMark.length === 0) { + throw Error("No available source marks"); + } + + return selectionsToTarget(context.sourceMark); + } +} + +function selectionsToTarget(selections: SelectionWithEditor[]) { + return selections.map( + (selection) => + new UntypedTarget({ editor: selection.editor, isReversed: isReversed(selection.selection), contentRange: selection.selection, - }); - }); - } + hasExplicitRange: !selection.selection.isEmpty, + }) + ); } diff --git a/src/processTargets/modifiers/InteriorStage.ts b/src/processTargets/modifiers/InteriorStage.ts index 2905b7fec3..305849fcb3 100644 --- a/src/processTargets/modifiers/InteriorStage.ts +++ b/src/processTargets/modifiers/InteriorStage.ts @@ -5,13 +5,13 @@ import { } from "../../typings/targetDescriptor.types"; import { ProcessedTargetsContext } from "../../typings/Types"; import { ModifierStage } from "../PipelineStages.types"; -import { weakContainingSurroundingPairStage } from "./commonWeakContainingScopeStages"; +import { containingSurroundingPairIfUntypedStage } from "./commonContainingScopeIfUntypedStages"; export class InteriorOnlyStage implements ModifierStage { constructor(private modifier: InteriorOnlyModifier) {} run(context: ProcessedTargetsContext, target: Target): Target[] { - return weakContainingSurroundingPairStage + return containingSurroundingPairIfUntypedStage .run(context, target) .flatMap((target) => target.getInteriorStrict()); } @@ -21,7 +21,7 @@ export class ExcludeInteriorStage implements ModifierStage { constructor(private modifier: ExcludeInteriorModifier) {} run(context: ProcessedTargetsContext, target: Target): Target[] { - return weakContainingSurroundingPairStage + return containingSurroundingPairIfUntypedStage .run(context, target) .flatMap((target) => target.getBoundaryStrict()); } diff --git a/src/processTargets/modifiers/ItemStage/ItemStage.ts b/src/processTargets/modifiers/ItemStage/ItemStage.ts index d20252f96e..884ae7f04c 100644 --- a/src/processTargets/modifiers/ItemStage/ItemStage.ts +++ b/src/processTargets/modifiers/ItemStage/ItemStage.ts @@ -40,10 +40,10 @@ export default class ItemStage implements ModifierStage { private getEveryTarget(context: ProcessedTargetsContext, target: Target) { const itemInfos = getItemInfosForIterationScope(context, target); - // If weak expand to all items in iteration scope - const filteredItemInfos = target.isWeak - ? itemInfos - : filterItemInfos(target, itemInfos); + // If target has explicit range filter to items in that range. Otherwise expand to all items in iteration scope. + const filteredItemInfos = target.hasExplicitRange + ? filterItemInfos(target, itemInfos) + : itemInfos; if (filteredItemInfos.length === 0) { throw new NoContainingScopeError(this.modifier.scopeType.type); diff --git a/src/processTargets/modifiers/LeadingTrailingStages.ts b/src/processTargets/modifiers/LeadingTrailingStages.ts index 961b1088ff..e70b7de7cf 100644 --- a/src/processTargets/modifiers/LeadingTrailingStages.ts +++ b/src/processTargets/modifiers/LeadingTrailingStages.ts @@ -5,16 +5,27 @@ import { } from "../../typings/targetDescriptor.types"; import { ProcessedTargetsContext } from "../../typings/Types"; import { ModifierStage } from "../PipelineStages.types"; -import { weakContainingTokenStage } from "./commonWeakContainingScopeStages"; +import { containingTokenIfUntypedStage } from "./commonContainingScopeIfUntypedStages"; + +/** + * Throw this error if user has requested leading or trailing delimiter but no + * such delimiter exists on the given target. + */ +class NoDelimiterError extends Error { + constructor(type: "leading" | "trailing") { + super(`Target has no ${type} delimiter.`); + this.name = "NoDelimiterError"; + } +} export class LeadingStage implements ModifierStage { constructor(private modifier: LeadingModifier) {} run(context: ProcessedTargetsContext, target: Target): Target[] { - return weakContainingTokenStage.run(context, target).map((target) => { + return containingTokenIfUntypedStage.run(context, target).map((target) => { const leading = target.getLeadingDelimiterTarget(); if (leading == null) { - throw Error("No available leading delimiter range"); + throw new NoDelimiterError("leading"); } return leading; }); @@ -25,10 +36,10 @@ export class TrailingStage implements ModifierStage { constructor(private modifier: TrailingModifier) {} run(context: ProcessedTargetsContext, target: Target): Target[] { - return weakContainingTokenStage.run(context, target).map((target) => { + return containingTokenIfUntypedStage.run(context, target).map((target) => { const trailing = target.getTrailingDelimiterTarget(); if (trailing == null) { - throw Error("No available trailing delimiter range"); + throw new NoDelimiterError("trailing"); } return trailing; }); diff --git a/src/processTargets/modifiers/ModifyIfUntypedStage.ts b/src/processTargets/modifiers/ModifyIfUntypedStage.ts new file mode 100644 index 0000000000..5350dc535c --- /dev/null +++ b/src/processTargets/modifiers/ModifyIfUntypedStage.ts @@ -0,0 +1,38 @@ +import { Target } from "../../typings/target.types"; +import { ModifyIfUntypedModifier } from "../../typings/targetDescriptor.types"; +import { ProcessedTargetsContext } from "../../typings/Types"; +import getModifierStage from "../getModifierStage"; +import { ModifierStage } from "../PipelineStages.types"; + +/** + * Runs {@link ModifyIfUntypedModifier.modifier} if the target has no explicit + * scope type, ie if {@link Target.hasExplicitScopeType} is `false`. + */ +export default class ModifyIfUntypedStage implements ModifierStage { + private nestedStage_?: ModifierStage; + + constructor(private modifier: ModifyIfUntypedModifier) {} + + run(context: ProcessedTargetsContext, target: Target): Target[] { + // If true this target has an explicit scope type and should not be modified. + if (target.hasExplicitScopeType) { + return [target]; + } + + /** + * This target is lacking an explicit scope type and should use inference/upgrade when needed. + * See {@link Target.hasExplicitScopeType} for more info + */ + return this.nestedStage + .run(context, target) + .map((newTarget) => newTarget.withThatTarget(target)); + } + + private get nestedStage() { + if (this.nestedStage_ == null) { + this.nestedStage_ = getModifierStage(this.modifier.modifier); + } + + return this.nestedStage_; + } +} diff --git a/src/processTargets/modifiers/ModifyIfWeakStage.ts b/src/processTargets/modifiers/ModifyIfWeakStage.ts deleted file mode 100644 index 0ff66d834f..0000000000 --- a/src/processTargets/modifiers/ModifyIfWeakStage.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Target } from "../../typings/target.types"; -import { ModifyIfWeakModifier } from "../../typings/targetDescriptor.types"; -import { ProcessedTargetsContext } from "../../typings/Types"; -import getModifierStage from "../getModifierStage"; -import { ModifierStage } from "../PipelineStages.types"; - -/** - * Runs {@link ModifyIfWeakModifier.modifier} if the target is weak. - */ -export default class ModifyIfWeakStage implements ModifierStage { - private nestedStage_?: ModifierStage; - - constructor(private modifier: ModifyIfWeakModifier) {} - - private get nestedStage() { - if (this.nestedStage_ == null) { - this.nestedStage_ = getModifierStage(this.modifier.modifier); - } - - return this.nestedStage_; - } - - run(context: ProcessedTargetsContext, target: Target): Target[] { - /** If true this target is of weak type and should use inference/upgrade when needed. See {@link WeakTarget} for more info */ - if (target.isWeak) { - return this.nestedStage - .run(context, target) - .map((newTarget) => newTarget.withThatTarget(target)); - } - return [target]; - } -} diff --git a/src/processTargets/modifiers/OrdinalRangeSubTokenStage.ts b/src/processTargets/modifiers/OrdinalRangeSubTokenStage.ts index ac1d14855b..438a4c52a7 100644 --- a/src/processTargets/modifiers/OrdinalRangeSubTokenStage.ts +++ b/src/processTargets/modifiers/OrdinalRangeSubTokenStage.ts @@ -25,9 +25,10 @@ export default class OrdinalRangeSubTokenStage implements ModifierStage { run(context: ProcessedTargetsContext, target: Target): Target[] { const { editor } = target; - const tokenContentRange = target.contentRange.isEmpty - ? getTokenRangeForSelection(target.editor, target.contentRange) - : target.contentRange; + // If the target has an explicit range use that. Otherwise expand to the token. + const tokenContentRange = target.hasExplicitRange + ? target.contentRange + : getTokenRangeForSelection(target.editor, target.contentRange); const tokenText = editor.document.getText(tokenContentRange); let pieces: { start: number; end: number }[] = []; diff --git a/src/processTargets/modifiers/commonContainingScopeIfUntypedStages.ts b/src/processTargets/modifiers/commonContainingScopeIfUntypedStages.ts new file mode 100644 index 0000000000..6575f35488 --- /dev/null +++ b/src/processTargets/modifiers/commonContainingScopeIfUntypedStages.ts @@ -0,0 +1,47 @@ +import ModifyIfUntypedStage from "./ModifyIfUntypedStage"; +// NB: We import `Target` below just so that @link below resolves. Once one of +// the following issues are fixed, we can either remove the above line or +// switch to `{import("foo")}` syntax in the `{@link}` tag. +// - https://github.com/microsoft/TypeScript/issues/43869 +// - https://github.com/microsoft/TypeScript/issues/43950 +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import type { Target } from "../../typings/target.types"; + +/** + * Expands the given target to the nearest containing surrounding pair if the + * target has no explicit scope type, ie if {@link Target.hasExplicitScopeType} + * is `false`. + */ +export const containingSurroundingPairIfUntypedStage = new ModifyIfUntypedStage( + { + type: "modifyIfUntyped", + modifier: { + type: "containingScope", + scopeType: { type: "surroundingPair", delimiter: "any" }, + }, + } +); + +/** + * Expands the given target to the nearest containing line if the target has no + * explicit scope type, ie if {@link Target.hasExplicitScopeType} is `false`. + */ +export const containingLineIfUntypedStage = new ModifyIfUntypedStage({ + type: "modifyIfUntyped", + modifier: { + type: "containingScope", + scopeType: { type: "line" }, + }, +}); + +/** + * Expands the given target to the nearest containing token if the target has no + * explicit scope type, ie if {@link Target.hasExplicitScopeType} is `false`. + */ +export const containingTokenIfUntypedStage = new ModifyIfUntypedStage({ + type: "modifyIfUntyped", + modifier: { + type: "containingScope", + scopeType: { type: "token" }, + }, +}); diff --git a/src/processTargets/modifiers/commonWeakContainingScopeStages.ts b/src/processTargets/modifiers/commonWeakContainingScopeStages.ts deleted file mode 100644 index 487d76dd08..0000000000 --- a/src/processTargets/modifiers/commonWeakContainingScopeStages.ts +++ /dev/null @@ -1,25 +0,0 @@ -import ModifyIfWeakStage from "./ModifyIfWeakStage"; - -export const weakContainingSurroundingPairStage = new ModifyIfWeakStage({ - type: "modifyIfWeak", - modifier: { - type: "containingScope", - scopeType: { type: "surroundingPair", delimiter: "any" }, - }, -}); - -export const weakContainingLineStage = new ModifyIfWeakStage({ - type: "modifyIfWeak", - modifier: { - type: "containingScope", - scopeType: { type: "line" }, - }, -}); - -export const weakContainingTokenStage = new ModifyIfWeakStage({ - type: "modifyIfWeak", - modifier: { - type: "containingScope", - scopeType: { type: "token" }, - }, -}); diff --git a/src/processTargets/modifiers/scopeTypeStages/LineStage.ts b/src/processTargets/modifiers/scopeTypeStages/LineStage.ts index 66f8389f68..1f0383a452 100644 --- a/src/processTargets/modifiers/scopeTypeStages/LineStage.ts +++ b/src/processTargets/modifiers/scopeTypeStages/LineStage.ts @@ -20,11 +20,10 @@ export default class implements ModifierStage { private getEveryTarget(target: Target): LineTarget[] { const { contentRange, editor } = target; - const { isEmpty } = contentRange; - const startLine = isEmpty ? 0 : contentRange.start.line; - const endLine = isEmpty - ? editor.document.lineCount - 1 - : contentRange.end.line; + const startLine = target.hasExplicitRange ? contentRange.start.line : 0; + const endLine = target.hasExplicitRange + ? contentRange.end.line + : editor.document.lineCount - 1; const targets: LineTarget[] = []; for (let i = startLine; i <= endLine; ++i) { diff --git a/src/processTargets/modifiers/scopeTypeStages/ParagraphStage.ts b/src/processTargets/modifiers/scopeTypeStages/ParagraphStage.ts index 2b6e2ede0b..47f1bc8e8f 100644 --- a/src/processTargets/modifiers/scopeTypeStages/ParagraphStage.ts +++ b/src/processTargets/modifiers/scopeTypeStages/ParagraphStage.ts @@ -21,10 +21,11 @@ export default class implements ModifierStage { private getEveryTarget(target: Target): ParagraphTarget[] { const { contentRange, editor } = target; - const { isEmpty } = contentRange; const { lineCount } = editor.document; - const startLine = isEmpty ? 0 : contentRange.start.line; - const endLine = isEmpty ? lineCount - 1 : contentRange.end.line; + const startLine = target.hasExplicitRange ? contentRange.start.line : 0; + const endLine = target.hasExplicitRange + ? contentRange.end.line + : lineCount - 1; const targets: ParagraphTarget[] = []; let paragraphStart = -1; @@ -51,6 +52,8 @@ export default class implements ModifierStage { possiblyAddParagraph(paragraphStart, i - 1); paragraphStart = -1; } + // NB: Ignore empty line if paragraphStart === -1 because it means it's + // just an extra empty line between blocks } // Start of paragraph else if (paragraphStart < 0) { diff --git a/src/processTargets/modifiers/scopeTypeStages/RegexStage.ts b/src/processTargets/modifiers/scopeTypeStages/RegexStage.ts index 794daefc79..a7bed8f4f7 100644 --- a/src/processTargets/modifiers/scopeTypeStages/RegexStage.ts +++ b/src/processTargets/modifiers/scopeTypeStages/RegexStage.ts @@ -26,13 +26,12 @@ class RegexStage implements ModifierStage { private getEveryTarget(target: Target): ScopeTypeTarget[] { const { contentRange, editor } = target; - const { isEmpty } = contentRange; - const start = isEmpty - ? editor.document.lineAt(contentRange.start).range.start - : contentRange.start; - const end = isEmpty - ? editor.document.lineAt(contentRange.end).range.end - : contentRange.end; + const start = target.hasExplicitRange + ? contentRange.start + : editor.document.lineAt(contentRange.start).range.start; + const end = target.hasExplicitRange + ? contentRange.end + : editor.document.lineAt(contentRange.end).range.end; const targets: ScopeTypeTarget[] = []; for (let i = start.line; i <= end.line; ++i) { diff --git a/src/processTargets/modifiers/scopeTypeStages/TokenStage.ts b/src/processTargets/modifiers/scopeTypeStages/TokenStage.ts index 46efcf60e8..f791e0f65c 100644 --- a/src/processTargets/modifiers/scopeTypeStages/TokenStage.ts +++ b/src/processTargets/modifiers/scopeTypeStages/TokenStage.ts @@ -24,13 +24,12 @@ export default class implements ModifierStage { target: Target ): TokenTarget[] { const { contentRange, editor } = target; - const { isEmpty } = contentRange; - const start = isEmpty - ? editor.document.lineAt(contentRange.start).range.start - : contentRange.start; - const end = isEmpty - ? editor.document.lineAt(contentRange.end).range.end - : contentRange.end; + const start = target.hasExplicitRange + ? contentRange.start + : editor.document.lineAt(contentRange.start).range.start; + const end = target.hasExplicitRange + ? contentRange.end + : editor.document.lineAt(contentRange.end).range.end; const range = new Range(start, end); const targets = getTokensInRange(editor, range).map(({ range }) => diff --git a/src/processTargets/targetUtil/createContinuousRange.ts b/src/processTargets/targetUtil/createContinuousRange.ts index 001282db93..8ac6c2249b 100644 --- a/src/processTargets/targetUtil/createContinuousRange.ts +++ b/src/processTargets/targetUtil/createContinuousRange.ts @@ -1,6 +1,6 @@ import { Position, Range } from "vscode"; import { Target } from "../../typings/target.types"; -import WeakTarget from "../targets/WeakTarget"; +import UntypedTarget from "../targets/UntypedTarget"; export function createContinuousRange( startTarget: Target, @@ -67,16 +67,17 @@ export function createSimpleContinuousRangeTarget( ); } -export function createContinuousRangeWeakTarget( +export function createContinuousRangeUntypedTarget( isReversed: boolean, startTarget: Target, endTarget: Target, includeStart: boolean, includeEnd: boolean -): WeakTarget { - return new WeakTarget({ +): UntypedTarget { + return new UntypedTarget({ editor: startTarget.editor, isReversed, + hasExplicitRange: true, contentRange: createContinuousRange( startTarget, endTarget, diff --git a/src/processTargets/targets/BaseTarget.ts b/src/processTargets/targets/BaseTarget.ts index 60a98e74ff..263c192719 100644 --- a/src/processTargets/targets/BaseTarget.ts +++ b/src/processTargets/targets/BaseTarget.ts @@ -1,5 +1,6 @@ import { isEqual } from "lodash"; import { Range, Selection, TextEditor } from "vscode"; +import { NoContainingScopeError } from "../../errors"; import { EditNewContext, Target } from "../../typings/target.types"; import { Position } from "../../typings/targetDescriptor.types"; import { EditWithRangeUpdater } from "../../typings/Types"; @@ -8,7 +9,7 @@ import { isSameType } from "../../util/typeUtils"; import { toPositionTarget } from "../modifiers/toPositionTarget"; import { createContinuousRange, - createContinuousRangeWeakTarget, + createContinuousRangeUntypedTarget, } from "../targetUtil/createContinuousRange"; /** Parameters supported by most target classes */ @@ -27,7 +28,8 @@ export interface CloneWithParameters { export default abstract class BaseTarget implements Target { protected readonly state: CommonTargetParameters; isLine = false; - isWeak = false; + hasExplicitScopeType = true; + hasExplicitRange = true; isRaw = false; isNotebookCell = false; @@ -100,10 +102,10 @@ export default abstract class BaseTarget implements Target { } getInteriorStrict(): Target[] { - throw Error("No available interior"); + throw new NoContainingScopeError("interior"); } getBoundaryStrict(): Target[] { - throw Error("No available boundaries"); + throw new NoContainingScopeError("boundary"); } readonly cloneWith = (parameters: CloneWithParameters) => { @@ -138,7 +140,7 @@ export default abstract class BaseTarget implements Target { }); } - return createContinuousRangeWeakTarget( + return createContinuousRangeUntypedTarget( isReversed, this, endTarget, diff --git a/src/processTargets/targets/UntypedTarget.ts b/src/processTargets/targets/UntypedTarget.ts new file mode 100644 index 0000000000..3a1459d465 --- /dev/null +++ b/src/processTargets/targets/UntypedTarget.ts @@ -0,0 +1,63 @@ +import { Range } from "vscode"; +import { BaseTarget, CommonTargetParameters } from "."; +import { Target } from "../../typings/target.types"; +import { createContinuousRangeUntypedTarget } from "../targetUtil/createContinuousRange"; +import { + getTokenLeadingDelimiterTarget, + getTokenRemovalRange, + getTokenTrailingDelimiterTarget, +} from "../targetUtil/insertionRemovalBehaviors/TokenInsertionRemovalBehavior"; + +interface UntypedTargetParameters extends CommonTargetParameters { + readonly hasExplicitRange: boolean; +} + +/** + * - Treated as "line" for "pour", "clone", and "breakpoint" + * - Use token delimiters (space) for removal and insertion + * - Expand to nearest containing pair when asked for boundary or interior + */ +export default class UntypedTarget extends BaseTarget { + insertionDelimiter = " "; + hasExplicitScopeType = false; + + constructor(parameters: UntypedTargetParameters) { + super(parameters); + this.hasExplicitRange = parameters.hasExplicitRange; + } + + getLeadingDelimiterTarget(): Target | undefined { + return getTokenLeadingDelimiterTarget(this); + } + getTrailingDelimiterTarget(): Target | undefined { + return getTokenTrailingDelimiterTarget(this); + } + getRemovalRange(): Range { + // If this range is in the middle of a whitespace sequence we don't want to remove leading or trailing whitespaces. + return this.editor.document.getText(this.contentRange).trim().length === 0 + ? this.contentRange + : getTokenRemovalRange(this); + } + + createContinuousRangeTarget( + isReversed: boolean, + endTarget: Target, + includeStart: boolean, + includeEnd: boolean + ): Target { + return createContinuousRangeUntypedTarget( + isReversed, + this, + endTarget, + includeStart, + includeEnd + ); + } + + protected getCloneParameters() { + return { + ...this.state, + hasExplicitRange: this.hasExplicitRange, + }; + } +} diff --git a/src/processTargets/targets/WeakTarget.ts b/src/processTargets/targets/WeakTarget.ts deleted file mode 100644 index 5c82fc252d..0000000000 --- a/src/processTargets/targets/WeakTarget.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Range } from "vscode"; -import { BaseTarget } from "."; -import { Target } from "../../typings/target.types"; -import { - getTokenLeadingDelimiterTarget, - getTokenRemovalRange, - getTokenTrailingDelimiterTarget, -} from "../targetUtil/insertionRemovalBehaviors/TokenInsertionRemovalBehavior"; - -/** - * - Treated as "line" for "pour", "clone", and "breakpoint" - * - Use token delimiters (space) for removal and insertion - * - Expand to nearest containing pair when asked for boundary or interior - */ -export default class WeakTarget extends BaseTarget { - insertionDelimiter = " "; - isWeak = true; - - getLeadingDelimiterTarget(): Target | undefined { - return getTokenLeadingDelimiterTarget(this); - } - getTrailingDelimiterTarget(): Target | undefined { - return getTokenTrailingDelimiterTarget(this); - } - getRemovalRange(): Range { - return getTokenRemovalRange(this); - } - - protected getCloneParameters() { - return this.state; - } -} diff --git a/src/processTargets/targets/index.ts b/src/processTargets/targets/index.ts index b0e1cccf83..cf7bf14ba7 100644 --- a/src/processTargets/targets/index.ts +++ b/src/processTargets/targets/index.ts @@ -22,5 +22,5 @@ export * from "./SurroundingPairTarget"; export { default as SurroundingPairTarget } from "./SurroundingPairTarget"; export * from "./TokenTarget"; export { default as TokenTarget } from "./TokenTarget"; -export * from "./WeakTarget"; -export { default as WeakTarget } from "./WeakTarget"; +export * from "./UntypedTarget"; +export { default as UntypedTarget } from "./UntypedTarget"; diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/chuckBoundingThat.yml b/src/test/suite/fixtures/recorded/implicitExpansion/chuckBoundingThat.yml new file mode 100644 index 0000000000..650dc92136 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/chuckBoundingThat.yml @@ -0,0 +1,31 @@ +languageId: plaintext +command: + spokenForm: chuck bounding that + version: 2 + targets: + - type: primitive + modifiers: + - {type: excludeInterior} + mark: {type: that} + usePrePhraseSnapshot: true + action: {name: remove} +initialState: + documentContents: (hello ) + selections: + - anchor: {line: 0, character: 8} + active: {line: 0, character: 8} + marks: {} + thatMark: + - anchor: {line: 0, character: 7} + active: {line: 0, character: 7} +finalState: + documentContents: hello + selections: + - anchor: {line: 0, character: 5} + active: {line: 0, character: 5} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 0, character: 5} + active: {line: 0, character: 5} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: [{type: excludeInterior}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/chuckCoreThat.yml b/src/test/suite/fixtures/recorded/implicitExpansion/chuckCoreThat.yml new file mode 100644 index 0000000000..51ceb3a109 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/chuckCoreThat.yml @@ -0,0 +1,29 @@ +languageId: plaintext +command: + spokenForm: chuck core that + version: 2 + targets: + - type: primitive + modifiers: + - {type: interiorOnly} + mark: {type: that} + usePrePhraseSnapshot: true + action: {name: remove} +initialState: + documentContents: (hello ) + selections: + - anchor: {line: 0, character: 8} + active: {line: 0, character: 8} + marks: {} + thatMark: + - anchor: {line: 0, character: 7} + active: {line: 0, character: 7} +finalState: + documentContents: () + selections: + - anchor: {line: 0, character: 2} + active: {line: 0, character: 2} + thatMark: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: [{type: interiorOnly}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/chuckLeadingThat.yml b/src/test/suite/fixtures/recorded/implicitExpansion/chuckLeadingThat.yml new file mode 100644 index 0000000000..ac7c865c97 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/chuckLeadingThat.yml @@ -0,0 +1,29 @@ +languageId: plaintext +command: + spokenForm: chuck leading that + version: 2 + targets: + - type: primitive + modifiers: + - {type: leading} + mark: {type: that} + usePrePhraseSnapshot: true + action: {name: remove} +initialState: + documentContents: " hello" + selections: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} + marks: {} + thatMark: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} +finalState: + documentContents: hello + selections: + - anchor: {line: 0, character: 5} + active: {line: 0, character: 5} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: [{type: leading}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/chuckSecondWordThat.yml b/src/test/suite/fixtures/recorded/implicitExpansion/chuckSecondWordThat.yml new file mode 100644 index 0000000000..c517db8054 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/chuckSecondWordThat.yml @@ -0,0 +1,34 @@ +languageId: plaintext +command: + spokenForm: chuck second word that + version: 2 + targets: + - type: primitive + modifiers: + - type: ordinalRange + scopeType: {type: word} + anchor: 1 + active: 1 + excludeAnchor: false + excludeActive: false + mark: {type: that} + usePrePhraseSnapshot: true + action: {name: remove} +initialState: + documentContents: helloWorld + selections: + - anchor: {line: 0, character: 10} + active: {line: 0, character: 10} + marks: {} + thatMark: + - anchor: {line: 0, character: 10} + active: {line: 0, character: 10} +finalState: + documentContents: hello + selections: + - anchor: {line: 0, character: 5} + active: {line: 0, character: 5} + thatMark: + - anchor: {line: 0, character: 5} + active: {line: 0, character: 5} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: [{type: ordinalRange, scopeType: {type: word}, anchor: 1, active: 1, excludeAnchor: false, excludeActive: false}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearBoundingThat.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearBoundingThat.yml new file mode 100644 index 0000000000..e0cdbc923c --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearBoundingThat.yml @@ -0,0 +1,35 @@ +languageId: plaintext +command: + spokenForm: clear bounding that + version: 2 + targets: + - type: primitive + modifiers: + - {type: excludeInterior} + mark: {type: that} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: | + (hello now) + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + marks: {} + thatMark: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 6} +finalState: + documentContents: | + hello now + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 0, character: 9} + active: {line: 0, character: 9} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 0, character: 9} + active: {line: 0, character: 9} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: [{type: excludeInterior}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearBounds.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearBounds.yml new file mode 100644 index 0000000000..1800c0e67f --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearBounds.yml @@ -0,0 +1,29 @@ +languageId: plaintext +command: + spokenForm: clear bounds + version: 2 + targets: + - type: primitive + modifiers: + - {type: excludeInterior} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: (aaa bbb) + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + marks: {} +finalState: + documentContents: aaa bbb + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 0, character: 7} + active: {line: 0, character: 7} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 0, character: 7} + active: {line: 0, character: 7} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: excludeInterior}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearBounds2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearBounds2.yml new file mode 100644 index 0000000000..2117c17e2e --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearBounds2.yml @@ -0,0 +1,29 @@ +languageId: plaintext +command: + spokenForm: clear bounds + version: 2 + targets: + - type: primitive + modifiers: + - {type: excludeInterior} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: (aaa bbb) + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 4} + marks: {} +finalState: + documentContents: aaa bbb + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 0, character: 7} + active: {line: 0, character: 7} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 0, character: 7} + active: {line: 0, character: 7} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: excludeInterior}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearBoundsAir.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearBoundsAir.yml new file mode 100644 index 0000000000..5601319881 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearBoundsAir.yml @@ -0,0 +1,33 @@ +languageId: plaintext +command: + spokenForm: clear bounds air + version: 2 + targets: + - type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: a} + modifiers: + - {type: excludeInterior} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: (aaa bbb) + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + marks: + default.a: + start: {line: 0, character: 1} + end: {line: 0, character: 4} +finalState: + documentContents: aaa bbb + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 0, character: 7} + active: {line: 0, character: 7} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 0, character: 7} + active: {line: 0, character: 7} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: a}, modifiers: [{type: excludeInterior}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearBoundsToken.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearBoundsToken.yml new file mode 100644 index 0000000000..f78fc8e88e --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearBoundsToken.yml @@ -0,0 +1,20 @@ +languageId: plaintext +command: + spokenForm: clear bounds token + version: 2 + targets: + - type: primitive + modifiers: + - {type: excludeInterior} + - type: containingScope + scopeType: {type: token} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: (aaa) + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + marks: {} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: excludeInterior}, {type: containingScope, scopeType: {type: token}}]}] +thrownError: {name: NoContainingScopeError} diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearCore.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearCore.yml new file mode 100644 index 0000000000..7a314261d0 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearCore.yml @@ -0,0 +1,25 @@ +languageId: plaintext +command: + spokenForm: clear core + version: 2 + targets: + - type: primitive + modifiers: + - {type: interiorOnly} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: (aaa bbb) + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + marks: {} +finalState: + documentContents: () + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + thatMark: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: interiorOnly}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearCore2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearCore2.yml new file mode 100644 index 0000000000..6d43a1cc39 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearCore2.yml @@ -0,0 +1,25 @@ +languageId: plaintext +command: + spokenForm: clear core + version: 2 + targets: + - type: primitive + modifiers: + - {type: interiorOnly} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: (aaa bbb) + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 4} + marks: {} +finalState: + documentContents: () + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + thatMark: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: interiorOnly}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearCoreAir.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearCoreAir.yml new file mode 100644 index 0000000000..6bec5760be --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearCoreAir.yml @@ -0,0 +1,29 @@ +languageId: plaintext +command: + spokenForm: clear core air + version: 2 + targets: + - type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: a} + modifiers: + - {type: interiorOnly} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: (aaa bbb) + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + marks: + default.a: + start: {line: 0, character: 1} + end: {line: 0, character: 4} +finalState: + documentContents: () + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + thatMark: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: a}, modifiers: [{type: interiorOnly}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearCoreThat.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearCoreThat.yml new file mode 100644 index 0000000000..a8aa2753e5 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearCoreThat.yml @@ -0,0 +1,31 @@ +languageId: plaintext +command: + spokenForm: clear core that + version: 2 + targets: + - type: primitive + modifiers: + - {type: interiorOnly} + mark: {type: that} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: | + (hello now) + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + marks: {} + thatMark: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 6} +finalState: + documentContents: | + () + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + thatMark: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: [{type: interiorOnly}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearCoreToken.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearCoreToken.yml new file mode 100644 index 0000000000..3a4abd07e2 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearCoreToken.yml @@ -0,0 +1,20 @@ +languageId: plaintext +command: + spokenForm: clear core token + version: 2 + targets: + - type: primitive + modifiers: + - {type: interiorOnly} + - type: containingScope + scopeType: {type: token} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: (aaa) + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + marks: {} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: interiorOnly}, {type: containingScope, scopeType: {type: token}}]}] +thrownError: {name: NoContainingScopeError} diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryItem.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryItem.yml new file mode 100644 index 0000000000..ce9d9a6c4a --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryItem.yml @@ -0,0 +1,38 @@ +languageId: plaintext +command: + spokenForm: clear every item + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: collectionItem} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: a, b, c, d + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: ", , , " + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 0, character: 2} + active: {line: 0, character: 2} + - anchor: {line: 0, character: 4} + active: {line: 0, character: 4} + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 0, character: 2} + active: {line: 0, character: 2} + - anchor: {line: 0, character: 4} + active: {line: 0, character: 4} + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: everyScope, scopeType: {type: collectionItem}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryItem2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryItem2.yml new file mode 100644 index 0000000000..3818b054fa --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryItem2.yml @@ -0,0 +1,30 @@ +languageId: plaintext +command: + spokenForm: clear every item + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: collectionItem} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: a, b, c, d + selections: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 7} + marks: {} +finalState: + documentContents: a, , , d + selections: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} + - anchor: {line: 0, character: 5} + active: {line: 0, character: 5} + thatMark: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} + - anchor: {line: 0, character: 5} + active: {line: 0, character: 5} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: everyScope, scopeType: {type: collectionItem}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryItemAir.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryItemAir.yml new file mode 100644 index 0000000000..673cb53653 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryItemAir.yml @@ -0,0 +1,42 @@ +languageId: plaintext +command: + spokenForm: clear every item air + version: 2 + targets: + - type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: a} + modifiers: + - type: everyScope + scopeType: {type: collectionItem} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: a, b, c, d + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: + default.a: + start: {line: 0, character: 0} + end: {line: 0, character: 1} +finalState: + documentContents: ", , , " + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 0, character: 2} + active: {line: 0, character: 2} + - anchor: {line: 0, character: 4} + active: {line: 0, character: 4} + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 0, character: 2} + active: {line: 0, character: 2} + - anchor: {line: 0, character: 4} + active: {line: 0, character: 4} + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: a}, modifiers: [{type: everyScope, scopeType: {type: collectionItem}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryLine.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryLine.yml new file mode 100644 index 0000000000..41bde0924c --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryLine.yml @@ -0,0 +1,45 @@ +languageId: plaintext +command: + spokenForm: clear every line + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: line} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: |- + a + b + c + d + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: |+ + + + + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + - anchor: {line: 2, character: 0} + active: {line: 2, character: 0} + - anchor: {line: 3, character: 0} + active: {line: 3, character: 0} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + - anchor: {line: 2, character: 0} + active: {line: 2, character: 0} + - anchor: {line: 3, character: 0} + active: {line: 3, character: 0} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: everyScope, scopeType: {type: line}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryLine2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryLine2.yml new file mode 100644 index 0000000000..dca343a4be --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryLine2.yml @@ -0,0 +1,38 @@ +languageId: plaintext +command: + spokenForm: clear every line + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: line} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: |- + a + b + c + d + selections: + - anchor: {line: 1, character: 0} + active: {line: 2, character: 1} + marks: {} +finalState: + documentContents: |- + a + + + d + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + - anchor: {line: 2, character: 0} + active: {line: 2, character: 0} + thatMark: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + - anchor: {line: 2, character: 0} + active: {line: 2, character: 0} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: everyScope, scopeType: {type: line}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryLineAir.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryLineAir.yml new file mode 100644 index 0000000000..7ad8033073 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryLineAir.yml @@ -0,0 +1,49 @@ +languageId: plaintext +command: + spokenForm: clear every line air + version: 2 + targets: + - type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: a} + modifiers: + - type: everyScope + scopeType: {type: line} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: |- + a + b + c + d + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: + default.a: + start: {line: 0, character: 0} + end: {line: 0, character: 1} +finalState: + documentContents: |+ + + + + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + - anchor: {line: 2, character: 0} + active: {line: 2, character: 0} + - anchor: {line: 3, character: 0} + active: {line: 3, character: 0} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + - anchor: {line: 2, character: 0} + active: {line: 2, character: 0} + - anchor: {line: 3, character: 0} + active: {line: 3, character: 0} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: a}, modifiers: [{type: everyScope, scopeType: {type: line}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryLineFunk.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryLineFunk.yml new file mode 100644 index 0000000000..3fb15ddc2a --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryLineFunk.yml @@ -0,0 +1,44 @@ +languageId: typescript +command: + spokenForm: clear every line funk + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: line} + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: | + + function myFunk() { + // aaa + } + selections: + - anchor: {line: 2, character: 5} + active: {line: 2, character: 5} + marks: {} +finalState: + documentContents: |2+ + + + + + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + - anchor: {line: 2, character: 2} + active: {line: 2, character: 2} + - anchor: {line: 3, character: 0} + active: {line: 3, character: 0} + thatMark: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + - anchor: {line: 2, character: 2} + active: {line: 2, character: 2} + - anchor: {line: 3, character: 0} + active: {line: 3, character: 0} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: everyScope, scopeType: {type: line}}, {type: containingScope, scopeType: {type: namedFunction}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryLineThat.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryLineThat.yml new file mode 100644 index 0000000000..c3b5b4036f --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryLineThat.yml @@ -0,0 +1,37 @@ +languageId: plaintext +command: + spokenForm: clear every line that + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: line} + mark: {type: that} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: |- + hello + whatever + selections: + - anchor: {line: 1, character: 8} + active: {line: 1, character: 8} + marks: {} + thatMark: + - anchor: {line: 0, character: 5} + active: {line: 0, character: 5} +finalState: + documentContents: |+ + + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: [{type: everyScope, scopeType: {type: line}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryLineThat2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryLineThat2.yml new file mode 100644 index 0000000000..88a4d265d5 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearEveryLineThat2.yml @@ -0,0 +1,42 @@ +languageId: plaintext +command: + spokenForm: clear every line that + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: line} + mark: {type: that} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: |- + hello + world + testing + again + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} + thatMark: + - anchor: {line: 1, character: 0} + active: {line: 2, character: 7} +finalState: + documentContents: |- + hello + + + again + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + - anchor: {line: 2, character: 0} + active: {line: 2, character: 0} + thatMark: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + - anchor: {line: 2, character: 0} + active: {line: 2, character: 0} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: [{type: everyScope, scopeType: {type: line}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearFirstCarSecondWordHarp.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearFirstCarSecondWordHarp.yml new file mode 100644 index 0000000000..42b1655fea --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearFirstCarSecondWordHarp.yml @@ -0,0 +1,40 @@ +languageId: plaintext +command: + spokenForm: clear first car second word harp + version: 2 + targets: + - type: primitive + modifiers: + - type: ordinalRange + scopeType: {type: character} + anchor: 0 + active: 0 + excludeAnchor: false + excludeActive: false + - type: ordinalRange + scopeType: {type: word} + anchor: 1 + active: 1 + excludeAnchor: false + excludeActive: false + mark: {type: decoratedSymbol, symbolColor: default, character: h} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: helloWorld + selections: + - anchor: {line: 0, character: 10} + active: {line: 0, character: 10} + marks: + default.h: + start: {line: 0, character: 0} + end: {line: 0, character: 10} +finalState: + documentContents: helloorld + selections: + - anchor: {line: 0, character: 5} + active: {line: 0, character: 5} + thatMark: + - anchor: {line: 0, character: 5} + active: {line: 0, character: 5} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: h}, modifiers: [{type: ordinalRange, scopeType: {type: character}, anchor: 0, active: 0, excludeAnchor: false, excludeActive: false}, {type: ordinalRange, scopeType: {type: word}, anchor: 1, active: 1, excludeAnchor: false, excludeActive: false}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearFirstWordPastTrap.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearFirstWordPastTrap.yml new file mode 100644 index 0000000000..971ff86461 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearFirstWordPastTrap.yml @@ -0,0 +1,42 @@ +languageId: plaintext +command: + spokenForm: clear first word past trap + version: 2 + targets: + - type: range + anchor: + type: primitive + modifiers: + - type: ordinalRange + scopeType: {type: word} + anchor: 0 + active: 0 + excludeAnchor: false + excludeActive: false + active: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: t} + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: |- + helloWorld + testingThere + selections: + - anchor: {line: 0, character: 7} + active: {line: 0, character: 7} + marks: + default.t: + start: {line: 1, character: 0} + end: {line: 1, character: 12} +finalState: + documentContents: There + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} +fullTargets: [{type: range, excludeAnchor: false, excludeActive: false, rangeType: continuous, anchor: {type: primitive, mark: {type: cursor}, modifiers: [&ref_0 {type: ordinalRange, scopeType: {type: word}, anchor: 0, active: 0, excludeAnchor: false, excludeActive: false}]}, active: {type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: t}, modifiers: [*ref_0]}}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearFirstWordThat.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearFirstWordThat.yml new file mode 100644 index 0000000000..9a9913a1b0 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearFirstWordThat.yml @@ -0,0 +1,36 @@ +languageId: plaintext +command: + spokenForm: clear first word that + version: 2 + targets: + - type: primitive + modifiers: + - type: ordinalRange + scopeType: {type: word} + anchor: 0 + active: 0 + excludeAnchor: false + excludeActive: false + mark: {type: that} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: | + helloWorld now + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + marks: {} + thatMark: + - anchor: {line: 0, character: 5} + active: {line: 0, character: 10} +finalState: + documentContents: | + hello now + selections: + - anchor: {line: 0, character: 5} + active: {line: 0, character: 5} + thatMark: + - anchor: {line: 0, character: 5} + active: {line: 0, character: 5} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: [{type: ordinalRange, scopeType: {type: word}, anchor: 0, active: 0, excludeAnchor: false, excludeActive: false}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearLeadingPastWhale.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearLeadingPastWhale.yml new file mode 100644 index 0000000000..9ff34f5c53 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearLeadingPastWhale.yml @@ -0,0 +1,37 @@ +languageId: plaintext +command: + spokenForm: clear leading past whale + version: 2 + targets: + - type: range + anchor: + type: primitive + modifiers: + - {type: leading} + active: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: w} + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: |2- + hello + world + selections: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} + marks: + default.w: + start: {line: 1, character: 1} + end: {line: 1, character: 6} +finalState: + documentContents: world + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} +fullTargets: [{type: range, excludeAnchor: false, excludeActive: false, rangeType: continuous, anchor: {type: primitive, mark: {type: cursor}, modifiers: [{type: leading}]}, active: {type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: w}, modifiers: [{type: leading}]}}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearLeadingSecondWord.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearLeadingSecondWord.yml new file mode 100644 index 0000000000..a8f80b63c2 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearLeadingSecondWord.yml @@ -0,0 +1,24 @@ +languageId: plaintext +command: + spokenForm: clear leading second word + version: 2 + targets: + - type: primitive + modifiers: + - {type: leading} + - type: ordinalRange + scopeType: {type: word} + anchor: 1 + active: 1 + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: helloWorld + selections: + - anchor: {line: 0, character: 10} + active: {line: 0, character: 10} + marks: {} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: leading}, {type: ordinalRange, scopeType: {type: word}, anchor: 1, active: 1, excludeAnchor: false, excludeActive: false}]}] +thrownError: {name: NoDelimiterError} diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearSecondWord.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearSecondWord.yml new file mode 100644 index 0000000000..b1650a3bbc --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearSecondWord.yml @@ -0,0 +1,30 @@ +languageId: plaintext +command: + spokenForm: clear second word + version: 2 + targets: + - type: primitive + modifiers: + - type: ordinalRange + scopeType: {type: word} + anchor: 1 + active: 1 + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: aaaBbbCccDdd + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: aaaCccDdd + selections: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} + thatMark: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: ordinalRange, scopeType: {type: word}, anchor: 1, active: 1, excludeAnchor: false, excludeActive: false}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearSecondWord2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearSecondWord2.yml new file mode 100644 index 0000000000..4669ad4c40 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearSecondWord2.yml @@ -0,0 +1,30 @@ +languageId: plaintext +command: + spokenForm: clear second word + version: 2 + targets: + - type: primitive + modifiers: + - type: ordinalRange + scopeType: {type: word} + anchor: 1 + active: 1 + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: aaaBbbCccDdd + selections: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 9} + marks: {} +finalState: + documentContents: aaaBbbDdd + selections: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} + thatMark: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: ordinalRange, scopeType: {type: word}, anchor: 1, active: 1, excludeAnchor: false, excludeActive: false}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearSecondWordAir.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearSecondWordAir.yml new file mode 100644 index 0000000000..cc9d7e38b3 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearSecondWordAir.yml @@ -0,0 +1,34 @@ +languageId: plaintext +command: + spokenForm: clear second word air + version: 2 + targets: + - type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: a} + modifiers: + - type: ordinalRange + scopeType: {type: word} + anchor: 1 + active: 1 + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: aaaBbbCccDdd + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: + default.a: + start: {line: 0, character: 0} + end: {line: 0, character: 12} +finalState: + documentContents: aaaCccDdd + selections: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} + thatMark: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: a}, modifiers: [{type: ordinalRange, scopeType: {type: word}, anchor: 1, active: 1, excludeAnchor: false, excludeActive: false}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearTrailing.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearTrailing.yml new file mode 100644 index 0000000000..d4a98b8d5d --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearTrailing.yml @@ -0,0 +1,25 @@ +languageId: plaintext +command: + spokenForm: clear trailing + version: 2 + targets: + - type: primitive + modifiers: + - {type: trailing} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: aaa bbb + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: aaabbb + selections: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} + thatMark: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: trailing}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearTrailing2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearTrailing2.yml new file mode 100644 index 0000000000..671ba09ce1 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearTrailing2.yml @@ -0,0 +1,25 @@ +languageId: plaintext +command: + spokenForm: clear trailing + version: 2 + targets: + - type: primitive + modifiers: + - {type: trailing} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: aaa bbb + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 1} + marks: {} +finalState: + documentContents: aaabbb + selections: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} + thatMark: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: trailing}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearTrailingAir.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearTrailingAir.yml new file mode 100644 index 0000000000..1a02563e52 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearTrailingAir.yml @@ -0,0 +1,29 @@ +languageId: plaintext +command: + spokenForm: clear trailing air + version: 2 + targets: + - type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: a} + modifiers: + - {type: trailing} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: aaa bbb + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: + default.a: + start: {line: 0, character: 0} + end: {line: 0, character: 3} +finalState: + documentContents: aaabbb + selections: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} + thatMark: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: a}, modifiers: [{type: trailing}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearTrailingLine.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearTrailingLine.yml new file mode 100644 index 0000000000..8290c1f0fe --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearTrailingLine.yml @@ -0,0 +1,29 @@ +languageId: plaintext +command: + spokenForm: clear trailing line + version: 2 + targets: + - type: primitive + modifiers: + - {type: trailing} + - type: containingScope + scopeType: {type: line} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: |- + a b + c d + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: a bc d + selections: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} + thatMark: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: trailing}, {type: containingScope, scopeType: {type: line}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clearTrailingThat.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clearTrailingThat.yml new file mode 100644 index 0000000000..eff2e68b07 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clearTrailingThat.yml @@ -0,0 +1,31 @@ +languageId: plaintext +command: + spokenForm: clear trailing that + version: 2 + targets: + - type: primitive + modifiers: + - {type: trailing} + mark: {type: that} + usePrePhraseSnapshot: true + action: {name: clearAndSetSelection} +initialState: + documentContents: | + helloWorld now + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + marks: {} + thatMark: + - anchor: {line: 0, character: 10} + active: {line: 0, character: 10} +finalState: + documentContents: | + helloWorldnow + selections: + - anchor: {line: 0, character: 10} + active: {line: 0, character: 10} + thatMark: + - anchor: {line: 0, character: 10} + active: {line: 0, character: 10} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: [{type: trailing}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/cloneAir.yml b/src/test/suite/fixtures/recorded/implicitExpansion/cloneAir.yml new file mode 100644 index 0000000000..ff704bcae5 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/cloneAir.yml @@ -0,0 +1,32 @@ +languageId: plaintext +command: + spokenForm: clone air + version: 2 + targets: + - type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: a} + usePrePhraseSnapshot: true + action: {name: insertCopyAfter} +initialState: + documentContents: aaa bbb + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: + default.a: + start: {line: 0, character: 0} + end: {line: 0, character: 3} +finalState: + documentContents: |- + aaa bbb + aaa bbb + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + thatMark: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 7} + sourceMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 7} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: a}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/cloneFunk.yml b/src/test/suite/fixtures/recorded/implicitExpansion/cloneFunk.yml new file mode 100644 index 0000000000..88a6992e1e --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/cloneFunk.yml @@ -0,0 +1,39 @@ +languageId: typescript +command: + spokenForm: clone funk + version: 2 + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true + action: {name: insertCopyAfter} +initialState: + documentContents: |- + function myFunk() { + // aaa + } + selections: + - anchor: {line: 1, character: 5} + active: {line: 1, character: 5} + marks: {} +finalState: + documentContents: |- + function myFunk() { + // aaa + } + + function myFunk() { + // aaa + } + selections: + - anchor: {line: 5, character: 5} + active: {line: 5, character: 5} + thatMark: + - anchor: {line: 4, character: 0} + active: {line: 6, character: 1} + sourceMark: + - anchor: {line: 0, character: 0} + active: {line: 2, character: 1} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: containingScope, scopeType: {type: namedFunction}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/cloneNearPastWhale.yml b/src/test/suite/fixtures/recorded/implicitExpansion/cloneNearPastWhale.yml new file mode 100644 index 0000000000..5681cac0a3 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/cloneNearPastWhale.yml @@ -0,0 +1,48 @@ +languageId: plaintext +command: + spokenForm: clone near past whale + version: 2 + targets: + - type: range + anchor: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: 'n'} + active: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: w} + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: true + action: {name: insertCopyAfter} +initialState: + documentContents: |+ + hello now + whatever + + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: + default.n: + start: {line: 0, character: 6} + end: {line: 0, character: 9} + default.w: + start: {line: 1, character: 0} + end: {line: 1, character: 8} +finalState: + documentContents: |+ + hello now + whatever + hello now + whatever + + selections: + - anchor: {line: 2, character: 0} + active: {line: 2, character: 0} + thatMark: + - anchor: {line: 2, character: 0} + active: {line: 3, character: 8} + sourceMark: + - anchor: {line: 0, character: 0} + active: {line: 1, character: 8} +fullTargets: [{type: range, excludeAnchor: false, excludeActive: false, rangeType: continuous, anchor: {type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: 'n'}, modifiers: []}, active: {type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: w}, modifiers: []}}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/clonePastWhale.yml b/src/test/suite/fixtures/recorded/implicitExpansion/clonePastWhale.yml new file mode 100644 index 0000000000..f4f2573c95 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/clonePastWhale.yml @@ -0,0 +1,41 @@ +languageId: plaintext +command: + spokenForm: clone past whale + version: 2 + targets: + - type: range + anchor: {type: primitive} + active: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: w} + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: true + action: {name: insertCopyAfter} +initialState: + documentContents: |- + hello + world + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: + default.w: + start: {line: 1, character: 0} + end: {line: 1, character: 5} +finalState: + documentContents: |- + hello + world + hello + world + selections: + - anchor: {line: 2, character: 0} + active: {line: 2, character: 0} + thatMark: + - anchor: {line: 2, character: 0} + active: {line: 3, character: 5} + sourceMark: + - anchor: {line: 0, character: 0} + active: {line: 1, character: 5} +fullTargets: [{type: range, excludeAnchor: false, excludeActive: false, rangeType: continuous, anchor: {type: primitive, mark: {type: cursor}, modifiers: []}, active: {type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: w}, modifiers: []}}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/cloneThat.yml b/src/test/suite/fixtures/recorded/implicitExpansion/cloneThat.yml new file mode 100644 index 0000000000..732ee901f5 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/cloneThat.yml @@ -0,0 +1,33 @@ +languageId: plaintext +command: + spokenForm: clone that + version: 2 + targets: + - type: primitive + mark: {type: that} + usePrePhraseSnapshot: true + action: {name: insertCopyAfter} +initialState: + documentContents: | + hello world + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} + thatMark: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} +finalState: + documentContents: | + hello world + hello world + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + thatMark: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 11} + sourceMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 11} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/cloneThat2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/cloneThat2.yml new file mode 100644 index 0000000000..579c4018bf --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/cloneThat2.yml @@ -0,0 +1,35 @@ +languageId: plaintext +command: + spokenForm: clone that + version: 2 + targets: + - type: primitive + mark: {type: that} + usePrePhraseSnapshot: true + action: {name: insertCopyAfter} +initialState: + documentContents: |+ + hello world + + selections: + - anchor: {line: 2, character: 0} + active: {line: 2, character: 0} + marks: {} + thatMark: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 11} +finalState: + documentContents: |+ + hello world + hello world + + selections: + - anchor: {line: 3, character: 0} + active: {line: 3, character: 0} + thatMark: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 11} + sourceMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 11} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/cloneThis.yml b/src/test/suite/fixtures/recorded/implicitExpansion/cloneThis.yml new file mode 100644 index 0000000000..83169183fa --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/cloneThis.yml @@ -0,0 +1,29 @@ +languageId: plaintext +command: + spokenForm: clone this + version: 2 + targets: + - type: primitive + mark: {type: cursor} + usePrePhraseSnapshot: true + action: {name: insertCopyAfter} +initialState: + documentContents: aaa bbb + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: |- + aaa bbb + aaa bbb + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + thatMark: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 7} + sourceMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 7} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/cloneThis2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/cloneThis2.yml new file mode 100644 index 0000000000..200f2fe3e3 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/cloneThis2.yml @@ -0,0 +1,29 @@ +languageId: plaintext +command: + spokenForm: clone this + version: 2 + targets: + - type: primitive + mark: {type: cursor} + usePrePhraseSnapshot: true + action: {name: insertCopyAfter} +initialState: + documentContents: aaa bbb + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 3} + marks: {} +finalState: + documentContents: |- + aaa bbb + aaa bbb + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 3} + thatMark: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 7} + sourceMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 7} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapPastInk.yml b/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapPastInk.yml new file mode 100644 index 0000000000..75f8591004 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapPastInk.yml @@ -0,0 +1,40 @@ +languageId: typescript +command: + spokenForm: funk wrap past ink + version: 2 + targets: + - type: range + anchor: {type: primitive} + active: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: i} + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: true + action: + name: wrapWithSnippet + args: [functionDeclaration.body] +initialState: + documentContents: |- + const whatever = "hello"; + const testing = "hello"; + selections: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} + marks: + default.i: + start: {line: 1, character: 6} + end: {line: 1, character: 13} +finalState: + documentContents: |- + function () { + const whatever = "hello"; + const testing = "hello"; + } + selections: + - anchor: {line: 0, character: 9} + active: {line: 0, character: 9} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 3, character: 1} +fullTargets: [{type: range, excludeAnchor: false, excludeActive: false, rangeType: continuous, anchor: {type: primitive, mark: {type: cursor}, modifiers: []}, active: {type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: i}, modifiers: []}}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapThat.yml b/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapThat.yml new file mode 100644 index 0000000000..2736db11da --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapThat.yml @@ -0,0 +1,33 @@ +languageId: typescript +command: + spokenForm: funk wrap that + version: 2 + targets: + - type: primitive + mark: {type: that} + usePrePhraseSnapshot: true + action: + name: wrapWithSnippet + args: [functionDeclaration.body] +initialState: + documentContents: | + const whatever = "hello"; + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + marks: {} + thatMark: + - anchor: {line: 0, character: 23} + active: {line: 0, character: 23} +finalState: + documentContents: | + function () { + const whatever = "hello"; + } + selections: + - anchor: {line: 0, character: 9} + active: {line: 0, character: 9} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 2, character: 1} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapThat2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapThat2.yml new file mode 100644 index 0000000000..ac2ed985ac --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapThat2.yml @@ -0,0 +1,33 @@ +languageId: typescript +command: + spokenForm: funk wrap that + version: 2 + targets: + - type: primitive + mark: {type: that} + usePrePhraseSnapshot: true + action: + name: wrapWithSnippet + args: [functionDeclaration.body] +initialState: + documentContents: | + const whatever = "hello"; + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + marks: {} + thatMark: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 14} +finalState: + documentContents: | + function () { + const whatever = "hello"; + } + selections: + - anchor: {line: 0, character: 9} + active: {line: 0, character: 9} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 2, character: 1} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapThis.yml b/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapThis.yml new file mode 100644 index 0000000000..c1a69e3995 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapThis.yml @@ -0,0 +1,29 @@ +languageId: typescript +command: + spokenForm: funk wrap this + version: 2 + targets: + - type: primitive + mark: {type: cursor} + usePrePhraseSnapshot: true + action: + name: wrapWithSnippet + args: [functionDeclaration.body] +initialState: + documentContents: const whatever = "hello"; + selections: + - anchor: {line: 0, character: 24} + active: {line: 0, character: 24} + marks: {} +finalState: + documentContents: |- + function () { + const whatever = "hello"; + } + selections: + - anchor: {line: 0, character: 9} + active: {line: 0, character: 9} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 2, character: 1} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapThis2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapThis2.yml new file mode 100644 index 0000000000..54dfcd4f38 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapThis2.yml @@ -0,0 +1,29 @@ +languageId: typescript +command: + spokenForm: funk wrap this + version: 2 + targets: + - type: primitive + mark: {type: cursor} + usePrePhraseSnapshot: true + action: + name: wrapWithSnippet + args: [functionDeclaration.body] +initialState: + documentContents: const whatever = "hello"; + selections: + - anchor: {line: 0, character: 18} + active: {line: 0, character: 23} + marks: {} +finalState: + documentContents: |- + function () { + const whatever = "hello"; + } + selections: + - anchor: {line: 0, character: 9} + active: {line: 0, character: 9} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 2, character: 1} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapToken.yml b/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapToken.yml new file mode 100644 index 0000000000..3f075ce478 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapToken.yml @@ -0,0 +1,31 @@ +languageId: typescript +command: + spokenForm: funk wrap token + version: 2 + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: token} + usePrePhraseSnapshot: true + action: + name: wrapWithSnippet + args: [functionDeclaration.body] +initialState: + documentContents: const whatever = "hello"; + selections: + - anchor: {line: 0, character: 18} + active: {line: 0, character: 18} + marks: {} +finalState: + documentContents: |- + const whatever = "function () { + hello + }"; + selections: + - anchor: {line: 0, character: 27} + active: {line: 0, character: 27} + thatMark: + - anchor: {line: 0, character: 18} + active: {line: 2, character: 1} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: containingScope, scopeType: {type: token}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapWhale.yml b/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapWhale.yml new file mode 100644 index 0000000000..1617cc20aa --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapWhale.yml @@ -0,0 +1,33 @@ +languageId: typescript +command: + spokenForm: funk wrap whale + version: 2 + targets: + - type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: w} + usePrePhraseSnapshot: true + action: + name: wrapWithSnippet + args: [functionDeclaration.body] +initialState: + documentContents: | + const whatever = "hello"; + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + marks: + default.w: + start: {line: 0, character: 6} + end: {line: 0, character: 14} +finalState: + documentContents: | + function () { + const whatever = "hello"; + } + selections: + - anchor: {line: 0, character: 9} + active: {line: 0, character: 9} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 2, character: 1} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: w}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapWhalePastBat.yml b/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapWhalePastBat.yml new file mode 100644 index 0000000000..43875bcccd --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/funkWrapWhalePastBat.yml @@ -0,0 +1,45 @@ +languageId: typescript +command: + spokenForm: funk wrap whale past bat + version: 2 + targets: + - type: range + anchor: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: w} + active: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: b} + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: true + action: + name: wrapWithSnippet + args: [functionDeclaration.body] +initialState: + documentContents: | + const whatever = "hello"; + const bar = "hello"; + selections: + - anchor: {line: 2, character: 0} + active: {line: 2, character: 0} + marks: + default.w: + start: {line: 0, character: 6} + end: {line: 0, character: 14} + default.b: + start: {line: 1, character: 6} + end: {line: 1, character: 9} +finalState: + documentContents: | + function () { + const whatever = "hello"; + const bar = "hello"; + } + selections: + - anchor: {line: 0, character: 9} + active: {line: 0, character: 9} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 3, character: 1} +fullTargets: [{type: range, excludeAnchor: false, excludeActive: false, rangeType: continuous, anchor: {type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: w}, modifiers: []}, active: {type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: b}, modifiers: []}}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/pourAir.yml b/src/test/suite/fixtures/recorded/implicitExpansion/pourAir.yml new file mode 100644 index 0000000000..d462f9c2bf --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/pourAir.yml @@ -0,0 +1,28 @@ +languageId: plaintext +command: + spokenForm: pour air + version: 2 + targets: + - type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: a} + usePrePhraseSnapshot: true + action: {name: editNewLineAfter} +initialState: + documentContents: aaa bbb + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: + default.a: + start: {line: 0, character: 0} + end: {line: 0, character: 3} +finalState: + documentContents: | + aaa bbb + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 3} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: a}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/pourFunk.yml b/src/test/suite/fixtures/recorded/implicitExpansion/pourFunk.yml new file mode 100644 index 0000000000..660231e91a --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/pourFunk.yml @@ -0,0 +1,33 @@ +languageId: typescript +command: + spokenForm: pour funk + version: 2 + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true + action: {name: editNewLineAfter} +initialState: + documentContents: |- + function myFunk() { + // aaa + } + selections: + - anchor: {line: 1, character: 5} + active: {line: 1, character: 5} + marks: {} +finalState: + documentContents: |+ + function myFunk() { + // aaa + } + + selections: + - anchor: {line: 4, character: 0} + active: {line: 4, character: 0} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 2, character: 1} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: containingScope, scopeType: {type: namedFunction}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/pourNearPastWhale.yml b/src/test/suite/fixtures/recorded/implicitExpansion/pourNearPastWhale.yml new file mode 100644 index 0000000000..12104495a2 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/pourNearPastWhale.yml @@ -0,0 +1,42 @@ +languageId: plaintext +command: + spokenForm: pour near past whale + version: 2 + targets: + - type: range + anchor: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: 'n'} + active: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: w} + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: true + action: {name: editNewLineAfter} +initialState: + documentContents: | + hello now + whatever + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: + default.n: + start: {line: 0, character: 6} + end: {line: 0, character: 9} + default.w: + start: {line: 1, character: 0} + end: {line: 1, character: 8} +finalState: + documentContents: |+ + hello now + whatever + + selections: + - anchor: {line: 2, character: 0} + active: {line: 2, character: 0} + thatMark: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 9} +fullTargets: [{type: range, excludeAnchor: false, excludeActive: false, rangeType: continuous, anchor: {type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: 'n'}, modifiers: []}, active: {type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: w}, modifiers: []}}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/pourPastWhale.yml b/src/test/suite/fixtures/recorded/implicitExpansion/pourPastWhale.yml new file mode 100644 index 0000000000..2d4e174e74 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/pourPastWhale.yml @@ -0,0 +1,36 @@ +languageId: plaintext +command: + spokenForm: pour past whale + version: 2 + targets: + - type: range + anchor: {type: primitive} + active: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: w} + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: true + action: {name: editNewLineAfter} +initialState: + documentContents: |- + hello + world + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: + default.w: + start: {line: 1, character: 0} + end: {line: 1, character: 5} +finalState: + documentContents: | + hello + world + selections: + - anchor: {line: 2, character: 0} + active: {line: 2, character: 0} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} +fullTargets: [{type: range, excludeAnchor: false, excludeActive: false, rangeType: continuous, anchor: {type: primitive, mark: {type: cursor}, modifiers: []}, active: {type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: w}, modifiers: []}}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/pourThat.yml b/src/test/suite/fixtures/recorded/implicitExpansion/pourThat.yml new file mode 100644 index 0000000000..092a674134 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/pourThat.yml @@ -0,0 +1,32 @@ +languageId: plaintext +command: + spokenForm: pour that + version: 2 + targets: + - type: primitive + mark: {type: that} + usePrePhraseSnapshot: true + action: {name: editNewLineAfter} +initialState: + documentContents: |+ + hello world + + selections: + - anchor: {line: 2, character: 0} + active: {line: 2, character: 0} + marks: {} + thatMark: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} +finalState: + documentContents: |+ + hello world + + + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + thatMark: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 6} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/pourThat2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/pourThat2.yml new file mode 100644 index 0000000000..e517055d39 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/pourThat2.yml @@ -0,0 +1,32 @@ +languageId: plaintext +command: + spokenForm: pour that + version: 2 + targets: + - type: primitive + mark: {type: that} + usePrePhraseSnapshot: true + action: {name: editNewLineAfter} +initialState: + documentContents: |+ + hello world + + selections: + - anchor: {line: 2, character: 0} + active: {line: 2, character: 0} + marks: {} + thatMark: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 11} +finalState: + documentContents: |+ + hello world + + + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + thatMark: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 11} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/pourThis.yml b/src/test/suite/fixtures/recorded/implicitExpansion/pourThis.yml new file mode 100644 index 0000000000..ffaf4d287a --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/pourThis.yml @@ -0,0 +1,25 @@ +languageId: plaintext +command: + spokenForm: pour this + version: 2 + targets: + - type: primitive + mark: {type: cursor} + usePrePhraseSnapshot: true + action: {name: editNewLineAfter} +initialState: + documentContents: aaa bbb + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} +finalState: + documentContents: | + aaa bbb + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/pourThis2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/pourThis2.yml new file mode 100644 index 0000000000..457eaaa3de --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/pourThis2.yml @@ -0,0 +1,25 @@ +languageId: plaintext +command: + spokenForm: pour this + version: 2 + targets: + - type: primitive + mark: {type: cursor} + usePrePhraseSnapshot: true + action: {name: editNewLineAfter} +initialState: + documentContents: aaa bbb + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 3} + marks: {} +finalState: + documentContents: | + aaa bbb + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 3} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkAfterThat.yml b/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkAfterThat.yml new file mode 100644 index 0000000000..40e906da71 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkAfterThat.yml @@ -0,0 +1,41 @@ +languageId: typescript +command: + spokenForm: snip funk after that + version: 2 + targets: + - type: primitive + mark: {type: that} + modifiers: + - {type: position, position: after} + usePrePhraseSnapshot: true + action: + name: insertSnippet + args: [functionDeclaration] +initialState: + documentContents: | + function myFunction() { + const whatever = "hello"; + } + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} + thatMark: + - anchor: {line: 1, character: 27} + active: {line: 1, character: 27} +finalState: + documentContents: | + function myFunction() { + const whatever = "hello"; + } + + function () { + + } + selections: + - anchor: {line: 4, character: 9} + active: {line: 4, character: 9} + thatMark: + - anchor: {line: 4, character: 0} + active: {line: 6, character: 1} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: [], positionModifier: {type: position, position: after}}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkAfterThat2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkAfterThat2.yml new file mode 100644 index 0000000000..5d7a176d20 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkAfterThat2.yml @@ -0,0 +1,41 @@ +languageId: typescript +command: + spokenForm: snip funk after that + version: 2 + targets: + - type: primitive + mark: {type: that} + modifiers: + - {type: position, position: after} + usePrePhraseSnapshot: true + action: + name: insertSnippet + args: [functionDeclaration] +initialState: + documentContents: |- + function whatever() { + const hello = "world"; + } + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 0} + marks: {} + thatMark: + - anchor: {line: 1, character: 10} + active: {line: 1, character: 15} +finalState: + documentContents: |- + function whatever() { + const hello = "world"; + } + + function () { + + } + selections: + - anchor: {line: 4, character: 9} + active: {line: 4, character: 9} + thatMark: + - anchor: {line: 4, character: 0} + active: {line: 6, character: 1} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: [], positionModifier: {type: position, position: after}}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkAfterThis.yml b/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkAfterThis.yml new file mode 100644 index 0000000000..d6831313e5 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkAfterThis.yml @@ -0,0 +1,42 @@ +languageId: typescript +command: + spokenForm: snip funk after this + version: 2 + targets: + - type: primitive + mark: {type: cursor} + modifiers: + - {type: position, position: after} + usePrePhraseSnapshot: true + action: + name: insertSnippet + args: [functionDeclaration] +initialState: + documentContents: |+ + function myFunction() { + const whatever = "hello"; + } + + + selections: + - anchor: {line: 1, character: 10} + active: {line: 1, character: 10} + marks: {} +finalState: + documentContents: |+ + function myFunction() { + const whatever = "hello"; + } + + function () { + + } + + + selections: + - anchor: {line: 4, character: 9} + active: {line: 4, character: 9} + thatMark: + - anchor: {line: 4, character: 0} + active: {line: 6, character: 1} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [], positionModifier: {type: position, position: after}}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkAfterThis2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkAfterThis2.yml new file mode 100644 index 0000000000..5ef2d56ea7 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkAfterThis2.yml @@ -0,0 +1,42 @@ +languageId: typescript +command: + spokenForm: snip funk after this + version: 2 + targets: + - type: primitive + mark: {type: cursor} + modifiers: + - {type: position, position: after} + usePrePhraseSnapshot: true + action: + name: insertSnippet + args: [functionDeclaration] +initialState: + documentContents: |+ + function myFunction() { + const whatever = "hello"; + } + + + selections: + - anchor: {line: 1, character: 10} + active: {line: 1, character: 18} + marks: {} +finalState: + documentContents: |+ + function myFunction() { + const whatever = "hello"; + } + + function () { + + } + + + selections: + - anchor: {line: 4, character: 9} + active: {line: 4, character: 9} + thatMark: + - anchor: {line: 4, character: 0} + active: {line: 6, character: 1} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [], positionModifier: {type: position, position: after}}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkAfterToken.yml b/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkAfterToken.yml new file mode 100644 index 0000000000..2a36f9a92a --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkAfterToken.yml @@ -0,0 +1,39 @@ +languageId: typescript +command: + spokenForm: snip funk after token + version: 2 + targets: + - type: primitive + modifiers: + - {type: position, position: after} + - type: containingScope + scopeType: {type: token} + usePrePhraseSnapshot: true + action: + name: insertSnippet + args: [functionDeclaration] +initialState: + documentContents: |+ + function myFunction() { + const whatever = "hello"; + } + + selections: + - anchor: {line: 1, character: 10} + active: {line: 1, character: 18} + marks: {} +finalState: + documentContents: |+ + function myFunction() { + const whatever function () { + + } = "hello"; + } + + selections: + - anchor: {line: 1, character: 28} + active: {line: 1, character: 28} + thatMark: + - anchor: {line: 1, character: 19} + active: {line: 3, character: 5} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: containingScope, scopeType: {type: token}}], positionModifier: {type: position, position: after}}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkAfterWhale.yml b/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkAfterWhale.yml new file mode 100644 index 0000000000..ca12946962 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkAfterWhale.yml @@ -0,0 +1,43 @@ +languageId: typescript +command: + spokenForm: snip funk after whale + version: 2 + targets: + - type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: w} + modifiers: + - {type: position, position: after} + usePrePhraseSnapshot: true + action: + name: insertSnippet + args: [functionDeclaration] +initialState: + documentContents: |+ + function myFunction() { + const whatever = "hello"; + } + + selections: + - anchor: {line: 4, character: 0} + active: {line: 4, character: 0} + marks: + default.w: + start: {line: 1, character: 10} + end: {line: 1, character: 18} +finalState: + documentContents: |+ + function myFunction() { + const whatever = "hello"; + } + + function () { + + } + + selections: + - anchor: {line: 4, character: 9} + active: {line: 4, character: 9} + thatMark: + - anchor: {line: 4, character: 0} + active: {line: 6, character: 1} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: w}, modifiers: [], positionModifier: {type: position, position: after}}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkToAirPastWhale.yml b/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkToAirPastWhale.yml new file mode 100644 index 0000000000..2271b50a59 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkToAirPastWhale.yml @@ -0,0 +1,51 @@ +languageId: typescript +command: + spokenForm: snip funk to air past whale + version: 2 + targets: + - type: range + anchor: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: a} + active: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: w} + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: true + action: + name: insertSnippet + args: [functionDeclaration] +initialState: + documentContents: |+ + function myFunction() { + const whatever = "hello"; + } + + function testing() { + const whatever = "hello"; + } + + selections: + - anchor: {line: 8, character: 0} + active: {line: 8, character: 0} + marks: + default.a: + start: {line: 1, character: 10} + end: {line: 1, character: 18} + default.w: + start: {line: 5, character: 10} + end: {line: 5, character: 18} +finalState: + documentContents: |+ + function () { + + } + + selections: + - anchor: {line: 0, character: 9} + active: {line: 0, character: 9} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 2, character: 1} +fullTargets: [{type: range, excludeAnchor: false, excludeActive: false, rangeType: continuous, anchor: {type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: a}, modifiers: []}, active: {type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: w}, modifiers: []}}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkToThisPastEach.yml b/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkToThisPastEach.yml new file mode 100644 index 0000000000..ef1a10091d --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/snipFunkToThisPastEach.yml @@ -0,0 +1,46 @@ +languageId: typescript +command: + spokenForm: snip funk to this past each + version: 2 + targets: + - type: range + anchor: + type: primitive + mark: {type: cursor} + active: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: e} + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: true + action: + name: insertSnippet + args: [functionDeclaration] +initialState: + documentContents: |- + function whatever() { + const hello = "world"; + } + + function testing() { + const hello = "world"; + } + selections: + - anchor: {line: 1, character: 10} + active: {line: 1, character: 10} + marks: + default.e: + start: {line: 5, character: 10} + end: {line: 5, character: 15} +finalState: + documentContents: |- + function () { + + } + selections: + - anchor: {line: 0, character: 9} + active: {line: 0, character: 9} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 2, character: 1} +fullTargets: [{type: range, excludeAnchor: false, excludeActive: false, rangeType: continuous, anchor: {type: primitive, mark: {type: cursor}, modifiers: []}, active: {type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: e}, modifiers: []}}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchAir.yml b/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchAir.yml new file mode 100644 index 0000000000..3f79ca9061 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchAir.yml @@ -0,0 +1,32 @@ +languageId: plaintext +command: + spokenForm: square switch air + version: 2 + targets: + - type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: a} + usePrePhraseSnapshot: true + action: + name: rewrapWithPairedDelimiter + args: ['[', ']'] +initialState: + documentContents: (aaa bbb) + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + marks: + default.a: + start: {line: 0, character: 1} + end: {line: 0, character: 4} +finalState: + documentContents: "[aaa bbb]" + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 9} + sourceMark: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 4} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: a}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchFunk.yml b/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchFunk.yml new file mode 100644 index 0000000000..15be6bc5d9 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchFunk.yml @@ -0,0 +1,26 @@ +languageId: typescript +command: + spokenForm: square switch funk + version: 2 + targets: + - type: primitive + modifiers: + - type: containingScope + scopeType: {type: namedFunction} + usePrePhraseSnapshot: true + action: + name: rewrapWithPairedDelimiter + args: ['[', ']'] +initialState: + documentContents: |- + { + function myFunk() { + // aaa + } + } + selections: + - anchor: {line: 2, character: 7} + active: {line: 2, character: 7} + marks: {} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: containingScope, scopeType: {type: namedFunction}}]}] +thrownError: {name: NoContainingScopeError} diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchLookPastTrap.yml b/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchLookPastTrap.yml new file mode 100644 index 0000000000..697636af83 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchLookPastTrap.yml @@ -0,0 +1,44 @@ +languageId: plaintext +command: + spokenForm: square switch look past trap + version: 2 + targets: + - type: range + anchor: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: l} + active: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: t} + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: true + action: + name: rewrapWithPairedDelimiter + args: ['[', ']'] +initialState: + documentContents: | + (hello there now) + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + marks: + default.l: + start: {line: 0, character: 1} + end: {line: 0, character: 6} + default.t: + start: {line: 0, character: 7} + end: {line: 0, character: 12} +finalState: + documentContents: | + [hello there now] + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 17} + sourceMark: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 6} +fullTargets: [{type: range, excludeAnchor: false, excludeActive: false, rangeType: continuous, anchor: {type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: l}, modifiers: []}, active: {type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: t}, modifiers: []}}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchPastWhale.yml b/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchPastWhale.yml new file mode 100644 index 0000000000..ddf618d459 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchPastWhale.yml @@ -0,0 +1,37 @@ +languageId: plaintext +command: + spokenForm: square switch past whale + version: 2 + targets: + - type: range + anchor: {type: primitive} + active: + type: primitive + mark: {type: decoratedSymbol, symbolColor: default, character: w} + excludeAnchor: false + excludeActive: false + usePrePhraseSnapshot: true + action: + name: rewrapWithPairedDelimiter + args: ['[', ']'] +initialState: + documentContents: (hello world there) + selections: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} + marks: + default.w: + start: {line: 0, character: 7} + end: {line: 0, character: 12} +finalState: + documentContents: "[hello world there]" + selections: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 19} + sourceMark: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 3} +fullTargets: [{type: range, excludeAnchor: false, excludeActive: false, rangeType: continuous, anchor: {type: primitive, mark: {type: cursor}, modifiers: []}, active: {type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: w}, modifiers: []}}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchThat.yml b/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchThat.yml new file mode 100644 index 0000000000..f44580e742 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchThat.yml @@ -0,0 +1,34 @@ +languageId: plaintext +command: + spokenForm: square switch that + version: 2 + targets: + - type: primitive + mark: {type: that} + usePrePhraseSnapshot: true + action: + name: rewrapWithPairedDelimiter + args: ['[', ']'] +initialState: + documentContents: | + (hello ) + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + marks: {} + thatMark: + - anchor: {line: 0, character: 7} + active: {line: 0, character: 7} +finalState: + documentContents: | + [hello ] + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 8} + sourceMark: + - anchor: {line: 0, character: 7} + active: {line: 0, character: 7} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchThat2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchThat2.yml new file mode 100644 index 0000000000..a276b9b8d2 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchThat2.yml @@ -0,0 +1,34 @@ +languageId: plaintext +command: + spokenForm: square switch that + version: 2 + targets: + - type: primitive + mark: {type: that} + usePrePhraseSnapshot: true + action: + name: rewrapWithPairedDelimiter + args: ['[', ']'] +initialState: + documentContents: | + (hello world) + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + marks: {} + thatMark: + - anchor: {line: 0, character: 7} + active: {line: 0, character: 12} +finalState: + documentContents: | + [hello world] + selections: + - anchor: {line: 1, character: 0} + active: {line: 1, character: 0} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 13} + sourceMark: + - anchor: {line: 0, character: 7} + active: {line: 0, character: 12} +fullTargets: [{type: primitive, mark: {type: that}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchThis.yml b/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchThis.yml new file mode 100644 index 0000000000..1cdd359fe4 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchThis.yml @@ -0,0 +1,29 @@ +languageId: plaintext +command: + spokenForm: square switch this + version: 2 + targets: + - type: primitive + mark: {type: cursor} + usePrePhraseSnapshot: true + action: + name: rewrapWithPairedDelimiter + args: ['[', ']'] +initialState: + documentContents: (aaa bbb) + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + marks: {} +finalState: + documentContents: "[aaa bbb]" + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 9} + sourceMark: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 1} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchThis2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchThis2.yml new file mode 100644 index 0000000000..ea52efe734 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/squareSwitchThis2.yml @@ -0,0 +1,29 @@ +languageId: plaintext +command: + spokenForm: square switch this + version: 2 + targets: + - type: primitive + mark: {type: cursor} + usePrePhraseSnapshot: true + action: + name: rewrapWithPairedDelimiter + args: ['[', ']'] +initialState: + documentContents: (aaa bbb) + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 4} + marks: {} +finalState: + documentContents: "[aaa bbb]" + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 4} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 9} + sourceMark: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 4} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: []}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryBlock.yml b/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryBlock.yml new file mode 100644 index 0000000000..bca2245982 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryBlock.yml @@ -0,0 +1,46 @@ +languageId: plaintext +command: + spokenForm: take every block + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: paragraph} + usePrePhraseSnapshot: true + action: {name: setSelection} +initialState: + documentContents: |- + first block-test + for testing + + second block-test + for testing + + third block-test + for testing + selections: + - anchor: {line: 0, character: 6} + active: {line: 3, character: 6} + marks: {} +finalState: + documentContents: |- + first block-test + for testing + + second block-test + for testing + + third block-test + for testing + selections: + - anchor: {line: 0, character: 0} + active: {line: 1, character: 11} + - anchor: {line: 3, character: 0} + active: {line: 4, character: 11} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 1, character: 11} + - anchor: {line: 3, character: 0} + active: {line: 4, character: 11} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: everyScope, scopeType: {type: paragraph}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryBlock2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryBlock2.yml new file mode 100644 index 0000000000..8c1477bc7a --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryBlock2.yml @@ -0,0 +1,50 @@ +languageId: plaintext +command: + spokenForm: take every block + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: paragraph} + usePrePhraseSnapshot: true + action: {name: setSelection} +initialState: + documentContents: |- + first block-test + for testing + + second block-test + for testing + + third block-test + for testing + selections: + - anchor: {line: 3, character: 6} + active: {line: 3, character: 6} + marks: {} +finalState: + documentContents: |- + first block-test + for testing + + second block-test + for testing + + third block-test + for testing + selections: + - anchor: {line: 0, character: 0} + active: {line: 1, character: 11} + - anchor: {line: 3, character: 0} + active: {line: 4, character: 11} + - anchor: {line: 6, character: 0} + active: {line: 7, character: 11} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 1, character: 11} + - anchor: {line: 3, character: 0} + active: {line: 4, character: 11} + - anchor: {line: 6, character: 0} + active: {line: 7, character: 11} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: everyScope, scopeType: {type: paragraph}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryBlockFunkWhale.yml b/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryBlockFunkWhale.yml new file mode 100644 index 0000000000..8c7eb14bf2 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryBlockFunkWhale.yml @@ -0,0 +1,54 @@ +languageId: typescript +command: + spokenForm: take every block funk whale + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: paragraph} + - type: containingScope + scopeType: {type: namedFunction} + mark: {type: decoratedSymbol, symbolColor: default, character: w} + usePrePhraseSnapshot: true + action: {name: setSelection} +initialState: + documentContents: |- + function whatever() { + const testing = "hello"; + + const again = "hello"; + } + + function another() { + const testing = "hello"; + } + selections: + - anchor: {line: 6, character: 16} + active: {line: 6, character: 16} + marks: + default.w: + start: {line: 0, character: 9} + end: {line: 0, character: 17} +finalState: + documentContents: |- + function whatever() { + const testing = "hello"; + + const again = "hello"; + } + + function another() { + const testing = "hello"; + } + selections: + - anchor: {line: 0, character: 0} + active: {line: 1, character: 28} + - anchor: {line: 3, character: 4} + active: {line: 4, character: 1} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 1, character: 28} + - anchor: {line: 3, character: 4} + active: {line: 4, character: 1} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: w}, modifiers: [{type: everyScope, scopeType: {type: paragraph}}, {type: containingScope, scopeType: {type: namedFunction}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryPaint.yml b/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryPaint.yml new file mode 100644 index 0000000000..a7adbbf3dc --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryPaint.yml @@ -0,0 +1,52 @@ +languageId: plaintext +command: + spokenForm: take every paint + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: nonWhitespaceSequence} + usePrePhraseSnapshot: true + action: {name: setSelection} +initialState: + documentContents: |- + first test-block + for testing + + second test-block + for testing + selections: + - anchor: {line: 0, character: 6} + active: {line: 3, character: 9} + marks: {} +finalState: + documentContents: |- + first test-block + for testing + + second test-block + for testing + selections: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 16} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 3} + - anchor: {line: 1, character: 4} + active: {line: 1, character: 11} + - anchor: {line: 3, character: 0} + active: {line: 3, character: 6} + - anchor: {line: 3, character: 7} + active: {line: 3, character: 17} + thatMark: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 16} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 3} + - anchor: {line: 1, character: 4} + active: {line: 1, character: 11} + - anchor: {line: 3, character: 0} + active: {line: 3, character: 6} + - anchor: {line: 3, character: 7} + active: {line: 3, character: 17} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: everyScope, scopeType: {type: boundedNonWhitespaceSequence}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryPaintBlockRisk.yml b/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryPaintBlockRisk.yml new file mode 100644 index 0000000000..21df333152 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryPaintBlockRisk.yml @@ -0,0 +1,54 @@ +languageId: plaintext +command: + spokenForm: take every paint block risk + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: nonWhitespaceSequence} + - type: containingScope + scopeType: {type: paragraph} + mark: {type: decoratedSymbol, symbolColor: default, character: r} + usePrePhraseSnapshot: true + action: {name: setSelection} +initialState: + documentContents: |- + first test-block + for testing + + second test-block + for testing + selections: + - anchor: {line: 4, character: 0} + active: {line: 4, character: 0} + marks: + default.r: + start: {line: 0, character: 0} + end: {line: 0, character: 5} +finalState: + documentContents: |- + first test-block + for testing + + second test-block + for testing + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 5} + - anchor: {line: 0, character: 6} + active: {line: 0, character: 16} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 3} + - anchor: {line: 1, character: 4} + active: {line: 1, character: 11} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 5} + - anchor: {line: 0, character: 6} + active: {line: 0, character: 16} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 3} + - anchor: {line: 1, character: 4} + active: {line: 1, character: 11} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: r}, modifiers: [{type: everyScope, scopeType: {type: boundedNonWhitespaceSequence}}, {type: containingScope, scopeType: {type: paragraph}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryPaintEach.yml b/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryPaintEach.yml new file mode 100644 index 0000000000..f398d1461c --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryPaintEach.yml @@ -0,0 +1,38 @@ +languageId: plaintext +command: + spokenForm: take every paint each + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: nonWhitespaceSequence} + mark: {type: decoratedSymbol, symbolColor: default, character: e} + usePrePhraseSnapshot: true + action: {name: setSelection} +initialState: + documentContents: |- + first test-block + for testing + selections: + - anchor: {line: 1, character: 11} + active: {line: 1, character: 11} + marks: + default.e: + start: {line: 0, character: 6} + end: {line: 0, character: 10} +finalState: + documentContents: |- + first test-block + for testing + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 5} + - anchor: {line: 0, character: 6} + active: {line: 0, character: 16} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 5} + - anchor: {line: 0, character: 6} + active: {line: 0, character: 16} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: e}, modifiers: [{type: everyScope, scopeType: {type: boundedNonWhitespaceSequence}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/takeEverySmallPaint.yml b/src/test/suite/fixtures/recorded/implicitExpansion/takeEverySmallPaint.yml new file mode 100644 index 0000000000..f8e50cae7e --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/takeEverySmallPaint.yml @@ -0,0 +1,52 @@ +languageId: plaintext +command: + spokenForm: take every paint + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: boundedNonWhitespaceSequence} + usePrePhraseSnapshot: true + action: {name: setSelection} +initialState: + documentContents: |- + first test-block + for testing + + second test-block + for testing + selections: + - anchor: {line: 0, character: 6} + active: {line: 3, character: 9} + marks: {} +finalState: + documentContents: |- + first test-block + for testing + + second test-block + for testing + selections: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 16} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 3} + - anchor: {line: 1, character: 4} + active: {line: 1, character: 11} + - anchor: {line: 3, character: 0} + active: {line: 3, character: 6} + - anchor: {line: 3, character: 7} + active: {line: 3, character: 17} + thatMark: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 16} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 3} + - anchor: {line: 1, character: 4} + active: {line: 1, character: 11} + - anchor: {line: 3, character: 0} + active: {line: 3, character: 6} + - anchor: {line: 3, character: 7} + active: {line: 3, character: 17} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: everyScope, scopeType: {type: boundedNonWhitespaceSequence}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/takeEverySmallPaint2.yml b/src/test/suite/fixtures/recorded/implicitExpansion/takeEverySmallPaint2.yml new file mode 100644 index 0000000000..ac6befef3f --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/takeEverySmallPaint2.yml @@ -0,0 +1,30 @@ +languageId: plaintext +command: + spokenForm: take every paint + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: boundedNonWhitespaceSequence} + usePrePhraseSnapshot: true + action: {name: setSelection} +initialState: + documentContents: (hello world-whatever testing) testing now + selections: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 10} + marks: {} +finalState: + documentContents: (hello world-whatever testing) testing now + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 6} + - anchor: {line: 0, character: 7} + active: {line: 0, character: 21} + thatMark: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 6} + - anchor: {line: 0, character: 7} + active: {line: 0, character: 21} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: everyScope, scopeType: {type: boundedNonWhitespaceSequence}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/takeEverySmallPaintBlockRisk.yml b/src/test/suite/fixtures/recorded/implicitExpansion/takeEverySmallPaintBlockRisk.yml new file mode 100644 index 0000000000..2c69631159 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/takeEverySmallPaintBlockRisk.yml @@ -0,0 +1,54 @@ +languageId: plaintext +command: + spokenForm: take every paint block risk + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: boundedNonWhitespaceSequence} + - type: containingScope + scopeType: {type: paragraph} + mark: {type: decoratedSymbol, symbolColor: default, character: r} + usePrePhraseSnapshot: true + action: {name: setSelection} +initialState: + documentContents: |- + first test-block + for testing + + second test-block + for testing + selections: + - anchor: {line: 4, character: 0} + active: {line: 4, character: 0} + marks: + default.r: + start: {line: 0, character: 0} + end: {line: 0, character: 5} +finalState: + documentContents: |- + first test-block + for testing + + second test-block + for testing + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 5} + - anchor: {line: 0, character: 6} + active: {line: 0, character: 16} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 3} + - anchor: {line: 1, character: 4} + active: {line: 1, character: 11} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 5} + - anchor: {line: 0, character: 6} + active: {line: 0, character: 16} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 3} + - anchor: {line: 1, character: 4} + active: {line: 1, character: 11} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: r}, modifiers: [{type: everyScope, scopeType: {type: boundedNonWhitespaceSequence}}, {type: containingScope, scopeType: {type: paragraph}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/takeEverySmallPaintEach.yml b/src/test/suite/fixtures/recorded/implicitExpansion/takeEverySmallPaintEach.yml new file mode 100644 index 0000000000..05b66e3de4 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/takeEverySmallPaintEach.yml @@ -0,0 +1,38 @@ +languageId: plaintext +command: + spokenForm: take every paint each + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: boundedNonWhitespaceSequence} + mark: {type: decoratedSymbol, symbolColor: default, character: e} + usePrePhraseSnapshot: true + action: {name: setSelection} +initialState: + documentContents: |- + first test-block + for testing + selections: + - anchor: {line: 1, character: 11} + active: {line: 1, character: 11} + marks: + default.e: + start: {line: 0, character: 6} + end: {line: 0, character: 10} +finalState: + documentContents: |- + first test-block + for testing + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 5} + - anchor: {line: 0, character: 6} + active: {line: 0, character: 16} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 5} + - anchor: {line: 0, character: 6} + active: {line: 0, character: 16} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: e}, modifiers: [{type: everyScope, scopeType: {type: boundedNonWhitespaceSequence}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/takeEverySmallPaintToken.yml b/src/test/suite/fixtures/recorded/implicitExpansion/takeEverySmallPaintToken.yml new file mode 100644 index 0000000000..a19851b621 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/takeEverySmallPaintToken.yml @@ -0,0 +1,32 @@ +languageId: plaintext +command: + spokenForm: take every paint token + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: boundedNonWhitespaceSequence} + - type: containingScope + scopeType: {type: token} + usePrePhraseSnapshot: true + action: {name: setSelection} +initialState: + documentContents: (hello world-whatever testing) testing now + selections: + - anchor: {line: 0, character: 3} + active: {line: 0, character: 10} + marks: {} +finalState: + documentContents: (hello world-whatever testing) testing now + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 6} + - anchor: {line: 0, character: 7} + active: {line: 0, character: 21} + thatMark: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 6} + - anchor: {line: 0, character: 7} + active: {line: 0, character: 21} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: everyScope, scopeType: {type: boundedNonWhitespaceSequence}}, {type: containingScope, scopeType: {type: token}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/takeEverySmallPaintWhale.yml b/src/test/suite/fixtures/recorded/implicitExpansion/takeEverySmallPaintWhale.yml new file mode 100644 index 0000000000..e443194800 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/takeEverySmallPaintWhale.yml @@ -0,0 +1,34 @@ +languageId: plaintext +command: + spokenForm: take every paint whale + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: boundedNonWhitespaceSequence} + mark: {type: decoratedSymbol, symbolColor: default, character: w} + usePrePhraseSnapshot: true + action: {name: setSelection} +initialState: + documentContents: (hello world-whatever) testing now + selections: + - anchor: {line: 0, character: 34} + active: {line: 0, character: 34} + marks: + default.w: + start: {line: 0, character: 7} + end: {line: 0, character: 12} +finalState: + documentContents: (hello world-whatever) testing now + selections: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 6} + - anchor: {line: 0, character: 7} + active: {line: 0, character: 21} + thatMark: + - anchor: {line: 0, character: 1} + active: {line: 0, character: 6} + - anchor: {line: 0, character: 7} + active: {line: 0, character: 21} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: w}, modifiers: [{type: everyScope, scopeType: {type: boundedNonWhitespaceSequence}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryToken.yml b/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryToken.yml new file mode 100644 index 0000000000..db98b783e9 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryToken.yml @@ -0,0 +1,60 @@ +languageId: plaintext +command: + spokenForm: take every token + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: token} + usePrePhraseSnapshot: true + action: {name: setSelection} +initialState: + documentContents: |- + first test-block + for testing + + second test-block + for testing + selections: + - anchor: {line: 0, character: 6} + active: {line: 3, character: 9} + marks: {} +finalState: + documentContents: |- + first test-block + for testing + + second test-block + for testing + selections: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 10} + - anchor: {line: 0, character: 10} + active: {line: 0, character: 11} + - anchor: {line: 0, character: 11} + active: {line: 0, character: 16} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 3} + - anchor: {line: 1, character: 4} + active: {line: 1, character: 11} + - anchor: {line: 3, character: 0} + active: {line: 3, character: 6} + - anchor: {line: 3, character: 7} + active: {line: 3, character: 11} + thatMark: + - anchor: {line: 0, character: 6} + active: {line: 0, character: 10} + - anchor: {line: 0, character: 10} + active: {line: 0, character: 11} + - anchor: {line: 0, character: 11} + active: {line: 0, character: 16} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 3} + - anchor: {line: 1, character: 4} + active: {line: 1, character: 11} + - anchor: {line: 3, character: 0} + active: {line: 3, character: 6} + - anchor: {line: 3, character: 7} + active: {line: 3, character: 11} +fullTargets: [{type: primitive, mark: {type: cursor}, modifiers: [{type: everyScope, scopeType: {type: token}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryTokenBlockRisk.yml b/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryTokenBlockRisk.yml new file mode 100644 index 0000000000..3b9de93706 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryTokenBlockRisk.yml @@ -0,0 +1,62 @@ +languageId: plaintext +command: + spokenForm: take every token block risk + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: token} + - type: containingScope + scopeType: {type: paragraph} + mark: {type: decoratedSymbol, symbolColor: default, character: r} + usePrePhraseSnapshot: true + action: {name: setSelection} +initialState: + documentContents: |- + first test-block + for testing + + second test-block + for testing + selections: + - anchor: {line: 4, character: 0} + active: {line: 4, character: 0} + marks: + default.r: + start: {line: 0, character: 0} + end: {line: 0, character: 5} +finalState: + documentContents: |- + first test-block + for testing + + second test-block + for testing + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 5} + - anchor: {line: 0, character: 6} + active: {line: 0, character: 10} + - anchor: {line: 0, character: 10} + active: {line: 0, character: 11} + - anchor: {line: 0, character: 11} + active: {line: 0, character: 16} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 3} + - anchor: {line: 1, character: 4} + active: {line: 1, character: 11} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 5} + - anchor: {line: 0, character: 6} + active: {line: 0, character: 10} + - anchor: {line: 0, character: 10} + active: {line: 0, character: 11} + - anchor: {line: 0, character: 11} + active: {line: 0, character: 16} + - anchor: {line: 1, character: 0} + active: {line: 1, character: 3} + - anchor: {line: 1, character: 4} + active: {line: 1, character: 11} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: r}, modifiers: [{type: everyScope, scopeType: {type: token}}, {type: containingScope, scopeType: {type: paragraph}}]}] diff --git a/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryTokenEach.yml b/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryTokenEach.yml new file mode 100644 index 0000000000..5c62b05cb2 --- /dev/null +++ b/src/test/suite/fixtures/recorded/implicitExpansion/takeEveryTokenEach.yml @@ -0,0 +1,46 @@ +languageId: plaintext +command: + spokenForm: take every token each + version: 2 + targets: + - type: primitive + modifiers: + - type: everyScope + scopeType: {type: token} + mark: {type: decoratedSymbol, symbolColor: default, character: e} + usePrePhraseSnapshot: true + action: {name: setSelection} +initialState: + documentContents: |- + first test-block + for testing + selections: + - anchor: {line: 1, character: 11} + active: {line: 1, character: 11} + marks: + default.e: + start: {line: 0, character: 6} + end: {line: 0, character: 10} +finalState: + documentContents: |- + first test-block + for testing + selections: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 5} + - anchor: {line: 0, character: 6} + active: {line: 0, character: 10} + - anchor: {line: 0, character: 10} + active: {line: 0, character: 11} + - anchor: {line: 0, character: 11} + active: {line: 0, character: 16} + thatMark: + - anchor: {line: 0, character: 0} + active: {line: 0, character: 5} + - anchor: {line: 0, character: 6} + active: {line: 0, character: 10} + - anchor: {line: 0, character: 10} + active: {line: 0, character: 11} + - anchor: {line: 0, character: 11} + active: {line: 0, character: 16} +fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: e}, modifiers: [{type: everyScope, scopeType: {type: token}}]}] diff --git a/src/test/suite/runTestSubset.ts b/src/test/suite/runTestSubset.ts index a7d8f5dc8d..dbd8ec213d 100644 --- a/src/test/suite/runTestSubset.ts +++ b/src/test/suite/runTestSubset.ts @@ -4,7 +4,7 @@ * configuration. * See https://mochajs.org/#-grep-regexp-g-regexp for supported syntax */ -export const TEST_SUBSET_GREP_STRING = "rust"; +export const TEST_SUBSET_GREP_STRING = "implicit"; /** * Determine whether we should run just the subset of the tests specified by diff --git a/src/testUtil/TestCase.ts b/src/testUtil/TestCase.ts index 121f9d180f..bc6d013058 100644 --- a/src/testUtil/TestCase.ts +++ b/src/testUtil/TestCase.ts @@ -58,12 +58,21 @@ export type TestCaseFixture = { marksToCheck?: string[]; initialState: TestCaseSnapshot; + /** + * Expected decorations in the test case, for example highlighting deletions in red. + */ decorations?: PlainTestDecoration[]; /** The final state after a command is issued. Undefined if we are testing a non-match(error) case. */ finalState?: TestCaseSnapshot; /** Used to assert if an error has been thrown. */ thrownError?: ThrownError; - returnValue: unknown; + + /** + * The return value of the command. Will be undefined when we have recorded an + * error test case. + */ + returnValue?: unknown; + /** Inferred full targets added for context; not currently used in testing */ fullTargets: TargetDescriptor[]; }; @@ -75,7 +84,7 @@ export class TestCase { decorations?: PlainTestDecoration[]; finalState?: TestCaseSnapshot; thrownError?: ThrownError; - returnValue: unknown = null; + returnValue?: unknown; targetKeys: string[]; private _awaitingFinalMarkInfo: boolean; marksToCheck?: string[]; diff --git a/src/typings/target.types.ts b/src/typings/target.types.ts index 9aece8c968..e22eb0498c 100644 --- a/src/typings/target.types.ts +++ b/src/typings/target.types.ts @@ -1,4 +1,21 @@ import { Range, Selection, TextEditor } from "vscode"; +// NB: We import `Target` below just so that @link below resolves. Once one of +// the following issues are fixed, we can either remove the above line or +// switch to `{import("foo")}` syntax in the `{@link}` tag. +// - https://github.com/microsoft/TypeScript/issues/43869 +// - https://github.com/microsoft/TypeScript/issues/43950 +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import type ModifyIfUntypedStage from "../processTargets/modifiers/ModifyIfUntypedStage"; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import type { SnippetVariable, Snippet } from "./snippet"; +import type { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + ScopeTypeTarget, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + TokenTarget, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + UntypedTarget, +} from "../processTargets/targets"; import { Position } from "./targetDescriptor.types"; import { EditWithRangeUpdater } from "./Types"; @@ -28,8 +45,60 @@ export interface Target { /** If true this target should be treated as a line */ readonly isLine: boolean; - /** If true this target is weak and can be transformed/upgraded */ - readonly isWeak: boolean; + /** + * If `true`, then this target has an explicit scope type, and so should never + * be automatically expanded to a containing scope. + * + * Examples of targets that have explicit scopes are {@link ScopeTypeTarget} + * (eg `"funk"`), {@link TokenTarget} (eg `"token"`), etc. + * + * As of writing this comment, the only target type that doesn't have an + * explicit scope type is {@link UntypedTarget}, which can be constructed by + * + * - using a decorated mark (`"air"`), or + * - using any cursor mark (`"this"`), or + * - using a range between decorated marks or cursor marks (eg `"past air"` or + * `"air past bat"`), or + * - using any `"that"` mark (eg after saying `"copy air"`), though this + * final behaviour will change with #466. + * + * The primary consumer of this attribute is {@link ModifyIfUntypedStage}, + * which is used in the following situations to automatically expand to a + * particular scope type when `hasExplicitScopeType` is `false`: + * + * - To expand to `"line"` for `"pour"`, `"clone"`, and `"breakpoint"` + * - To expand to `"token"` for `"leading"` and `"trailing"` + * - To expand to nearest containing pair for `"inside"`, `"bounds"`, and + * `"rewrap"` + * - To expand to {@link SnippetVariable.wrapperScopeType} for snippet + * wrapping + * - To expand to {@link Snippet.insertionScopeTypes} for snippet insertion + * + * For example, when the user says `"pour air"`, the + * {@link DecoratedSymbolStage} will return an {@link UntypedTarget}, which + * has `hasExplicitScopeType=false`, so `"pour"` will expand to the line + * containining the air token and insert a newline after it. + */ + readonly hasExplicitScopeType: boolean; + + /** + * If `true`, then this target has an explicit range. This attribute is used + * by `"every"` to determine whether to return all scopes in the iteration + * scope or just the ones that overlap with the given target's + * {@link contentRange}. + * + * Most targets have explicit ranges. As of writing this comment, the only + * targets that don't are as follows: + * + * - a decorated mark (`"air"`), or + * - an empty cursor mark (`"this"` with an empty selection), or + * - an empty `"that"` mark (eg after saying `"chuck air"`). + * + * For example, when the user says `"change every state air"`, we clear every + * statement in the function, but `"change every state this"` with a non-empty + * selection will only target statements overlapping the cursor. + */ + readonly hasExplicitRange: boolean; /** If true this target is a raw selection and its insertion delimiter should not be used on bring action */ readonly isRaw: boolean; diff --git a/src/typings/targetDescriptor.types.ts b/src/typings/targetDescriptor.types.ts index 7c6919b27a..3d44bbb5f8 100644 --- a/src/typings/targetDescriptor.types.ts +++ b/src/typings/targetDescriptor.types.ts @@ -1,4 +1,7 @@ import { HatStyleName } from "../core/constants"; +// FIXME: See microsoft/TypeScript#43869 +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import type { Target } from "./target.types"; export interface CursorMark { type: "cursor"; @@ -203,13 +206,14 @@ export interface HeadTailModifier { } /** - * Runs {@link modifier} if the target is weak. + * Runs {@link modifier} if the target has no explicit scope type, ie if + * {@link Target.hasExplicitScopeType} is `false`. */ -export interface ModifyIfWeakModifier { - type: "modifyIfWeak"; +export interface ModifyIfUntypedModifier { + type: "modifyIfUntyped"; /** - * The modifier to apply if the target is weak + * The modifier to apply if the target is untyped */ modifier: Modifier; } @@ -239,7 +243,7 @@ export type Modifier = | LeadingModifier | TrailingModifier | RawSelectionModifier - | ModifyIfWeakModifier + | ModifyIfUntypedModifier | CascadingModifier; export interface PartialRangeTargetDescriptor {