mirror of
https://github.com/helix-editor/helix.git
synced 2024-11-25 02:46:17 +04:00
Select subtree within injections in :tree-sitter-subtree (#9309)
`:tree-sitter-subtree` could previously only print subtrees of nodes in the root injection layer. We can improve on that by finding the layer that contains the given byte range and printing the subtree within that layer. That gives more useful results when a selection is within an injection layer.
This commit is contained in:
parent
3011df4f35
commit
eca3ccff76
@ -1338,6 +1338,23 @@ pub fn highlight_iter<'a>(
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn descendant_for_byte_range(&self, start: usize, end: usize) -> Option<Node<'_>> {
|
||||||
|
let mut container_id = self.root;
|
||||||
|
|
||||||
|
for (layer_id, layer) in self.layers.iter() {
|
||||||
|
if layer.depth > self.layers[container_id].depth
|
||||||
|
&& layer.contains_byte_range(start, end)
|
||||||
|
{
|
||||||
|
container_id = layer_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.layers[container_id]
|
||||||
|
.tree()
|
||||||
|
.root_node()
|
||||||
|
.descendant_for_byte_range(start, end)
|
||||||
|
}
|
||||||
|
|
||||||
// Commenting
|
// Commenting
|
||||||
// comment_strings_for_pos
|
// comment_strings_for_pos
|
||||||
// is_commented
|
// is_commented
|
||||||
@ -1434,6 +1451,32 @@ fn parse(&mut self, parser: &mut Parser, source: RopeSlice) -> Result<(), Error>
|
|||||||
self.tree = Some(tree);
|
self.tree = Some(tree);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Whether the layer contains the given byte range.
|
||||||
|
///
|
||||||
|
/// If the layer has multiple ranges (i.e. combined injections), the
|
||||||
|
/// given range is considered contained if it is within the start and
|
||||||
|
/// end bytes of the first and last ranges **and** if the given range
|
||||||
|
/// starts or ends within any of the layer's ranges.
|
||||||
|
fn contains_byte_range(&self, start: usize, end: usize) -> bool {
|
||||||
|
let layer_start = self
|
||||||
|
.ranges
|
||||||
|
.first()
|
||||||
|
.expect("ranges should not be empty")
|
||||||
|
.start_byte;
|
||||||
|
let layer_end = self
|
||||||
|
.ranges
|
||||||
|
.last()
|
||||||
|
.expect("ranges should not be empty")
|
||||||
|
.end_byte;
|
||||||
|
|
||||||
|
layer_start <= start
|
||||||
|
&& layer_end >= end
|
||||||
|
&& self.ranges.iter().any(|range| {
|
||||||
|
let byte_range = range.start_byte..range.end_byte;
|
||||||
|
byte_range.contains(&start) || byte_range.contains(&end)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn generate_edits(
|
pub(crate) fn generate_edits(
|
||||||
|
@ -2117,11 +2117,7 @@ fn tree_sitter_subtree(
|
|||||||
let text = doc.text();
|
let text = doc.text();
|
||||||
let from = text.char_to_byte(primary_selection.from());
|
let from = text.char_to_byte(primary_selection.from());
|
||||||
let to = text.char_to_byte(primary_selection.to());
|
let to = text.char_to_byte(primary_selection.to());
|
||||||
if let Some(selected_node) = syntax
|
if let Some(selected_node) = syntax.descendant_for_byte_range(from, to) {
|
||||||
.tree()
|
|
||||||
.root_node()
|
|
||||||
.descendant_for_byte_range(from, to)
|
|
||||||
{
|
|
||||||
let mut contents = String::from("```tsq\n");
|
let mut contents = String::from("```tsq\n");
|
||||||
helix_core::syntax::pretty_print_tree(&mut contents, selected_node)?;
|
helix_core::syntax::pretty_print_tree(&mut contents, selected_node)?;
|
||||||
contents.push_str("\n```");
|
contents.push_str("\n```");
|
||||||
|
Loading…
Reference in New Issue
Block a user