Skip to content

Commit 072443a

Browse files
Updated source and that mark for replace action (#1884)
Fixes #1883 ## Checklist - [x] 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>
1 parent 00d596a commit 072443a

File tree

4 files changed

+131
-19
lines changed

4 files changed

+131
-19
lines changed

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

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
import { FlashStyle, ReplaceWith } from "@cursorless/common";
2-
import { flatten, zip } from "lodash";
1+
import {
2+
FlashStyle,
3+
RangeExpansionBehavior,
4+
ReplaceWith,
5+
} from "@cursorless/common";
6+
import { zip } from "lodash";
37
import { RangeUpdater } from "../core/updateSelections/RangeUpdater";
4-
import { performEditsAndUpdateSelections } from "../core/updateSelections/updateSelections";
8+
import { performEditsAndUpdateSelectionsWithBehavior } from "../core/updateSelections/updateSelections";
59
import { ide } from "../singletons/ide.singleton";
6-
import { Destination } from "../typings/target.types";
10+
import { SelectionWithEditor } from "../typings/Types";
11+
import { Destination, Target } from "../typings/target.types";
712
import { flashTargets, runForEachEditor } from "../util/targetUtils";
813
import { ActionReturnValue } from "./actions.types";
914

@@ -47,30 +52,49 @@ export default class Replace {
4752
}
4853

4954
const edits = zip(destinations, texts).map(([destination, text]) => ({
50-
edit: destination!.constructChangeEdit(text!),
5155
editor: destination!.editor,
56+
target: destination!.target,
57+
edit: destination!.constructChangeEdit(text!),
5258
}));
5359

54-
const thatMark = flatten(
55-
await runForEachEditor(
56-
edits,
57-
(edit) => edit.editor,
58-
async (editor, edits) => {
59-
const [updatedSelections] = await performEditsAndUpdateSelections(
60+
const sourceTargets: Target[] = [];
61+
const thatSelections: SelectionWithEditor[] = [];
62+
63+
await runForEachEditor(
64+
edits,
65+
(edit) => edit.editor,
66+
async (editor, edits) => {
67+
const contentSelections = {
68+
selections: edits.map(({ target }) => target.contentSelection),
69+
};
70+
const editSelections = {
71+
selections: edits.map(({ edit }) => edit.range.toSelection(false)),
72+
rangeBehavior: RangeExpansionBehavior.openOpen,
73+
};
74+
75+
const [updatedContentSelections, updatedEditSelections] =
76+
await performEditsAndUpdateSelectionsWithBehavior(
6077
this.rangeUpdater,
6178
ide().getEditableTextEditor(editor),
6279
edits.map(({ edit }) => edit),
63-
[destinations.map((destination) => destination.contentSelection)],
80+
[contentSelections, editSelections],
6481
);
6582

66-
return updatedSelections.map((selection) => ({
83+
for (const [edit, selection] of zip(edits, updatedContentSelections)) {
84+
sourceTargets.push(edit!.target.withContentRange(selection!));
85+
}
86+
87+
for (const [edit, selection] of zip(edits, updatedEditSelections)) {
88+
thatSelections.push({
6789
editor,
68-
selection,
69-
}));
70-
},
71-
),
90+
selection: edit!.edit
91+
.updateRange(selection!)
92+
.toSelection(selection!.isReversed),
93+
});
94+
}
95+
},
7296
);
7397

74-
return { thatSelections: thatMark };
98+
return { sourceTargets, thatSelections };
7599
}
76100
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@ abstract class SortBase implements SimpleAction {
3535

3636
const sortedTexts = this.sortTexts(unsortedTexts);
3737

38-
return this.actions.replace.run(
38+
const { thatSelections } = await this.actions.replace.run(
3939
sortedTargets.map((target) => target.toDestination("to")),
4040
sortedTexts,
4141
);
42+
43+
return { thatSelections };
4244
}
4345
}
4446

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
languageId: plaintext
2+
command:
3+
version: 6
4+
spokenForm: place hello after air
5+
action:
6+
name: replace
7+
replaceWith: [hello]
8+
destination:
9+
type: primitive
10+
insertionMode: after
11+
target:
12+
type: primitive
13+
mark: {type: decoratedSymbol, symbolColor: default, character: a}
14+
usePrePhraseSnapshot: true
15+
spokenFormError: Action 'replace'
16+
initialState:
17+
documentContents: aaa
18+
selections:
19+
- anchor: {line: 0, character: 0}
20+
active: {line: 0, character: 0}
21+
marks:
22+
default.a:
23+
start: {line: 0, character: 0}
24+
end: {line: 0, character: 3}
25+
finalState:
26+
documentContents: aaa hello
27+
selections:
28+
- anchor: {line: 0, character: 0}
29+
active: {line: 0, character: 0}
30+
thatMark:
31+
- type: UntypedTarget
32+
contentRange:
33+
start: {line: 0, character: 4}
34+
end: {line: 0, character: 9}
35+
isReversed: false
36+
hasExplicitRange: true
37+
sourceMark:
38+
- type: UntypedTarget
39+
contentRange:
40+
start: {line: 0, character: 0}
41+
end: {line: 0, character: 3}
42+
isReversed: false
43+
hasExplicitRange: false
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
languageId: plaintext
2+
command:
3+
version: 6
4+
spokenForm: place hello to fine
5+
action:
6+
name: replace
7+
replaceWith: [hello]
8+
destination:
9+
type: primitive
10+
insertionMode: to
11+
target:
12+
type: primitive
13+
mark: {type: decoratedSymbol, symbolColor: default, character: f}
14+
usePrePhraseSnapshot: true
15+
spokenFormError: Action 'replace'
16+
initialState:
17+
documentContents: foo
18+
selections:
19+
- anchor: {line: 0, character: 0}
20+
active: {line: 0, character: 0}
21+
marks:
22+
default.f:
23+
start: {line: 0, character: 0}
24+
end: {line: 0, character: 3}
25+
finalState:
26+
documentContents: hello
27+
selections:
28+
- anchor: {line: 0, character: 0}
29+
active: {line: 0, character: 0}
30+
thatMark:
31+
- type: UntypedTarget
32+
contentRange:
33+
start: {line: 0, character: 0}
34+
end: {line: 0, character: 5}
35+
isReversed: false
36+
hasExplicitRange: true
37+
sourceMark:
38+
- type: UntypedTarget
39+
contentRange:
40+
start: {line: 0, character: 0}
41+
end: {line: 0, character: 5}
42+
isReversed: false
43+
hasExplicitRange: false

0 commit comments

Comments
 (0)