From 8e72138ef7b2ea6b7c250be1fcfcca7ff094d150 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Sat, 22 Feb 2025 14:39:50 +0100 Subject: [PATCH 1/3] Don't discard nodes with non adjacent error siblings --- .../recorded/surroundingPair/changePair.yml | 25 +++++++++++++++++++ .../TreeSitterQuery/isContainedInErrorNode.ts | 16 +++++++++++- 2 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 data/fixtures/recorded/surroundingPair/changePair.yml diff --git a/data/fixtures/recorded/surroundingPair/changePair.yml b/data/fixtures/recorded/surroundingPair/changePair.yml new file mode 100644 index 0000000000..3bfc52df27 --- /dev/null +++ b/data/fixtures/recorded/surroundingPair/changePair.yml @@ -0,0 +1,25 @@ +languageId: typescriptreact +command: + version: 7 + spokenForm: change pair + action: + name: clearAndSetSelection + target: + type: primitive + modifiers: + - type: containingScope + scopeType: {type: surroundingPair, delimiter: any} + usePrePhraseSnapshot: false +initialState: + documentContents: | +
null}>hello &
+ selections: + - anchor: {line: 0, character: 14} + active: {line: 0, character: 14} + marks: {} +finalState: + documentContents: | +
hello &
+ selections: + - anchor: {line: 0, character: 9} + active: {line: 0, character: 9} diff --git a/packages/cursorless-engine/src/languages/TreeSitterQuery/isContainedInErrorNode.ts b/packages/cursorless-engine/src/languages/TreeSitterQuery/isContainedInErrorNode.ts index 8b3c46a9bc..bbd28a125e 100644 --- a/packages/cursorless-engine/src/languages/TreeSitterQuery/isContainedInErrorNode.ts +++ b/packages/cursorless-engine/src/languages/TreeSitterQuery/isContainedInErrorNode.ts @@ -6,10 +6,24 @@ import type { SyntaxNode } from "web-tree-sitter"; * @returns True if the given node is contained in an error node */ export function isContainedInErrorNode(node: SyntaxNode) { - let currentNode: SyntaxNode | null = node; + if (node.hasError) { + return true; + } + + let currentNode: SyntaxNode | null = node.parent; while (currentNode != null) { + // Ancestral node has errors, but it was not siblings to the previous node + // that caused the problem. We don't want to discard a node when a sibling + // that isn't adjacent is erroring. if (currentNode.hasError) { + return false; + } + // A adjacent sibling node was causing the problem. ie we are right next to the error node. + if ( + currentNode.previousSibling?.isError || + currentNode.nextSibling?.isError + ) { return true; } currentNode = currentNode.parent; From 9a6c9a92c68db7ab790c5c989d34657c3b1a8659 Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Sat, 22 Feb 2025 14:45:13 +0100 Subject: [PATCH 2/3] Clean up --- .../TreeSitterQuery/isContainedInErrorNode.ts | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/packages/cursorless-engine/src/languages/TreeSitterQuery/isContainedInErrorNode.ts b/packages/cursorless-engine/src/languages/TreeSitterQuery/isContainedInErrorNode.ts index bbd28a125e..463d97e2e8 100644 --- a/packages/cursorless-engine/src/languages/TreeSitterQuery/isContainedInErrorNode.ts +++ b/packages/cursorless-engine/src/languages/TreeSitterQuery/isContainedInErrorNode.ts @@ -6,27 +6,35 @@ import type { SyntaxNode } from "web-tree-sitter"; * @returns True if the given node is contained in an error node */ export function isContainedInErrorNode(node: SyntaxNode) { + // This node or one of it descendants is an error node if (node.hasError) { return true; } - let currentNode: SyntaxNode | null = node.parent; + let ancestorNode: SyntaxNode | null = node.parent; - while (currentNode != null) { - // Ancestral node has errors, but it was not siblings to the previous node - // that caused the problem. We don't want to discard a node when a sibling - // that isn't adjacent is erroring. - if (currentNode.hasError) { + while (ancestorNode != null) { + // Ancestral node is an error node + if (ancestorNode.isError) { + return true; + } + + // Ancestral node has errors, but it was not siblings to the previous node. + // We don't want to discard a node when a sibling that isn't adjacent is + // erroring. + if (ancestorNode.hasError) { return false; } + // A adjacent sibling node was causing the problem. ie we are right next to the error node. if ( - currentNode.previousSibling?.isError || - currentNode.nextSibling?.isError + ancestorNode.previousSibling?.isError || + ancestorNode.nextSibling?.isError ) { return true; } - currentNode = currentNode.parent; + + ancestorNode = ancestorNode.parent; } return false; From b9453d9104cc81285db0e68816743178c76d6dbd Mon Sep 17 00:00:00 2001 From: Andreas Arvidsson Date: Sat, 22 Feb 2025 16:06:06 +0100 Subject: [PATCH 3/3] Empty commit