tree_sitter_edit/
editor.rs

1use crate::traversal::{traverse, Order};
2use tree_sitter::{Node, Tree};
3
4#[derive(Debug)]
5pub struct Edit {
6    pub position: usize,
7    pub delete: usize,
8    pub insert: Vec<u8>,
9}
10
11// TODO(lb): Perhaps make an associated error type so that these operations can
12// fail?
13
14/// Modify a tree-sitter parse tree when printing.
15pub trait Editor {
16    /// Does this editor have an edit for this node?
17    #[must_use]
18    fn has_edit(&self, tree: &Tree, node: &Node<'_>) -> bool;
19
20    /// Edit this node (precondition: [`Editor::has_edit`]).
21    fn edit(&self, source: &[u8], tree: &Tree, node: &Node<'_>) -> Vec<u8>;
22
23    /// Get all edits to this tree, in order.
24    ///
25    /// Edits must be ordered by start byte and must not overlap.
26    ///
27    /// [`default_in_order`] does an in-order traversal of the tree.
28    fn in_order_edits<'a>(
29        &'a self,
30        source: &'a [u8],
31        tree: &'a Tree,
32    ) -> Box<dyn Iterator<Item = Edit> + 'a> {
33        Box::new(traverse(tree.walk(), Order::Pre).filter_map(|n| {
34            if self.has_edit(tree, &n) {
35                Some(Edit {
36                    position: n.start_byte(),
37                    delete: n.end_byte() - n.start_byte(),
38                    insert: self.edit(source, tree, &n),
39                })
40            } else {
41                None
42            }
43        }))
44    }
45}