Skip to content

Commit 7448866

Browse files
AndreasArvidssonpre-commit-ci-lite[bot]pokey
authored
Destinations as first-class objects (#1605)
- Fixes #1630 - Partially #1351 ## Checklist - [ ] I have added [tests](https://www.cursorless.org/docs/contributing/test-case-recorder/) - [ ] I have updated the [docs](https://github.com/cursorless-dev/cursorless/tree/main/docs) and [cheatsheet](https://github.com/cursorless-dev/cursorless/tree/main/cursorless-talon/src/cheatsheet) - [ ] I have not broken the cheatsheet --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Co-authored-by: Pokey Rule <[email protected]>
1 parent b923563 commit 7448866

File tree

99 files changed

+2461
-1234
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+2461
-1234
lines changed

packages/common/src/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,17 @@ export * from "./util/CompositeKeyMap";
6565
export * from "./ide/normalized/NormalizedIDE";
6666
export * from "./types/command/command.types";
6767
export * from "./types/command/PartialTargetDescriptor.types";
68-
export * from "./types/command/ActionCommand";
68+
export * from "./types/command/DestinationDescriptor.types";
69+
export * from "./types/command/ActionDescriptor";
6970
export * from "./types/command/legacy/CommandV0V1.types";
7071
export * from "./types/command/legacy/CommandV2.types";
7172
export * from "./types/command/legacy/CommandV3.types";
7273
export * from "./types/command/legacy/CommandV4.types";
7374
export * from "./types/command/legacy/targetDescriptorV2.types";
74-
export * from "./types/command/CommandV5.types";
75+
export * from "./types/command/legacy/ActionCommandV5";
76+
export * from "./types/command/legacy/CommandV5.types";
77+
export * from "./types/command/legacy/PartialTargetDescriptorV5.types";
78+
export * from "./types/command/CommandV6.types";
7579
export * from "./types/command/legacy/PartialTargetDescriptorV3.types";
7680
export * from "./types/command/legacy/PartialTargetDescriptorV4.types";
7781
export * from "./types/CommandServerApi";
Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
import {
2+
PartialTargetDescriptor,
3+
ScopeType,
4+
} from "./PartialTargetDescriptor.types";
5+
import { DestinationDescriptor } from "./DestinationDescriptor.types";
6+
7+
/**
8+
* A simple action takes only a single target and no other arguments.
9+
*/
10+
const simpleActionNames = [
11+
"clearAndSetSelection",
12+
"copyToClipboard",
13+
"cutToClipboard",
14+
"deselect",
15+
"editNewLineAfter",
16+
"editNewLineBefore",
17+
"experimental.setInstanceReference",
18+
"extractVariable",
19+
"findInWorkspace",
20+
"foldRegion",
21+
"followLink",
22+
"indentLine",
23+
"insertCopyAfter",
24+
"insertCopyBefore",
25+
"insertEmptyLineAfter",
26+
"insertEmptyLineBefore",
27+
"insertEmptyLinesAround",
28+
"outdentLine",
29+
"randomizeTargets",
30+
"remove",
31+
"rename",
32+
"revealDefinition",
33+
"revealTypeDefinition",
34+
"reverseTargets",
35+
"scrollToBottom",
36+
"scrollToCenter",
37+
"scrollToTop",
38+
"setSelection",
39+
"setSelectionAfter",
40+
"setSelectionBefore",
41+
"showDebugHover",
42+
"showHover",
43+
"showQuickFix",
44+
"showReferences",
45+
"sortTargets",
46+
"toggleLineBreakpoint",
47+
"toggleLineComment",
48+
"unfoldRegion",
49+
] as const;
50+
51+
const complexActionNames = [
52+
"callAsFunction",
53+
"editNew",
54+
"executeCommand",
55+
"generateSnippet",
56+
"getText",
57+
"highlight",
58+
"insertSnippet",
59+
"moveToTarget",
60+
"pasteFromClipboard",
61+
"replace",
62+
"replaceWithTarget",
63+
"rewrapWithPairedDelimiter",
64+
"swapTargets",
65+
"wrapWithPairedDelimiter",
66+
"wrapWithSnippet",
67+
] as const;
68+
69+
export const actionNames = [
70+
...simpleActionNames,
71+
...complexActionNames,
72+
] as const;
73+
74+
export type SimpleActionName = (typeof simpleActionNames)[number];
75+
export type ActionType = (typeof actionNames)[number];
76+
77+
/**
78+
* A simple action takes only a single target and no other arguments.
79+
*/
80+
export interface SimpleActionDescriptor {
81+
name: SimpleActionName;
82+
target: PartialTargetDescriptor;
83+
}
84+
85+
export interface BringMoveActionDescriptor {
86+
name: "replaceWithTarget" | "moveToTarget";
87+
source: PartialTargetDescriptor;
88+
destination: DestinationDescriptor;
89+
}
90+
91+
export interface CallActionDescriptor {
92+
name: "callAsFunction";
93+
94+
/**
95+
* The target to use as the function to be called.
96+
*/
97+
callee: PartialTargetDescriptor;
98+
99+
/**
100+
* The target to wrap in a function call.
101+
*/
102+
argument: PartialTargetDescriptor;
103+
}
104+
105+
export interface SwapActionDescriptor {
106+
name: "swapTargets";
107+
target1: PartialTargetDescriptor;
108+
target2: PartialTargetDescriptor;
109+
}
110+
111+
export interface WrapWithPairedDelimiterActionDescriptor {
112+
name: "wrapWithPairedDelimiter" | "rewrapWithPairedDelimiter";
113+
left: string;
114+
right: string;
115+
target: PartialTargetDescriptor;
116+
}
117+
118+
export interface PasteActionDescriptor {
119+
name: "pasteFromClipboard";
120+
destination: DestinationDescriptor;
121+
}
122+
123+
export interface GenerateSnippetActionDescriptor {
124+
name: "generateSnippet";
125+
snippetName?: string;
126+
target: PartialTargetDescriptor;
127+
}
128+
129+
interface NamedInsertSnippetArg {
130+
type: "named";
131+
name: string;
132+
substitutions?: Record<string, string>;
133+
}
134+
interface CustomInsertSnippetArg {
135+
type: "custom";
136+
body: string;
137+
scopeType?: ScopeType;
138+
substitutions?: Record<string, string>;
139+
}
140+
export type InsertSnippetArg = NamedInsertSnippetArg | CustomInsertSnippetArg;
141+
142+
export interface InsertSnippetActionDescriptor {
143+
name: "insertSnippet";
144+
snippetDescription: InsertSnippetArg;
145+
destination: DestinationDescriptor;
146+
}
147+
148+
interface NamedWrapWithSnippetArg {
149+
type: "named";
150+
name: string;
151+
variableName: string;
152+
}
153+
interface CustomWrapWithSnippetArg {
154+
type: "custom";
155+
body: string;
156+
variableName?: string;
157+
scopeType?: ScopeType;
158+
}
159+
export type WrapWithSnippetArg =
160+
| NamedWrapWithSnippetArg
161+
| CustomWrapWithSnippetArg;
162+
163+
export interface WrapWithSnippetActionDescriptor {
164+
name: "wrapWithSnippet";
165+
snippetDescription: WrapWithSnippetArg;
166+
target: PartialTargetDescriptor;
167+
}
168+
169+
export interface ExecuteCommandOptions {
170+
commandArgs?: any[];
171+
ensureSingleEditor?: boolean;
172+
ensureSingleTarget?: boolean;
173+
restoreSelection?: boolean;
174+
showDecorations?: boolean;
175+
}
176+
177+
export interface ExecuteCommandActionDescriptor {
178+
name: "executeCommand";
179+
commandId: string;
180+
options?: ExecuteCommandOptions;
181+
target: PartialTargetDescriptor;
182+
}
183+
184+
export type ReplaceWith = string[] | { start: number };
185+
186+
export interface ReplaceActionDescriptor {
187+
name: "replace";
188+
replaceWith: ReplaceWith;
189+
destination: DestinationDescriptor;
190+
}
191+
192+
export interface HighlightActionDescriptor {
193+
name: "highlight";
194+
highlightId?: string;
195+
target: PartialTargetDescriptor;
196+
}
197+
198+
export interface EditNewActionDescriptor {
199+
name: "editNew";
200+
destination: DestinationDescriptor;
201+
}
202+
203+
export interface GetTextActionOptions {
204+
showDecorations?: boolean;
205+
ensureSingleTarget?: boolean;
206+
}
207+
208+
export interface GetTextActionDescriptor {
209+
name: "getText";
210+
options?: GetTextActionOptions;
211+
target: PartialTargetDescriptor;
212+
}
213+
214+
export type ActionDescriptor =
215+
| SimpleActionDescriptor
216+
| BringMoveActionDescriptor
217+
| SwapActionDescriptor
218+
| CallActionDescriptor
219+
| PasteActionDescriptor
220+
| ExecuteCommandActionDescriptor
221+
| ReplaceActionDescriptor
222+
| HighlightActionDescriptor
223+
| GenerateSnippetActionDescriptor
224+
| InsertSnippetActionDescriptor
225+
| WrapWithSnippetActionDescriptor
226+
| WrapWithPairedDelimiterActionDescriptor
227+
| EditNewActionDescriptor
228+
| GetTextActionDescriptor;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type { ActionDescriptor } from "./ActionDescriptor";
2+
3+
export interface CommandV6 {
4+
/**
5+
* The version number of the command API
6+
*/
7+
version: 6;
8+
9+
/**
10+
* The spoken form of the command if issued from a voice command system
11+
*/
12+
spokenForm?: string;
13+
14+
/**
15+
* If the command is issued from a voice command system, this boolean indicates
16+
* whether we should use the pre phrase snapshot. Only set this to true if the
17+
* voice command system issues a pre phrase signal at the start of every
18+
* phrase.
19+
*/
20+
usePrePhraseSnapshot: boolean;
21+
22+
/**
23+
* The action to perform. This field contains everything necessary to actually
24+
* perform the action. The other fields are just metadata.
25+
*/
26+
action: ActionDescriptor;
27+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import {
2+
PartialListTargetDescriptor,
3+
PartialPrimitiveTargetDescriptor,
4+
PartialRangeTargetDescriptor,
5+
} from "./PartialTargetDescriptor.types";
6+
7+
/**
8+
* The insertion mode to use when inserting relative to a target.
9+
* - `before` inserts before the target. Depending on the target, a delimiter
10+
* may be inserted after the inserted text.
11+
* - `after` inserts after the target. Depending on the target, a delimiter may
12+
* be inserted before the inserted text.
13+
* - `to` replaces the target. However, this insertion mode may also be used
14+
* when the target is really only a pseudo-target. For example, you could say
15+
* `"bring type air to bat"` even if `bat` doesn't already have a type. In
16+
* that case, `"take type bat"` wouldn't work, so `"type bat"` is really just
17+
* a pseudo-target in that situation.
18+
*/
19+
export type InsertionMode = "before" | "after" | "to";
20+
21+
export interface PrimitiveDestinationDescriptor {
22+
type: "primitive";
23+
24+
/**
25+
* The insertion mode to use when inserting relative to {@link target}.
26+
*/
27+
insertionMode: InsertionMode;
28+
29+
target:
30+
| PartialPrimitiveTargetDescriptor
31+
| PartialRangeTargetDescriptor
32+
| PartialListTargetDescriptor;
33+
}
34+
35+
/**
36+
* A list of destinations. This is used when the user uses more than one insertion mode
37+
* in a single command. For example, `"bring air after bat and before cap"`.
38+
*/
39+
export interface ListDestinationDescriptor {
40+
type: "list";
41+
destinations: PrimitiveDestinationDescriptor[];
42+
}
43+
44+
/**
45+
* An implicit destination. This is used for e.g. `"bring air"` (note the user
46+
* doesn't explicitly specify the destination), or `"snip funk"`.
47+
*/
48+
export interface ImplicitDestinationDescriptor {
49+
type: "implicit";
50+
}
51+
52+
export type DestinationDescriptor =
53+
| ListDestinationDescriptor
54+
| PrimitiveDestinationDescriptor
55+
| ImplicitDestinationDescriptor;

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

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -268,21 +268,21 @@ export interface InferPreviousMarkModifier {
268268
type: "inferPreviousMark";
269269
}
270270

271-
export type TargetPosition = "before" | "after" | "start" | "end";
271+
export interface StartOfModifier {
272+
type: "startOf";
273+
}
272274

273-
export interface PositionModifier {
274-
type: "position";
275-
position: TargetPosition;
275+
export interface EndOfModifier {
276+
type: "endOf";
276277
}
277278

278-
export interface PartialPrimitiveTargetDescriptor {
279-
type: "primitive";
280-
mark?: PartialMark;
279+
export interface HeadModifier {
280+
type: "extendThroughStartOf";
281281
modifiers?: Modifier[];
282282
}
283283

284-
export interface HeadTailModifier {
285-
type: "extendThroughStartOf" | "extendThroughEndOf";
284+
export interface TailModifier {
285+
type: "extendThroughEndOf";
286286
modifiers?: Modifier[];
287287
}
288288

@@ -326,14 +326,16 @@ export interface RangeModifier {
326326
}
327327

328328
export type Modifier =
329-
| PositionModifier
329+
| StartOfModifier
330+
| EndOfModifier
330331
| InteriorOnlyModifier
331332
| ExcludeInteriorModifier
332333
| ContainingScopeModifier
333334
| EveryScopeModifier
334335
| OrdinalScopeModifier
335336
| RelativeScopeModifier
336-
| HeadTailModifier
337+
| HeadModifier
338+
| TailModifier
337339
| LeadingModifier
338340
| TrailingModifier
339341
| RawSelectionModifier
@@ -348,6 +350,12 @@ export type Modifier =
348350
// vertical puts a selection on each line vertically between the two targets
349351
export type PartialRangeType = "continuous" | "vertical";
350352

353+
export interface PartialPrimitiveTargetDescriptor {
354+
type: "primitive";
355+
mark?: PartialMark;
356+
modifiers?: Modifier[];
357+
}
358+
351359
export interface PartialRangeTargetDescriptor {
352360
type: "range";
353361
anchor: PartialPrimitiveTargetDescriptor | ImplicitTargetDescriptor;

0 commit comments

Comments
 (0)