File Coverage

lib/Kephra/App/EditPanel/Fold.pm
Criterion Covered Total %
statement 6 93 6.4
branch 0 50 0.0
condition 0 48 0.0
subroutine 2 19 10.5
pod 0 11 0.0
total 8 221 3.6


line stmt bran cond sub pod time code
1             package Kephra::App::EditPanel::Fold;
2             our $VERSION = '0.05';
3            
4 1     1   1887 use strict;
  1         2  
  1         42  
5 1     1   6 use warnings;
  1         2  
  1         1729  
6             #
7             sub _ep_ref {
8 0 0   0     Kephra::App::EditPanel::is($_[0]) ? $_[0] : Kephra::App::EditPanel::_ref()
9             }
10 0     0     sub _config { Kephra::App::EditPanel::Margin::_config()->{fold} }
11 0     0     sub _attribute { 'folded_lines' }
12             #
13             sub _is_head_level { # is this the fold level of a head node ?
14 0     0     my $level = shift;
15 0 0         return 1 if ($level % 1024) < (($level >> 16) % 1024);
16             }
17             sub _is_node {
18 0     0     my $line = shift;
19 0 0         return 1 if _ep_ref()->GetFoldParent($line+1) == $line;
20             }
21             sub _get_line { #
22 0     0     my ($ep, $event) = @_;
23 0           $ep = _ep_ref();
24 0           my $line = Kephra::App::EditPanel::Margin::clicked_on_line($event);
25             # save position where context menu poped so we can fold there
26 0 0         if ($line == -1){
27 0 0 0       if (defined $event and ref $event eq 'Wx::StyledTextEvent'){
28 0           $line = $ep->LineFromPosition( $event->GetPosition() );
29             }
30 0           else { $line = $ep->GetCurrentLine() }
31             }
32 0           return $line;
33             }
34             #
35             sub store {
36 0     0 0   for my $doc_nr (@{Kephra::Document::Data::all_nr()}) {
  0            
37 0           my $ep = Kephra::Document::Data::_ep($doc_nr);
38 0           my @lines;
39 0           for (0 .. $ep->GetLineCount()-1) {
40 0 0         push @lines, $_ unless $ep->GetFoldExpanded( $_ );
41             }
42 0           Kephra::Document::Data::set_attribute( _attribute(), \@lines, $doc_nr);
43             }
44             }
45            
46             sub restore {
47 0     0 0   my $doc_nr = Kephra::Document::Data::valid_or_current_doc_nr(shift);
48 0           my $ep = Kephra::Document::Data::_ep($doc_nr);
49 0 0 0       return if $doc_nr < 0 or not ref $ep;
50 0           my $lines = Kephra::Document::Data::get_attribute( _attribute(), $doc_nr);
51 0 0         return unless ref $lines eq 'ARRAY';
52 0           for (reverse @$lines){
53 0 0         $ep->ToggleFold($_) if $ep->GetFoldExpanded($_);
54             }
55             }
56             #
57             # folding functions
58             #
59             sub toggle_here {
60 0     0 0   my $ep = _ep_ref();
61 0           my $line = _get_line(@_);
62 0           $ep->ToggleFold($line);
63 0 0 0       Kephra::Edit::Goto::next_visible_pos() if _config()->{keep_caret_visible}
64             and not $ep->GetFoldExpanded($line);
65             }
66             sub toggle_recursively {
67 0     0 0   my $ep = _ep_ref();
68 0           my $line = _get_line(@_);
69            
70            
71 0 0         unless ( _is_node( $line ) ) {
72 0           $line = $ep->GetFoldParent($line);
73 0 0         return if $line == -1;
74             }
75            
76 0           my $node_xpanded = not $ep->GetFoldExpanded($line);
77 0           my $cursor = $ep->GetLastChild($line, -1);
78 0           while ($cursor >= $line) {
79 0 0 0       $ep->ToggleFold($cursor) if $ep->GetFoldExpanded($cursor) xor $node_xpanded;
80 0           $cursor--;
81             }
82 0 0 0       Kephra::Edit::Goto::next_visible_pos() if _config()->{keep_caret_visible} and not $node_xpanded;
83             }
84 0     0 0   sub toggle_siblings { toggle_siblings_of_line( _get_line(@_) ) }
85             sub toggle_siblings_of_line {
86 0     0 0   my $ep = _ep_ref();
87 0           my $line = shift;
88 0 0 0       return if $line < 0 or $line > ($ep->GetLineCount()-1);
89 0           my $level = $ep->GetFoldLevel($line);
90 0           my $parent = $ep->GetFoldParent($line);
91 0           my $xp = not $ep->GetFoldExpanded($line);
92 0           my $first_line = $parent;
93 0           my $cursor = $ep->GetLastChild($parent, -1 );
94 0 0         ($first_line, $cursor) = (-1, $ep->GetLineCount()-2) if $parent == -1;
95 0           while ($cursor > $first_line){
96 0 0 0       $ep->ToggleFold($cursor) if $ep->GetFoldLevel($cursor) == $level
      0        
97             and ($ep->GetFoldExpanded($cursor) xor $xp);
98 0           $cursor--;
99             }
100 0 0 0       Kephra::Edit::Goto::next_visible_pos() if _config()->{keep_caret_visible}
101             and not $xp;
102 0           $ep->EnsureCaretVisible;
103             }
104            
105             sub toggle_level {
106 0     0 0   my $ep = _ep_ref();
107 0           my $line = _get_line(@_);
108 0 0 0       return if $line < 0 or $line > ($ep->GetLineCount()-1);
109 0           my $level = $ep->GetFoldLevel($line);
110 0           my $xp = not $ep->GetFoldExpanded($line);
111 0           for (0 .. $ep->GetLineCount()-1) {
112 0 0 0       $ep->ToggleFold($_) if $ep->GetFoldLevel($_) == $level
      0        
113             and ($ep->GetFoldExpanded($_) xor $xp);
114             }
115 0 0 0       Kephra::Edit::Goto::next_visible_pos() if _config()->{keep_caret_visible}
116             and not $xp;
117 0           $ep->EnsureCaretVisible;
118             }
119            
120             sub toggle_all {
121 0     0 0   my $ep = _ep_ref();
122 0           my $newline = my $oldline = $ep->GetLineCount();
123             # looking for the head of heads // capi di capi
124 0   0       while ($oldline == $newline and $oldline > 0){
125 0           $newline = --$oldline;
126 0           $newline = $ep->GetFoldParent($newline) while $ep->GetFoldParent($newline) > -1;
127             }
128 0           my $root_unfolded = $ep->GetFoldExpanded($newline);
129 0 0         $root_unfolded ? fold_all() : unfold_all();
130 0 0 0       Kephra::Edit::Goto::next_visible_pos() if _config()->{keep_caret_visible}
131             and $root_unfolded;
132             }
133             sub fold_all {
134 0     0 0   my $ep = _ep_ref();
135 0           my $cursor = $ep->GetLineCount()-1;
136 0           while ($cursor > -1) {
137 0 0         $ep->ToggleFold($cursor) if $ep->GetFoldExpanded($cursor);
138 0           $cursor--;
139             }
140             }
141             sub unfold_all {
142 0     0 0   my $ep = _ep_ref();
143 0           my $cursor = $ep->GetLineCount()-1;
144 0           while ($cursor > -1) {
145 0 0         $ep->ToggleFold($cursor) unless $ep->GetFoldExpanded($cursor);
146 0           $cursor--;
147             }
148             }
149 0     0 0   sub show_folded_children {
150             #my $ep = _ep_ref();
151             #my $parent = _get_line(@_);
152             #unless ( _is_head_level( $ep->GetFoldLevel($parent) ) ) {
153             #$parent = $ep->GetFoldParent($parent);
154             #return if $parent == -1;
155             #}
156             #$ep->ToggleFold($parent) unless $ep->GetFoldExpanded($parent);
157             #my $cursöor = $ep->GetLastChild( $parent, -1 );
158             #my $level = $ep->GetFoldLevel($parent) >> 16;
159             #while (@cursor > $parent) {
160             #$ep->ToggleFold($cursor) if $ep->GetFoldLevel($cursor) % 2048 == $level
161             #and $ep->GetFoldExpanded($cursor);
162             #$cursor--;
163             #}
164             }
165            
166             1;
167            
168             =head1 NAME
169            
170             Kephra::App::EditPanel::Fold - code folding functions
171            
172             =head1 DESCRIPTION
173            
174             =cut