Skip to content

Commit 69679de

Browse files
Surrounding pairs: Fall back to text based algorithm when error node is detected. (#1558)
Fixes #712 ## 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
1 parent 5253d4c commit 69679de

File tree

2 files changed

+53
-0
lines changed
  • packages
    • cursorless-engine/src/processTargets/modifiers/surroundingPair
    • cursorless-vscode-e2e/src/suite/fixtures/recorded/surroundingPair/parseTree/python

2 files changed

+53
-0
lines changed

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,18 @@ function processSurroundingPairCore(
9999
try {
100100
node = languageDefinitions.getNodeAtLocation(document, range);
101101

102+
// Error nodes are unreliable and should be ignored. Fall back to text based
103+
// algorithm.
104+
if (nodeHasError(node)) {
105+
return findSurroundingPairTextBased(
106+
editor,
107+
range,
108+
null,
109+
delimiters,
110+
scopeType,
111+
);
112+
}
113+
102114
textFragmentExtractor = getTextFragmentExtractor(document.languageId);
103115
} catch (err) {
104116
if ((err as Error).name === "UnsupportedLanguageError") {
@@ -148,3 +160,22 @@ function processSurroundingPairCore(
148160
scopeType,
149161
);
150162
}
163+
164+
function nodeHasError(node: SyntaxNode, includeChildren = false): boolean {
165+
if (nodeIsError(node)) {
166+
return true;
167+
}
168+
if (includeChildren) {
169+
if (node.children.some(nodeIsError)) {
170+
return true;
171+
}
172+
}
173+
if (node.parent != null) {
174+
return nodeHasError(node.parent, true);
175+
}
176+
return false;
177+
}
178+
179+
function nodeIsError(node: SyntaxNode): boolean {
180+
return node.type === "ERROR";
181+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
languageId: python
2+
command:
3+
version: 5
4+
spokenForm: clear pair
5+
action: {name: clearAndSetSelection}
6+
targets:
7+
- type: primitive
8+
modifiers:
9+
- type: containingScope
10+
scopeType: {type: surroundingPair, delimiter: any}
11+
usePrePhraseSnapshot: true
12+
initialState:
13+
documentContents: "def funk(words:list<str>):"
14+
selections:
15+
- anchor: {line: 0, character: 20}
16+
active: {line: 0, character: 20}
17+
marks: {}
18+
finalState:
19+
documentContents: "def funk(words:list):"
20+
selections:
21+
- anchor: {line: 0, character: 19}
22+
active: {line: 0, character: 19}

0 commit comments

Comments
 (0)