diff --git a/cli/src/tests/tree_test.rs b/cli/src/tests/tree_test.rs index c63b588b..f3792138 100644 --- a/cli/src/tests/tree_test.rs +++ b/cli/src/tests/tree_test.rs @@ -376,6 +376,45 @@ fn test_tree_cursor() { assert_eq!(copy.node().kind(), "struct_item"); } +#[test] +fn test_tree_cursor_previous_sibling() { + let mut parser = Parser::new(); + parser.set_language(get_language("rust")).unwrap(); + + let text = " + // Hi there + // This is fun! + // Another one! +"; + let tree = parser.parse(text, None).unwrap(); + + let mut cursor = tree.walk(); + assert_eq!(cursor.node().kind(), "source_file"); + + assert!(cursor.goto_last_child()); + assert_eq!(cursor.node().kind(), "line_comment"); + assert_eq!( + cursor.node().utf8_text(text.as_bytes()).unwrap(), + "// Another one!" + ); + + assert!(cursor.goto_previous_sibling()); + assert_eq!(cursor.node().kind(), "line_comment"); + assert_eq!( + cursor.node().utf8_text(text.as_bytes()).unwrap(), + "// This is fun!" + ); + + assert!(cursor.goto_previous_sibling()); + assert_eq!(cursor.node().kind(), "line_comment"); + assert_eq!( + cursor.node().utf8_text(text.as_bytes()).unwrap(), + "// Hi there" + ); + + assert!(!cursor.goto_previous_sibling()); +} + #[test] fn test_tree_cursor_fields() { let mut parser = Parser::new(); diff --git a/lib/src/tree_cursor.c b/lib/src/tree_cursor.c index 25eca482..63d22c8b 100644 --- a/lib/src/tree_cursor.c +++ b/lib/src/tree_cursor.c @@ -377,11 +377,15 @@ TreeCursorStep ts_tree_cursor_goto_previous_sibling_internal(TSTreeCursor *_self position = parent->position; uint32_t child_index = array_back(&self->stack)->child_index; const Subtree *children = ts_subtree_children((*(parent->subtree))); - for (uint32_t i = 0; i < child_index; ++i) { - position = length_add(position, ts_subtree_total_size(children[i])); - } - if (child_index > 0) + + if (child_index > 0) { + // skip first child padding since its position should match the position of the parent + position = length_add(position, ts_subtree_size(children[0])); + for (uint32_t i = 1; i < child_index; ++i) { + position = length_add(position, ts_subtree_total_size(children[i])); + } position = length_add(position, ts_subtree_padding(children[child_index])); + } array_back(&self->stack)->position = position;