Skip to content

Commit 1e88a2f

Browse files
committed
Add implicit special target
1 parent 2ae73a7 commit 1e88a2f

File tree

28 files changed

+434
-75
lines changed

28 files changed

+434
-75
lines changed

cursorless-talon/src/spoken_forms.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,11 @@ def handle_new_values(csv_name: str, values: list[SpokenFormEntry]):
115115
)
116116

117117
disposables = [
118-
handle_csv("actions.csv"),
118+
handle_csv(
119+
"actions.csv",
120+
extra_allowed_values=["private.setImplicitTarget"],
121+
default_list_name="simple_action",
122+
),
119123
handle_csv("target_connectives.csv"),
120124
handle_csv("modifiers.csv"),
121125
handle_csv("positions.csv"),

packages/common/src/StoredTargetKey.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ export const storedTargetKeys = [
22
"that",
33
"source",
44
"instanceReference",
5+
"implicit",
56
] as const;
67
export type StoredTargetKey = (typeof storedTargetKeys)[number];

packages/common/src/testUtil/TestCaseSnapshot.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,30 @@
1+
import { StoredTargetKey } from "../StoredTargetKey";
12
import {
23
RangePlainObject,
34
SelectionPlainObject,
45
SerializedMarks,
56
TargetPlainObject,
67
} from "../util/toPlainObject";
78

8-
export type TestCaseSnapshot = {
9+
type MarkKeys = {
10+
[K in `${StoredTargetKey}Mark`]?: TargetPlainObject[];
11+
};
12+
13+
export interface TestCaseSnapshot extends MarkKeys {
914
documentContents: string;
1015
selections: SelectionPlainObject[];
1116
clipboard?: string;
1217
// FIXME Visible ranges are not asserted during testing, see:
1318
// https://github.com/cursorless-dev/cursorless/issues/160
1419
visibleRanges?: RangePlainObject[];
1520
marks?: SerializedMarks;
16-
thatMark?: TargetPlainObject[];
17-
sourceMark?: TargetPlainObject[];
18-
instanceReferenceMark?: TargetPlainObject[];
1921
timeOffsetSeconds?: number;
2022

2123
/**
2224
* Extra information about the snapshot. Must be json serializable
2325
*/
2426
metadata?: unknown;
25-
};
26-
27+
}
2728
export type ExtraSnapshotField = keyof TestCaseSnapshot;
2829
export type ExcludableSnapshotField = keyof TestCaseSnapshot;
2930

packages/common/src/types/command/ActionDescriptor.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ const simpleActionNames = [
4949
"toggleLineBreakpoint",
5050
"toggleLineComment",
5151
"unfoldRegion",
52+
"private.setImplicitTarget",
5253
"private.showParseTree",
5354
"private.getTargets",
5455
] as const;

packages/cursorless-engine/src/CommandHistory.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ function sanitizeActionInPlace(action: ActionDescriptor): void {
194194
case "swapTargets":
195195
case "wrapWithPairedDelimiter":
196196
case "findInDocument":
197+
case "private.setImplicitTarget":
197198
break;
198199

199200
default: {

packages/cursorless-engine/src/actions/Actions.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import Remove from "./Remove";
3333
import Replace from "./Replace";
3434
import Rewrap from "./Rewrap";
3535
import { ScrollToBottom, ScrollToCenter, ScrollToTop } from "./Scroll";
36-
import { SetInstanceReference } from "./SetInstanceReference";
36+
import { SetSpecialTarget } from "./SetSpecialTarget";
3737
import {
3838
SetSelection,
3939
SetSelectionAfter,
@@ -134,7 +134,10 @@ export class Actions implements ActionRecord {
134134
scrollToBottom = new ScrollToBottom();
135135
scrollToCenter = new ScrollToCenter();
136136
scrollToTop = new ScrollToTop();
137-
["experimental.setInstanceReference"] = new SetInstanceReference();
137+
["private.setImplicitTarget"] = new SetSpecialTarget("implicit");
138+
["experimental.setInstanceReference"] = new SetSpecialTarget(
139+
"instanceReference",
140+
);
138141
setSelection = new SetSelection();
139142
setSelectionAfter = new SetSelectionAfter();
140143
setSelectionBefore = new SetSelectionBefore();
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1+
import { StoredTargetKey } from "@cursorless/common";
12
import { Target } from "../typings/target.types";
23
import { SimpleAction, ActionReturnValue } from "./actions.types";
34

4-
export class SetInstanceReference implements SimpleAction {
5-
constructor() {
5+
export class SetSpecialTarget implements SimpleAction {
6+
noAutomaticTokenExpansion = true;
7+
8+
constructor(private key: StoredTargetKey) {
69
this.run = this.run.bind(this);
710
}
811

912
async run(targets: Target[]): Promise<ActionReturnValue> {
1013
return {
1114
thatTargets: targets,
12-
instanceReferenceTargets: targets,
15+
[`${this.key}Targets`]: targets,
1316
};
1417
}
1518
}

packages/cursorless-engine/src/actions/actions.types.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ export interface ActionReturnValue {
5252
* to determine either the range for "every", or the start point for "next"
5353
*/
5454
instanceReferenceTargets?: Target[];
55+
56+
/**
57+
* A list of targets that become the start of the pipeline when the mark is ommitted.
58+
*/
59+
implicitTargets?: Target[];
5560
}
5661

5762
export interface SimpleAction {
@@ -62,6 +67,13 @@ export interface SimpleAction {
6267
* @param args Extra args to command
6368
*/
6469
getFinalStages?(): ModifierStage[];
70+
71+
/**
72+
* If `true`, don't perform automatic token expansion for "<action> this" with
73+
* empty cursor. Used for actions like `setImplicitTarget` that are just
74+
* loading up the pipeline.
75+
*/
76+
noAutomaticTokenExpansion?: boolean;
6577
}
6678

6779
/**

packages/cursorless-engine/src/core/commandRunner/CommandRunnerImpl.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { selectionToStoredTarget } from "./selectionToStoredTarget";
1818
export class CommandRunnerImpl implements CommandRunner {
1919
private inferenceContext: InferenceContext;
2020
private finalStages: ModifierStage[] = [];
21+
private noAutomaticTokenExpansion: boolean | undefined;
2122

2223
constructor(
2324
private debug: Debug,
@@ -53,6 +54,7 @@ export class CommandRunnerImpl implements CommandRunner {
5354
sourceSelections: newSourceSelections,
5455
sourceTargets: newSourceTargets,
5556
instanceReferenceTargets: newInstanceReferenceTargets,
57+
implicitTargets: newImplicitTargets,
5658
} = await this.runAction(action);
5759

5860
this.storedTargets.set(
@@ -64,6 +66,7 @@ export class CommandRunnerImpl implements CommandRunner {
6466
constructStoredTarget(newSourceTargets, newSourceSelections),
6567
);
6668
this.storedTargets.set("instanceReference", newInstanceReferenceTargets);
69+
this.storedTargets.set("implicit", newImplicitTargets);
6770

6871
return returnValue;
6972
}
@@ -179,6 +182,8 @@ export class CommandRunnerImpl implements CommandRunner {
179182
default: {
180183
const action = this.actions[actionDescriptor.name];
181184
this.finalStages = action.getFinalStages?.() ?? [];
185+
this.noAutomaticTokenExpansion =
186+
action.noAutomaticTokenExpansion ?? false;
182187
return action.run(this.getTargets(actionDescriptor.target));
183188
}
184189
}
@@ -191,7 +196,10 @@ export class CommandRunnerImpl implements CommandRunner {
191196
partialTargetsDescriptor,
192197
);
193198

194-
return this.pipelineRunner.run(targetDescriptor, this.finalStages);
199+
return this.pipelineRunner.run(targetDescriptor, {
200+
actionFinalStages: this.finalStages,
201+
noAutomaticTokenExpansion: this.noAutomaticTokenExpansion,
202+
});
195203
}
196204

197205
private getDestinations(

packages/cursorless-engine/src/core/inferFullTargetDescriptor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ function inferPrimitiveTarget(
104104
(shouldInferPreviousMark(target)
105105
? getPreviousMark(previousTargets)
106106
: null) ?? {
107-
type: "cursor",
107+
type: "implicit",
108108
};
109109

110110
const modifiers =

0 commit comments

Comments
 (0)