Skip to content

Commit 662065c

Browse files
Fixed problem with strong containment when cursor is after matching pair (#1574)
Fixes #908 ## 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: Pokey Rule <[email protected]>
1 parent 34d5672 commit 662065c

File tree

8 files changed

+138
-9
lines changed

8 files changed

+138
-9
lines changed

packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/findDelimiterPairContainingSelection.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1+
import {
2+
SimpleSurroundingPairName,
3+
SurroundingPairScopeType,
4+
} from "@cursorless/common";
5+
import { generateUnmatchedDelimiters } from "./generateUnmatchedDelimiters";
16
import { getSurroundingPairOffsets } from "./getSurroundingPairOffsets";
27
import {
3-
SurroundingPairOffsets,
4-
PossibleDelimiterOccurrence,
58
Offsets,
9+
PossibleDelimiterOccurrence,
10+
SurroundingPairOffsets,
611
} from "./types";
7-
import { generateUnmatchedDelimiters } from "./generateUnmatchedDelimiters";
8-
import { SimpleSurroundingPairName } from "@cursorless/common";
912

1013
/**
1114
* Looks for a surrounding pair that contains the selection, returning null if none is found.
@@ -40,6 +43,7 @@ export function findDelimiterPairContainingSelection(
4043
delimiterOccurrences: PossibleDelimiterOccurrence[],
4144
acceptableDelimiters: SimpleSurroundingPairName[],
4245
selectionOffsets: Offsets,
46+
scopeType: SurroundingPairScopeType,
4347
): SurroundingPairOffsets | null {
4448
// Accept any delimiter when scanning right
4549
const acceptableRightDelimiters = acceptableDelimiters;
@@ -86,6 +90,18 @@ export function findDelimiterPairContainingSelection(
8690
// If left delimiter is left of our selection, we return it. Otherwise
8791
// loop back and continue scanning outwards.
8892
if (leftDelimiterOccurrence.offsets.start <= selectionOffsets.start) {
93+
if (
94+
scopeType.requireStrongContainment &&
95+
!(
96+
leftDelimiterOccurrence.offsets.end <= selectionOffsets.start &&
97+
rightDelimiterOccurrence.offsets.start >= selectionOffsets.end
98+
)
99+
) {
100+
// If we require strong containment, continue searching for something
101+
// bigger if the selection overlaps either delimiter
102+
continue;
103+
}
104+
89105
return getSurroundingPairOffsets(
90106
leftDelimiterOccurrence,
91107
rightDelimiterOccurrence,

packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/findSurroundingPairCore.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,5 +74,6 @@ export function findSurroundingPairCore(
7474
delimiterOccurrences,
7575
acceptableDelimiters,
7676
selectionOffsets,
77+
scopeType,
7778
);
7879
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
languageId: markdown
2+
command:
3+
version: 5
4+
spokenForm: clear every short paint
5+
action: {name: clearAndSetSelection}
6+
targets:
7+
- type: primitive
8+
modifiers:
9+
- type: everyScope
10+
scopeType: {type: boundedNonWhitespaceSequence}
11+
usePrePhraseSnapshot: true
12+
initialState:
13+
documentContents: foo(aa|aa-().c_d bb|bb-().'')
14+
selections:
15+
- anchor: {line: 0, character: 5}
16+
active: {line: 0, character: 5}
17+
marks: {}
18+
finalState:
19+
documentContents: foo( )
20+
selections:
21+
- anchor: {line: 0, character: 4}
22+
active: {line: 0, character: 4}
23+
- anchor: {line: 0, character: 5}
24+
active: {line: 0, character: 5}

packages/cursorless-vscode-e2e/src/suite/fixtures/recorded/selectionTypes/changeEveryShortPaintPairParen.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ initialState:
2222
start: {line: 0, character: 3}
2323
end: {line: 0, character: 4}
2424
finalState:
25-
documentContents: foo( )
25+
documentContents: " "
2626
selections:
27-
- anchor: {line: 0, character: 4}
28-
active: {line: 0, character: 4}
29-
- anchor: {line: 0, character: 5}
30-
active: {line: 0, character: 5}
27+
- anchor: {line: 0, character: 0}
28+
active: {line: 0, character: 0}
29+
- anchor: {line: 0, character: 1}
30+
active: {line: 0, character: 1}
3131
fullTargets: [{type: primitive, mark: {type: decoratedSymbol, symbolColor: default, character: (}, modifiers: [{type: everyScope, scopeType: {type: boundedNonWhitespaceSequence}}, {type: containingScope, scopeType: {type: surroundingPair, delimiter: any}}]}]
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
languageId: plaintext
2+
command:
3+
version: 5
4+
spokenForm: clear short paint
5+
action: {name: clearAndSetSelection}
6+
targets:
7+
- type: primitive
8+
modifiers:
9+
- type: containingScope
10+
scopeType: {type: boundedNonWhitespaceSequence}
11+
usePrePhraseSnapshot: true
12+
initialState:
13+
documentContents: (hello)
14+
selections:
15+
- anchor: {line: 0, character: 0}
16+
active: {line: 0, character: 0}
17+
marks: {}
18+
finalState:
19+
documentContents: ""
20+
selections:
21+
- anchor: {line: 0, character: 0}
22+
active: {line: 0, character: 0}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
languageId: plaintext
2+
command:
3+
version: 5
4+
spokenForm: clear short paint
5+
action: {name: clearAndSetSelection}
6+
targets:
7+
- type: primitive
8+
modifiers:
9+
- type: containingScope
10+
scopeType: {type: boundedNonWhitespaceSequence}
11+
usePrePhraseSnapshot: true
12+
initialState:
13+
documentContents: (hello)
14+
selections:
15+
- anchor: {line: 0, character: 7}
16+
active: {line: 0, character: 7}
17+
marks: {}
18+
finalState:
19+
documentContents: ""
20+
selections:
21+
- anchor: {line: 0, character: 0}
22+
active: {line: 0, character: 0}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
languageId: plaintext
2+
command:
3+
version: 5
4+
spokenForm: clear short paint
5+
action: {name: clearAndSetSelection}
6+
targets:
7+
- type: primitive
8+
modifiers:
9+
- type: containingScope
10+
scopeType: {type: boundedNonWhitespaceSequence}
11+
usePrePhraseSnapshot: true
12+
initialState:
13+
documentContents: (hello)
14+
selections:
15+
- anchor: {line: 0, character: 6}
16+
active: {line: 0, character: 6}
17+
marks: {}
18+
finalState:
19+
documentContents: ()
20+
selections:
21+
- anchor: {line: 0, character: 1}
22+
active: {line: 0, character: 1}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
languageId: plaintext
2+
command:
3+
version: 5
4+
spokenForm: clear short paint
5+
action: {name: clearAndSetSelection}
6+
targets:
7+
- type: primitive
8+
modifiers:
9+
- type: containingScope
10+
scopeType: {type: boundedNonWhitespaceSequence}
11+
usePrePhraseSnapshot: true
12+
initialState:
13+
documentContents: (hello)
14+
selections:
15+
- anchor: {line: 0, character: 1}
16+
active: {line: 0, character: 1}
17+
marks: {}
18+
finalState:
19+
documentContents: ()
20+
selections:
21+
- anchor: {line: 0, character: 1}
22+
active: {line: 0, character: 1}

0 commit comments

Comments
 (0)