diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs index 78d25c1a5ba86..5c9bdf8eaa97e 100644 --- a/helix-term/src/commands/typed.rs +++ b/helix-term/src/commands/typed.rs @@ -1,7 +1,8 @@ -use std::ops::Deref; +use std::{fmt::Write, ops::Deref}; use super::*; +use helix_core::tree_sitter::TreeCursor; use helix_view::{ apply_transaction, editor::{Action, CloseError, ConfigEvent}, @@ -1473,7 +1474,55 @@ 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, + ) { + 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, ")"); + } + } + + 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 =