Text-Treesitter

 view release on metacpan or  search on metacpan

examples/viewtree.pl  view on Meta::CPAN

      $str->append( build_leader_string( \@positions ) );
      my $prevcol = @positions ? $positions[-1][1] + 1 : 0;
      $str->append( " " x ( $col - $prevcol ) );

      push @positions, [ $col, $endcol - 1 ];

      my $is_named = $node->is_named;

      $str->append_tagged( substr( $line, $col, $len ),
         fgindex => $has_children ? COLOUR_GREEN :
                    $is_named     ? COLOUR_MAGENTA :
                                    COLOUR_YELLOW,
      );
      if( defined $fieldname or $is_named ) {
         $str->append( " "x( length( $line ) - $endcol ) );

         $str->append( " $fieldname:" ) if defined $fieldname;
         $str->append_tagged( sprintf( ' (%s)', $node->type ),
            $node->type eq "ERROR" ? ( fgindex => COLOUR_RED ) : (),
         ) if $is_named;
      }

      $str->say_to_terminal;
   }

   print build_leader_string( \@positions ), "\n";
}

sub extract_nodes_on_line
{
   my ( $lineidx, $node ) = @_;

   return ( $node ) if $node->start_row == $lineidx and $node->end_row == $lineidx;

   my @ret;
   foreach my $child ( $node->child_nodes ) {
      my $childstart = $child->start_row;
      last if $childstart > $lineidx;

      my $childend = $child->end_row;
      next if $childend < $lineidx;

      push @ret, extract_nodes_on_line( $lineidx, $child ) if
         $childstart <= $lineidx and $childend >= $lineidx;
   }

   # If @ret is empty that means $node is the leaf node that covered the
   # -entire- line
   return $node if !@ret;

   return @ret;
}

if( defined $FILE ) {
   my $tree = $ts->parse_file( $FILE );
   my $root = $tree->root_node;

   # We can't call print_tree_flamegraph on text spanning multiple lines. Also
   # the output will be huge and unusable. Split it per line and only output
   # the nodes contained entirely within each line.
   my @lines = split m/\n/, $root->text;

   foreach my $lineidx ( 0 .. $#lines ) {
      my $line = $lines[$lineidx];

      if( !length $line ) {
         print "\n";
         next;
      }

      my @linenodes = extract_nodes_on_line( $lineidx, $root );

      if( @linenodes ) {
         print "\n" if $lineidx > 0;
         print_tree_flamegraph( $line, $lineidx, map { [ undef, $_ ] } @linenodes );
      }
      print "$line\n";
   }

   exit;
}

while( defined( my $line = $term->readline( "> " ) ) ) {
   my $tree = $ts->parse_string( $line );

   print_tree_flamegraph( $line, 0, [ undef, $tree->root_node ] );

   print "$line\n";
}



( run in 0.588 second using v1.01-cache-2.11-cpan-5511b514fd6 )