diff --git a/src/syntax.rs b/src/syntax.rs
index 744479e61..84eae013f 100644
--- a/src/syntax.rs
+++ b/src/syntax.rs
@@ -48,8 +48,10 @@ impl<'a> fmt::Debug for ChangeKind<'a> {
/// Fields that are common to both `Syntax::List` and `Syntax::Atom`.
pub struct SyntaxInfo<'a> {
+ /// The previous node with the same parent as this one.
+ previous_sibling: Cell>>,
/// The next node with the same parent as this one.
- pub next_sibling: Cell >>,
+ next_sibling: Cell >>,
/// The syntax node that occurs before this one, in a depth-first
/// tree traversal.
pub prev: Cell >>,
@@ -76,6 +78,7 @@ pub struct SyntaxInfo<'a> {
impl<'a> SyntaxInfo<'a> {
pub fn new() -> Self {
Self {
+ previous_sibling: Cell::new(None),
next_sibling: Cell::new(None),
prev: Cell::new(None),
parent: Cell::new(None),
@@ -424,6 +427,7 @@ fn set_content_id(nodes: &[&Syntax], existing: &mut HashMap) {
}
pub fn init_next_prev<'a>(roots: &[&'a Syntax<'a>]) {
+ set_prev_sibling(roots);
set_next_sibling(roots);
set_prev(roots, None);
set_prev_is_contiguous(roots);
@@ -446,6 +450,21 @@ fn set_unique_id<'a>(nodes: &[&'a Syntax<'a>], next_id: &mut NonZeroU32) {
}
}
+fn set_prev_sibling<'a>(nodes: &[&'a Syntax<'a>]) {
+ for (i, node) in nodes.iter().enumerate() {
+ if i == 0 {
+ continue;
+ }
+
+ let sibling = nodes.get(i - 1).copied();
+ node.info().previous_sibling.set(sibling);
+
+ if let List { children, .. } = node {
+ set_prev_sibling(children);
+ }
+ }
+}
+
fn set_next_sibling<'a>(nodes: &[&'a Syntax<'a>]) {
for (i, node) in nodes.iter().enumerate() {
let sibling = nodes.get(i + 1).copied();