Skip to content

Properly expand to token when using "end of this" #2782

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
languageId: plaintext
command:
version: 7
spokenForm: bring air to end of this
action:
name: replaceWithTarget
source:
type: primitive
mark: {type: decoratedSymbol, symbolColor: default, character: a}
destination:
type: primitive
insertionMode: to
target:
type: primitive
mark: {type: cursor}
modifiers:
- {type: endOf}
usePrePhraseSnapshot: false
initialState:
documentContents: |-
a
bbb
selections:
- anchor: {line: 1, character: 0}
active: {line: 1, character: 0}
marks:
default.a:
start: {line: 0, character: 0}
end: {line: 0, character: 1}
finalState:
documentContents: |-
a
bbba
selections:
- anchor: {line: 1, character: 0}
active: {line: 1, character: 0}
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ class TargetPipeline {
): Target[] {
let markStage: MarkStage;
let targetModifierStages: ModifierStage[];
let automaticTokenExpansionBefore = false;

if (targetDescriptor.type === "implicit") {
markStage = new ImplicitStage();
Expand All @@ -218,28 +219,62 @@ class TargetPipeline {
this.modifierStageFactory,
targetDescriptor.modifiers,
);
automaticTokenExpansionBefore =
doAutomaticTokenExpansionBefore(targetDescriptor);
}

// First, get the targets output by the mark
const markOutputTargets = markStage.run();

const [preStages, postStages] = this.getPreAndPostStages(
automaticTokenExpansionBefore,
);

/**
* The modifier pipeline that will be applied to construct our final targets
*/
const modifierStages = [
...preStages,
...targetModifierStages,
...this.opts.actionFinalStages,

// This performs auto-expansion to token when you say eg "take this" with an
// empty selection
...(this.opts.noAutomaticTokenExpansion
? []
: [new ContainingTokenIfUntypedEmptyStage(this.modifierStageFactory)]),
...postStages,
];

// Run all targets through the modifier stages
return processModifierStages(modifierStages, markOutputTargets);
}

private getPreAndPostStages(
automaticTokenExpansionBefore: boolean,
): [ModifierStage[], ModifierStage[]] {
if (this.opts.noAutomaticTokenExpansion) {
return [[], []];
}
// This performs auto-expansion to token when you say eg "take this" with an
// empty selection
const stage = new ContainingTokenIfUntypedEmptyStage(
this.modifierStageFactory,
);
if (automaticTokenExpansionBefore) {
return [[stage], []];
}
return [[], [stage]];
}
}

/**
* Determines whether we should automatically expand the token before the target.
* True if the target has modifiers that are all "startOf" or "endOf".
*/
function doAutomaticTokenExpansionBefore(
targetDescriptor: PrimitiveTargetDescriptor,
): boolean {
return (
targetDescriptor.modifiers.length > 0 &&
targetDescriptor.modifiers.every(
({ type }) => type === "startOf" || type === "endOf",
)
);
}

/** Convert a list of target modifiers to modifier stages */
Expand Down
Loading