diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 78d25c1a5ba8..09b55d7de235 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -1,4 +1,4 @@ -use std::ops::Deref; +use std::{fmt::Write, ops::Deref}; use super::*; @@ -1473,7 +1473,57 @@ fn tree_sitter_subtree( .root_node() .descendant_for_byte_range(from, to) { - let contents = format!("```tsq\n{}\n```", selected_node.to_sexp()); + fn pretty_print_node( + node: Node<'_>, + sexpr: &mut String, + is_root: bool, + field_name: Option<&str>, + depth: usize, + ) -> anyhow::Result<()> { + fn is_visible(node: Node<'_>) -> bool { + node.is_missing() + || (node.is_named() && node.language().node_kind_is_visible(node.kind_id())) + } + + if is_visible(node) { + write!(sexpr, "{:depth$}", "")?; + + if let Some(field_name) = field_name { + write!(sexpr, "{}: ", field_name)?; + } + + write!(sexpr, "({}", node.kind())?; + } else if is_root { + write!(sexpr, "(\"{}\")", node.kind())?; + } + + for child_idx in 0..node.child_count() { + if let Some(child) = node.child(child_idx) { + if is_visible(child) { + sexpr.push('\n'); + } + + pretty_print_node( + child, + sexpr, + false, + node.field_name_for_child(child_idx as u32), + depth + 2, + )?; + } + } + + if is_visible(node) { + write!(sexpr, ")")?; + } + + Ok(()) + } + + let mut sexpr = String::new(); + pretty_print_node(selected_node, &mut sexpr, true, None, 0)?; + + let contents = format!("```tsq\n{}\n```", sexpr); let callback = async move { let call: job::Callback =