File Coverage

blib/lib/App/sdview/Highlighter.pm
Criterion Covered Total %
statement 18 52 34.6
branch 0 12 0.0
condition 0 6 0.0
subroutine 6 7 85.7
pod 0 1 0.0
total 24 78 30.7


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2024 -- leonerd@leonerd.org.uk
5              
6 1     1   786 use v5.26;
  1         5  
7 1     1   8 use warnings;
  1         2  
  1         79  
8 1     1   7 use experimental 'signatures';
  1         3  
  1         9  
9              
10             package App::sdview::Highlighter 0.20;
11              
12 1         3 use constant HAVE_TEXT_TREESITTER => defined eval {
13 1         385 require Text::Treesitter;
14 0         0 require Text::Treesitter::QueryCursor;
15 0         0 require Text::Treesitter::QueryMatch;
16 1     1   340 };
  1         2  
17              
18 1     1   713 use Convert::Color;
  1         59031  
  1         87  
19 1     1   770 use Convert::Color::XTerm;
  1         5999  
  1         1142  
20              
21             # chunks of this code copypasted from Text-Treesitter/examples/highlight.pl
22              
23             my %TS_FOR_LANGUAGE;
24             my %HIGHLIGHTS_FOR_LANGUAGE;
25              
26 0           sub highlight_str ( $cls, $str, $language, %opts )
  0            
  0            
27 0     0 0   {
  0            
  0            
28 0           return unless HAVE_TEXT_TREESITTER;
29 0 0         return if $language eq "text";
30              
31 0   0       my $ts = $TS_FOR_LANGUAGE{ $language } //= eval {
32 0           Text::Treesitter->new(
33             lang_name => $language,
34             #lang_dir => $LANGUAGE_DIR,
35             )
36             };
37 0 0         defined $ts or return;
38              
39 0   0       my $query_highlight = $HIGHLIGHTS_FOR_LANGUAGE{ $language } //= eval {
40 0           $ts->load_query_file( "highlights.scm" )
41             };
42 0 0         unless( defined $query_highlight ) {
43 0           my $e = $@;
44 0           warn "Unable to load $language highlights: $e\n";
45 0           return;
46             }
47              
48             # TODO: handle injections
49              
50 0           my $tree;
51 0 0         if( defined $opts{start_byte} ) {
52 0           $tree = $ts->parse_string_range( $str, %opts{qw( start_byte end_byte )} );
53             }
54             else {
55 0           $tree = $ts->parse_string( $str );
56             }
57 0           my $root = $tree->root_node;
58              
59 0           my $qc = Text::Treesitter::QueryCursor->new;
60              
61 0           $qc->exec( $query_highlight, $root );
62              
63 0           while( my $captures = $qc->next_match_captures ) {
64 0           CAPTURE: foreach my $capturename ( sort keys $captures->%* ) {
65             # TODO: actually implement the priority logic
66 0 0         next if $capturename eq "priority";
67              
68 0           my $node = $captures->{$capturename};
69              
70 0           my $start = $tree->byte_to_char( $node->start_byte );
71 0           my $len = $tree->byte_to_char( $node->end_byte ) - $start;
72              
73 0 0         my $format = App::sdview::Style->highlight_style( $capturename )
74             or next;
75              
76 0           $str->apply_tag( $start, $len, $_, $format->{$_} ) for keys %$format;
77             }
78             }
79             }
80              
81             0x55AA;