File Coverage

lib/Kephra/Edit/Goto.pm
Criterion Covered Total %
statement 6 107 5.6
branch 0 56 0.0
condition 0 15 0.0
subroutine 2 17 11.7
pod 0 12 0.0
total 8 207 3.8


line stmt bran cond sub pod time code
1             package Kephra::Edit::Goto;
2             our $VERSION = '0.11';
3            
4 1     1   1203 use strict;
  1         3  
  1         40  
5 1     1   7 use warnings;
  1         2  
  1         1602  
6             #
7             # internal calls
8             #
9 0     0     sub _ep_ref { Kephra::App::EditPanel::_ref() }
10 0     0     sub _center_caret { Kephra::Edit::_center_caret() }
11             sub _pos {
12 0     0     my $ep = _ep_ref();
13 0           my $pos = shift;
14 0 0         $pos += $ep->GetLength if $pos < 0;
15 0           $ep->GotoPos($pos);
16 0           $ep->EnsureCaretVisible();
17             }
18             #
19             # simple jump calls
20             #
21 0     0 0   sub pos { position(@_) }
22             sub position { # jump caret to character based text position
23 0     0 0   my $pos = shift;
24 0 0         return unless $pos;
25 0           my $ep = _ep_ref();
26 0           my $max = $ep->GetLength;
27 0           my $fvl = $ep->GetFirstVisibleLine;
28 0           my $visible = $ep->GetLineVisible( $ep->LineFromPosition($pos) );
29            
30 0 0         $pos += $max if $pos < 0;
31 0 0         $pos = 0 if $pos < 0;
32 0 0         $pos = $max if $pos > $max;
33 0           $ep->SetCurrentPos($pos);
34 0           $ep->SetSelection ($pos, $pos);
35 0           $ep->SearchAnchor;
36             #$visible ? $ep->ScrollToLine($fvl) : _center_caret();
37 0           $ep->EnsureCaretVisible;
38 0           $ep->EnsureVisible( $ep->LineFromPosition($pos) );
39             #_center_caret();
40             }
41             sub next_visible_pos {
42 0     0 0   my $ep = _ep_ref();
43 0           my $line = $ep->GetCurrentLine();
44 0 0         return if $ep->GetLineVisible($line);
45 0           $line = $ep->GetFoldParent($line) until $ep->GetLineVisible($line);
46 0           $ep->GotoLine($line);
47 0           _center_caret();
48             }
49            
50             sub line {
51 0     0 0   my $ep = _ep_ref();
52 0           my $l18n = Kephra::API::localisation()->{dialog}{edit};
53 0           my $line = Kephra::Dialog::get_number(
54             $l18n->{goto_line_input},
55             $l18n->{goto_line_headline},
56             $ep->GetCurrentLine + 1
57             );
58 0 0         line_nr( $line - 1) unless $line == &Wx::wxCANCEL;
59             }
60 0     0 0   sub line_nr { position( _ep_ref()->PositionFromLine( shift ) ) }
61            
62             sub last_edit {
63 0     0 0   my $pos = Kephra::Document::Data::get_attribute('edit_pos');
64 0 0         position( $pos ) if defined $pos;
65             }
66            
67             #
68             # block navigation
69             #
70 0     0 0   sub prev_block{ _ep_ref()->CmdKeyExecute(&Wx::wxSTC_CMD_PARAUP) }
71 0     0 0   sub next_block{ _ep_ref()->CmdKeyExecute(&Wx::wxSTC_CMD_PARADOWN) }
72             #
73             # brace navigation
74             #
75             sub prev_brace {
76 0     0 0   my $ep = _ep_ref();
77 0           my $oldpos = my $pos = $ep->GetCurrentPos;
78 0           my $braceleft = 1; # is brace left to caret
79            
80 0 0         $braceleft--, $pos-- if $ep->BraceMatch($pos-1) > -1;
81 0           $ep->GotoPos($pos - 1);
82 0           $ep->SearchAnchor();
83 0           my $newpos = $ep->SearchPrev(&Wx::wxSTC_FIND_REGEXP, '[{}()\[\]]');
84 0 0         $newpos++ if $ep->BraceMatch($newpos) > $newpos;
85 0 0 0       $newpos-- if not $braceleft and $newpos == $ep->BraceMatch($pos)+1;
86 0 0         $newpos > -1 ? position($newpos) : position($oldpos);
87             }
88            
89             sub next_brace {
90 0     0 0   my $ep = _ep_ref( );
91 0           my $oldpos = my $pos = $ep->GetCurrentPos;
92 0           my $braceleft = 0; # is brace left to caret
93              
94 0 0 0       $braceleft++, $pos--
95             if $ep->BraceMatch($pos-1) > -1 and $ep->BraceMatch($pos) == -1;
96 0           $ep->GotoPos($oldpos + 1);
97 0           $ep->SearchAnchor();
98 0           my $newpos = $ep->SearchNext(&Wx::wxSTC_FIND_REGEXP, '[{}()\[\]]');
99 0 0         $newpos++ if $ep->BraceMatch($newpos) > $newpos;
100 0 0 0       $newpos++ if not $braceleft and $newpos == $ep->BraceMatch($pos);
101 0 0         $newpos > -1 ? position($newpos) : position($oldpos);
102             }
103            
104             sub prev_related_brace {
105 0     0 0   my $ep = _ep_ref();
106 0           my $pos = $ep->GetCurrentPos;
107 0           my $braceright = 1; # is brace right to caret
108 0           my $matchpos = $ep->BraceMatch(--$pos);
109 0 0         $braceright--, $matchpos = $ep->BraceMatch(++$pos) if $matchpos == -1;
110 0 0         if ($matchpos == -1) { prev_brace() }
  0            
111             else {
112 0 0         if ($matchpos < $pos) {
113 0 0         $braceright ? position($matchpos) : position($matchpos+1);
114             }
115             else { # when there is no matching brace
116 0           my $open_char = chr $ep->GetCharAt($pos);
117 0           my $close_char = chr $ep->GetCharAt($matchpos);
118 0           $ep->GotoPos($pos);
119 0           $ep->SearchAnchor();
120 0           my $next_open = $ep->SearchPrev(0, $open_char);
121 0           $ep->GotoPos($pos);
122 0           $ep->SearchAnchor();
123 0           my $next_close = $ep->SearchPrev(0, $close_char);
124 0 0 0       if ($next_open ==-1 and $next_close == -1) {
125 0           $ep->GotoPos($ep->GetLength);
126 0           $ep->SearchAnchor();
127 0           position( $ep->SearchPrev(0, $close_char) );
128             } else {
129 0 0         $next_open > $next_close
130             ? position( $next_open + 1 )
131             : position( $next_close );
132             }
133             }
134             }
135             }
136            
137             sub next_related_brace {
138 0     0 0   my $ep = _ep_ref();
139 0           my $pos = $ep->GetCurrentPos;
140 0           my $braceleft = 1; # is brace left to caret
141 0           my $matchpos = $ep->BraceMatch($pos);
142 0 0         $braceleft--, $matchpos = $ep->BraceMatch(--$pos) if $matchpos == -1;
143 0 0         if ($matchpos == -1) { next_brace() }
  0            
144             else {
145 0 0         if ($matchpos > $pos) {
146 0 0         $braceleft ? position($matchpos+1) : position($matchpos);
147             }
148             else { # when there is no matching brace
149 0           my $open_char = chr $ep->GetCharAt($matchpos);
150 0           my $close_char = chr $ep->GetCharAt($pos);
151 0           $ep->GotoPos($pos + 1);
152 0           $ep->SearchAnchor();
153 0           my $next_open = $ep->SearchNext(0, $open_char);
154 0           $ep->GotoPos($pos + 1);
155 0           $ep->SearchAnchor();
156 0           my $next_close = $ep->SearchNext(0, $close_char);
157 0 0 0       if ($next_open ==-1 and $next_close == -1) {
158 0           $ep->GotoPos(0);
159 0           $ep->SearchAnchor();
160 0           position( $ep->SearchNext(0, $open_char) );
161             } else {
162 0 0         $next_open < $next_close
163             ? position( $next_open + 1 )
164             : position( $next_close );
165             }
166             }
167             }
168             }
169            
170             1;
171             __END__