line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Kephra::Edit;
|
2
|
|
|
|
|
|
|
our $VERSION = '0.42';
|
3
|
|
|
|
|
|
|
|
4
|
1
|
|
|
1
|
|
1127
|
use strict;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
38
|
|
5
|
1
|
|
|
1
|
|
7
|
use warnings;
|
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
3825
|
|
6
|
|
|
|
|
|
|
#
|
7
|
|
|
|
|
|
|
# internal helper function
|
8
|
|
|
|
|
|
|
#
|
9
|
0
|
|
|
0
|
|
|
sub _ep_ref { Kephra::App::EditPanel::_ref() }
|
10
|
0
|
|
|
0
|
|
|
sub _keep_focus{ Wx::Window::SetFocus( _ep_ref() ) }
|
11
|
|
|
|
|
|
|
sub _let_caret_visible {
|
12
|
0
|
|
|
0
|
|
|
my $ep = _ep_ref();
|
13
|
0
|
|
|
|
|
|
my ($selstart, $selend) = $ep->GetSelection;
|
14
|
0
|
|
|
|
|
|
my $los = $ep->LinesOnScreen;
|
15
|
0
|
0
|
|
|
|
|
if ( $selstart == $selend ) {
|
16
|
0
|
0
|
|
|
|
|
$ep->ScrollToLine($ep->GetCurrentLine - ( $los / 2 ))
|
17
|
|
|
|
|
|
|
unless $ep->GetLineVisible( $ep->GetCurrentLine() );
|
18
|
|
|
|
|
|
|
} else {
|
19
|
0
|
|
|
|
|
|
my $startline = $ep->LineFromPosition($selstart);
|
20
|
0
|
|
|
|
|
|
my $endline = $ep->LineFromPosition($selend);
|
21
|
0
|
0
|
0
|
|
|
|
$ep->ScrollToLine( $startline - (($los - $endline - $startline) / 2) )
|
22
|
|
|
|
|
|
|
unless $ep->GetLineVisible($startline)
|
23
|
|
|
|
|
|
|
and $ep->GetLineVisible($endline);
|
24
|
|
|
|
|
|
|
}
|
25
|
0
|
|
|
|
|
|
$ep->EnsureCaretVisible;
|
26
|
|
|
|
|
|
|
}
|
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
sub _center_caret {
|
29
|
0
|
|
|
0
|
|
|
my $ep = _ep_ref();
|
30
|
0
|
|
|
|
|
|
my $line = $ep->GetCurrentLine();
|
31
|
0
|
|
|
|
|
|
$ep->ScrollToLine( $line - ( $ep->LinesOnScreen / 2 ));
|
32
|
0
|
|
|
|
|
|
$ep->EnsureVisible($line);
|
33
|
0
|
|
|
|
|
|
$ep->EnsureCaretVisible();
|
34
|
|
|
|
|
|
|
}
|
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
my @pos_stack;
|
37
|
|
|
|
|
|
|
sub _save_positions {
|
38
|
0
|
|
|
0
|
|
|
my $ep = _ep_ref();
|
39
|
0
|
|
|
|
|
|
my %pos;
|
40
|
0
|
|
|
|
|
|
$pos{document} = Kephra::Document::Data::current_nr();
|
41
|
0
|
|
|
|
|
|
$pos{pos} = $ep->GetCurrentPos;
|
42
|
0
|
|
|
|
|
|
$pos{line} = $ep->GetCurrentLine;
|
43
|
0
|
|
|
|
|
|
$pos{col} = $ep->GetColumn( $pos{pos} );
|
44
|
0
|
|
|
|
|
|
$pos{sel_begin} = $ep->GetSelectionStart;
|
45
|
0
|
|
|
|
|
|
$pos{sel_end} = $ep->GetSelectionEnd;
|
46
|
0
|
|
|
|
|
|
push @pos_stack, \%pos;
|
47
|
|
|
|
|
|
|
}
|
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
sub _restore_positions {
|
50
|
0
|
|
|
0
|
|
|
my $ep = _ep_ref();
|
51
|
0
|
|
|
|
|
|
my %pos = %{ pop @pos_stack };
|
|
0
|
|
|
|
|
|
|
52
|
0
|
0
|
|
|
|
|
if (%pos) {
|
53
|
0
|
0
|
|
|
|
|
Kephra::Document::Change::to_number( $pos{document} )
|
54
|
|
|
|
|
|
|
if $pos{document} != Kephra::Document::Data::current_nr();
|
55
|
0
|
|
|
|
|
|
$ep->SetCurrentPos( $pos{pos} );
|
56
|
0
|
0
|
|
|
|
|
$ep->GotoLine( $pos{line} ) if $ep->GetCurrentLine != $pos{line};
|
57
|
0
|
0
|
|
|
|
|
if ( $ep->GetColumn( $ep->GetCurrentPos ) == $pos{col} ) {
|
58
|
0
|
|
|
|
|
|
$ep->SetSelection( $pos{sel_begin}, $pos{sel_end} );
|
59
|
|
|
|
|
|
|
} else {
|
60
|
0
|
|
|
|
|
|
my $npos = $ep->PositionFromLine( $pos{line} ) + $pos{col};
|
61
|
0
|
|
|
|
|
|
my $max = $ep->GetLineEndPosition( $pos{line} );
|
62
|
0
|
0
|
|
|
|
|
$npos = $max if $npos > $max;
|
63
|
0
|
|
|
|
|
|
$ep->SetCurrentPos($npos);
|
64
|
0
|
|
|
|
|
|
$ep->SetSelection( $npos, $npos );
|
65
|
|
|
|
|
|
|
}
|
66
|
|
|
|
|
|
|
}
|
67
|
0
|
|
|
|
|
|
&_let_caret_visible;
|
68
|
|
|
|
|
|
|
}
|
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
sub _select_all_if_none {
|
71
|
0
|
|
|
0
|
|
|
my $ep = _ep_ref();
|
72
|
0
|
|
|
|
|
|
my ($start, $end) = $ep->GetSelection;
|
73
|
0
|
0
|
|
|
|
|
if ( $start == $end ) {
|
74
|
0
|
|
|
|
|
|
$ep->SelectAll;
|
75
|
0
|
|
|
|
|
|
($start, $end) = $ep->GetSelection;
|
76
|
|
|
|
|
|
|
}
|
77
|
0
|
|
|
|
|
|
return $ep->GetTextRange( $start, $end );
|
78
|
|
|
|
|
|
|
}
|
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
sub _selection_left_to_right {
|
81
|
0
|
|
0
|
0
|
|
|
my $ep = shift || _ep_ref();
|
82
|
0
|
|
|
|
|
|
my ($start, $end) = $ep->GetSelection;
|
83
|
0
|
|
|
|
|
|
my $pos = $ep->GetCurrentPos;
|
84
|
0
|
0
|
|
|
|
|
return -1 if $start == $end;
|
85
|
0
|
0
|
|
|
|
|
return $start == $pos ? 0 : 1;
|
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
sub _nearest_grid_pos { # position in document from given line and column |
88
|
0
|
|
|
0
|
|
|
my $line = shift; |
89
|
0
|
|
|
|
|
|
my $col = shift; |
90
|
0
|
|
0
|
|
|
|
my $ep = shift || _ep_ref(); |
91
|
0
|
0
|
|
|
|
|
return unless defined $col; |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
# first staight foreward attempt |
94
|
0
|
|
|
|
|
|
my $lpos = $ep->PositionFromLine($line); |
95
|
0
|
|
|
|
|
|
my $pos = $lpos + $col; |
96
|
0
|
0
|
0
|
|
|
|
return $pos if $ep->GetColumn($pos) == $col |
97
|
|
|
|
|
|
|
and $ep->LineFromPosition($pos) == $line; |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
# if line too short take last pos of line |
100
|
0
|
|
|
|
|
|
my $endpos = $ep->GetLineEndPosition($line); |
101
|
0
|
0
|
|
|
|
|
return $endpos if $ep->GetColumn($endpos) < $col; |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
# if tabs used calculate |
104
|
0
|
|
|
|
|
|
my $ipos = $ep->GetLineIndentation($line); |
105
|
0
|
|
|
|
|
|
my $icol = $ep->GetColumn($ipos); |
106
|
0
|
0
|
|
|
|
|
return $ipos + $col - $icol if $icol <= $col; |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
# if between indenting tabs take neares |
109
|
0
|
|
|
|
|
|
my $tabsize = $ep->GetTabWidth(); |
110
|
0
|
|
|
|
|
|
my $tabs = $col / $tabsize; |
111
|
0
|
0
|
|
|
|
|
return ($col % $tabsize < $tabsize / 2) ? $lpos + $tabs : $lpos + $tabs + 1; |
112
|
|
|
|
|
|
|
}
|
113
|
0
|
|
|
0
|
0
|
|
sub can_paste { _ep_ref()->CanPaste }
|
114
|
0
|
|
|
0
|
0
|
|
sub can_copy { Kephra::Document::Data::attr('text_selected') }
|
115
|
|
|
|
|
|
|
#
|
116
|
|
|
|
|
|
|
# simple textedit |
117
|
|
|
|
|
|
|
#
|
118
|
0
|
|
|
0
|
0
|
|
sub cut { _ep_ref()->Cut }
|
119
|
|
|
|
|
|
|
sub copy { |
120
|
0
|
|
|
0
|
0
|
|
my $ep = _ep_ref(); |
121
|
0
|
|
|
|
|
|
$ep->Copy; |
122
|
0
|
0
|
|
|
|
|
$ep->SelectionIsRectangle() |
123
|
|
|
|
|
|
|
? Kephra::Document::Data::set_value('copied_rect_selection',get_clipboard_text()) |
124
|
|
|
|
|
|
|
: Kephra::Document::Data::set_value('copied_rect_selection',''); |
125
|
|
|
|
|
|
|
}
|
126
|
|
|
|
|
|
|
sub paste {
|
127
|
0
|
|
|
0
|
0
|
|
my $lch = Kephra::Document::Data::get_value('copied_rect_selection'); |
128
|
0
|
|
|
|
|
|
my $cb = get_clipboard_text(); |
129
|
0
|
0
|
0
|
|
|
|
(defined $lch and $lch eq $cb) ? paste_rectangular($cb) : _ep_ref()->Paste; |
130
|
|
|
|
|
|
|
} |
131
|
|
|
|
|
|
|
sub paste_rectangular { |
132
|
0
|
|
0
|
0
|
0
|
|
my $text = shift || get_clipboard_text(); |
133
|
0
|
|
0
|
|
|
|
my $ep = shift || _ep_ref(); |
134
|
0
|
|
|
|
|
|
my $dragpos = shift; |
135
|
0
|
|
|
|
|
|
my $droppos = shift; |
136
|
|
|
|
|
|
|
# all additional parameters have to be provided or no one |
137
|
0
|
0
|
0
|
|
|
|
return -1 if defined $dragpos and not defined $droppos; |
138
|
|
|
|
|
|
|
|
139
|
0
|
|
|
|
|
|
my @lines = split( /[\r\n]+/, $text); |
140
|
0
|
0
|
|
|
|
|
$droppos = $ep->GetCurrentPos unless defined $dragpos; |
141
|
0
|
|
|
|
|
|
my $linenr = $ep->LineFromPosition( $droppos ); |
142
|
0
|
|
|
|
|
|
my $colnr = $ep->GetColumn($droppos ); |
143
|
|
|
|
|
|
|
|
144
|
0
|
0
|
|
|
|
|
if (defined $dragpos){ |
145
|
|
|
|
|
|
|
# calculate real drop position if dragged foreward |
146
|
|
|
|
|
|
|
# because selection is cut out before inserted and this changed droppos |
147
|
0
|
0
|
|
|
|
|
if ($dragpos <= $droppos){ |
148
|
0
|
|
|
|
|
|
my $selwidth = length $lines[0]; |
149
|
0
|
|
|
|
|
|
my $dnddelta = $linenr - $ep->LineFromPosition( $dragpos ); |
150
|
0
|
|
|
|
|
|
my $max = scalar @lines; |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
#$dnddelta = $max < $dnddelta ? $max : $dnddelta; |
153
|
|
|
|
|
|
|
#$dnddelta *= $selwidth; |
154
|
|
|
|
|
|
|
#$droppos -= $dnddelta; |
155
|
|
|
|
|
|
|
#print "$dragpos ---$droppos\n"; |
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
|
159
|
0
|
|
|
|
|
|
$ep->BeginUndoAction; |
160
|
0
|
0
|
|
|
|
|
$ep->ReplaceSelection(''),$ep->SetCurrentPos($droppos) if defined $dragpos; |
161
|
|
|
|
|
|
|
|
162
|
0
|
|
|
|
|
|
my $insertpos; |
163
|
0
|
|
|
|
|
|
for my $line (@lines){ |
164
|
0
|
|
|
|
|
|
$insertpos = $ep->PositionFromLine($linenr) + $colnr; |
165
|
0
|
|
|
|
|
|
$insertpos += $colnr - $ep->GetColumn( $insertpos ) ; |
166
|
0
|
0
|
|
|
|
|
$insertpos = $ep->GetLineEndPosition($linenr) |
167
|
|
|
|
|
|
|
if $ep->LineFromPosition( $insertpos ) > $linenr; |
168
|
0
|
|
|
|
|
|
$ep->InsertText( $insertpos, $line); |
169
|
0
|
|
|
|
|
|
$linenr++; |
170
|
|
|
|
|
|
|
} |
171
|
0
|
|
|
|
|
|
$ep->EndUndoAction; |
172
|
|
|
|
|
|
|
}
|
173
|
|
|
|
|
|
|
sub replace {
|
174
|
0
|
|
|
0
|
0
|
|
my $ep = _ep_ref();
|
175
|
0
|
|
|
|
|
|
my $text = get_clipboard_text();
|
176
|
0
|
|
|
|
|
|
copy();
|
177
|
0
|
|
|
|
|
|
_ep_ref()->ReplaceSelection($text);
|
178
|
|
|
|
|
|
|
}
|
179
|
|
|
|
|
|
|
|
180
|
0
|
|
|
0
|
0
|
|
sub clear { _ep_ref()->Clear }
|
181
|
|
|
|
|
|
|
sub get_clipboard_text {
|
182
|
0
|
|
|
0
|
0
|
|
my $cboard = &Wx::wxTheClipboard;
|
183
|
0
|
|
|
|
|
|
my $text;
|
184
|
0
|
|
|
|
|
|
$cboard->Open;
|
185
|
0
|
0
|
|
|
|
|
if ( $cboard->IsSupported( &Wx::wxDF_TEXT ) ) {
|
186
|
0
|
|
|
|
|
|
my $data = Wx::TextDataObject->new;
|
187
|
0
|
|
|
|
|
|
my $ok = $cboard->GetData( $data );
|
188
|
0
|
0
|
|
|
|
|
if ( $ok ) {
|
189
|
0
|
|
|
|
|
|
$text = $data->GetText;
|
190
|
|
|
|
|
|
|
} else {
|
191
|
|
|
|
|
|
|
# todo: error handling
|
192
|
|
|
|
|
|
|
}
|
193
|
|
|
|
|
|
|
}
|
194
|
0
|
|
|
|
|
|
$cboard->Close;
|
195
|
0
|
0
|
|
|
|
|
return defined $text ? $text : -1;
|
196
|
|
|
|
|
|
|
}
|
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
sub del_back_tab{
|
199
|
0
|
|
|
0
|
0
|
|
my $ep = _ep_ref();
|
200
|
0
|
|
|
|
|
|
my $pos = $ep->GetCurrentPos();
|
201
|
0
|
|
|
|
|
|
my $tab_size = Kephra::Document::Data::attr('tab_size');
|
202
|
0
|
|
|
|
|
|
my $deltaspace = $ep->GetColumn($pos--) % $tab_size;
|
203
|
0
|
0
|
|
|
|
|
$deltaspace = $tab_size unless $deltaspace;
|
204
|
0
|
|
0
|
|
|
|
do { $ep->CmdKeyExecute(&Wx::wxSTC_CMD_DELETEBACK) }
|
|
0
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
while $ep->GetCharAt(--$pos) == 32 and --$deltaspace;
|
206
|
|
|
|
|
|
|
}
|
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
#
|
209
|
|
|
|
|
|
|
# Edit Selection
|
210
|
|
|
|
|
|
|
# |
211
|
0
|
|
|
0
|
0
|
|
sub get_selection { _ep_ref()->GetSelectedText() } |
212
|
|
|
|
|
|
|
sub move_target { |
213
|
0
|
|
|
0
|
0
|
|
my $linedelta = shift; |
214
|
0
|
0
|
|
|
|
|
return unless defined $linedelta; |
215
|
0
|
|
0
|
|
|
|
my $ep = shift || _ep_ref(); |
216
|
0
|
|
|
|
|
|
my $targetstart = $ep->GetTargetStart(); |
217
|
0
|
|
|
|
|
|
my $targettext = $ep->GetTextRange($targetstart, $ep->GetTargetEnd()); |
218
|
0
|
|
|
|
|
|
$ep->BeginUndoAction; |
219
|
0
|
|
|
|
|
|
$ep->ReplaceTarget(''); |
220
|
0
|
|
|
|
|
|
$ep->InsertText($targetstart+$linedelta, $targettext); |
221
|
0
|
|
|
|
|
|
$ep->EndUndoAction; |
222
|
|
|
|
|
|
|
} |
223
|
|
|
|
|
|
|
sub move_selection { |
224
|
0
|
|
|
0
|
0
|
|
my $linedelta = shift; |
225
|
0
|
0
|
|
|
|
|
return unless defined $linedelta; |
226
|
0
|
|
0
|
|
|
|
my $ep = shift || _ep_ref(); |
227
|
0
|
|
|
|
|
|
my ($selbegin, $selend) = $ep->GetSelection(); |
228
|
0
|
|
|
|
|
|
my $targettext = $ep->GetSelectedText(); |
229
|
0
|
|
|
|
|
|
$ep->BeginUndoAction; |
230
|
0
|
|
|
|
|
|
$ep->ReplaceSelection(''); |
231
|
0
|
|
|
|
|
|
my $pos = $ep->GetCurrentPos; |
232
|
0
|
|
|
|
|
|
$pos += $linedelta; |
233
|
0
|
|
|
|
|
|
$ep->InsertText($pos, $targettext); |
234
|
0
|
|
|
|
|
|
$ep->SetSelection($pos, $pos + $selend - $selbegin); |
235
|
0
|
|
|
|
|
|
$ep->EndUndoAction; |
236
|
|
|
|
|
|
|
}
|
237
|
|
|
|
|
|
|
sub move_lines { |
238
|
0
|
|
|
0
|
0
|
|
my $linedelta = shift; |
239
|
0
|
0
|
|
|
|
|
return unless defined $linedelta; |
240
|
0
|
|
0
|
|
|
|
my $ep = shift || _ep_ref(); |
241
|
|
|
|
|
|
|
|
242
|
0
|
|
|
|
|
|
my ( $selbegin, $selend) = $ep->GetSelection(); |
243
|
0
|
|
|
|
|
|
my $sellength = $selend - $selbegin; |
244
|
0
|
|
|
|
|
|
my $selstartline = $ep->LineFromPosition($selbegin); |
245
|
0
|
|
|
|
|
|
my $targetstart = $ep->GetTargetStart(); |
246
|
0
|
|
|
|
|
|
my $targetend = $ep->GetTargetEnd(); |
247
|
0
|
|
|
|
|
|
my $blockbegin = $ep->PositionFromLine($selstartline); |
248
|
0
|
|
|
|
|
|
my $blockend = $ep->PositionFromLine( $ep->LineFromPosition($selend)+1 ); |
249
|
0
|
|
|
|
|
|
my $selcolumn = $selbegin - $blockbegin; |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
# endmode is taken when last line on start or end of operation has no EOL |
252
|
|
|
|
|
|
|
# then i take the the EOL char from the line before instead and have to |
253
|
|
|
|
|
|
|
# insert in a pos before to keep consistent |
254
|
0
|
|
|
|
|
|
my $endmode; |
255
|
0
|
0
|
0
|
|
|
|
if ($blockend == $ep->GetLength() |
256
|
|
|
|
|
|
|
or $ep->LineFromPosition($selend) + $linedelta >= $ep->GetLineCount()-1 ) { |
257
|
0
|
|
|
|
|
|
$blockbegin = $ep->GetLineEndPosition($selstartline-1); |
258
|
0
|
|
|
|
|
|
$blockend = $ep->GetLineEndPosition( $ep->LineFromPosition($selend) ); |
259
|
0
|
|
|
|
|
|
$endmode = 1; |
260
|
|
|
|
|
|
|
} |
261
|
0
|
|
|
|
|
|
$selstartline += $linedelta; |
262
|
0
|
|
|
|
|
|
my $blocktext = $ep->GetTextRange($blockbegin, $blockend); |
263
|
0
|
|
|
|
|
|
$ep->BeginUndoAction; |
264
|
0
|
|
|
|
|
|
$ep->SetTargetStart( $blockbegin ); |
265
|
0
|
|
|
|
|
|
$ep->SetTargetEnd( $blockend ); |
266
|
0
|
|
|
|
|
|
$ep->ReplaceTarget(''); |
267
|
0
|
0
|
|
|
|
|
$selstartline = 0 if $selstartline < 0; |
268
|
0
|
0
|
|
|
|
|
$selstartline = $ep->GetLineCount() if $selstartline > $ep->GetLineCount(); |
269
|
0
|
0
|
|
|
|
|
my $target = $endmode |
270
|
|
|
|
|
|
|
? $ep->GetLineEndPosition($selstartline-1) |
271
|
|
|
|
|
|
|
: $ep->PositionFromLine($selstartline); |
272
|
0
|
|
|
|
|
|
$ep->InsertText($target, $blocktext); |
273
|
0
|
|
|
|
|
|
$selbegin = $ep->PositionFromLine($selstartline) + $selcolumn; |
274
|
0
|
|
|
|
|
|
$ep->SetSelection($selbegin, $selbegin + $sellength); |
275
|
0
|
|
|
|
|
|
$ep->SetTargetStart($targetstart ); |
276
|
0
|
|
|
|
|
|
$ep->SetTargetEnd( $targetend ); |
277
|
0
|
|
|
|
|
|
$ep->EndUndoAction; |
278
|
|
|
|
|
|
|
}
|
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
sub selection_move_left {
|
281
|
0
|
|
0
|
0
|
0
|
|
my $ep = shift || _ep_ref(); |
282
|
0
|
|
|
|
|
|
my ($selbegin, $selend) = $ep->GetSelection();
|
283
|
0
|
0
|
0
|
|
|
|
if ( $selbegin == $selend |
284
|
|
|
|
|
|
|
or $ep->LineFromPosition( $selbegin ) != $ep->LineFromPosition( $selend ) ) { |
285
|
0
|
|
|
|
|
|
Kephra::Edit::Format::dedent_tab(); |
286
|
|
|
|
|
|
|
} |
287
|
|
|
|
|
|
|
else { |
288
|
0
|
|
|
|
|
|
my $newpos = $ep->WordStartPosition($selbegin, 1); |
289
|
0
|
0
|
|
|
|
|
my $move_delta = $newpos == $selbegin ? -1 : $newpos - $selbegin; |
290
|
0
|
|
|
|
|
|
move_selection( $move_delta ); |
291
|
|
|
|
|
|
|
}
|
292
|
|
|
|
|
|
|
}
|
293
|
|
|
|
|
|
|
|
294
|
|
|
|
|
|
|
sub selection_move_right{
|
295
|
0
|
|
|
0
|
0
|
|
my $ep = _ep_ref(); |
296
|
0
|
|
|
|
|
|
my ($selbegin, $selend) = $ep->GetSelection(); |
297
|
0
|
|
|
|
|
|
my $endline = $ep->LineFromPosition( $selend );
|
298
|
0
|
0
|
0
|
|
|
|
if ( $selbegin == $selend or $ep->LineFromPosition( $selbegin ) != $endline ) { |
299
|
0
|
|
|
|
|
|
Kephra::Edit::Format::indent_tab(); |
300
|
|
|
|
|
|
|
} |
301
|
|
|
|
|
|
|
else { |
302
|
0
|
|
|
|
|
|
my $newpos = $ep->WordEndPosition($selend, 1); |
303
|
0
|
0
|
|
|
|
|
my $move_delta = $newpos == $selend ? 1 : $newpos - $selend; |
304
|
0
|
0
|
0
|
|
|
|
move_selection( $move_delta ) |
305
|
|
|
|
|
|
|
unless $endline == $ep->GetLineCount() - 1 |
306
|
|
|
|
|
|
|
and $ep->GetLineEndPosition($endline) == $selend; |
307
|
|
|
|
|
|
|
}
|
308
|
|
|
|
|
|
|
}
|
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
sub selection_move_up {
|
311
|
0
|
|
0
|
0
|
0
|
|
my $ep = shift || _ep_ref(); |
312
|
0
|
|
|
|
|
|
my ($selbegin, $selend) = $ep->GetSelection(); |
313
|
0
|
|
|
|
|
|
my $firstline = $ep->LineFromPosition( $selbegin ); |
314
|
0
|
|
|
|
|
|
my $lastline = $ep->LineFromPosition( $selend ); |
315
|
|
|
|
|
|
|
|
316
|
0
|
0
|
0
|
|
|
|
if ( $selbegin != $selend and $firstline == $lastline) { |
317
|
0
|
|
|
|
|
|
my $line = $firstline; |
318
|
0
|
|
|
|
|
|
my $col = $ep->GetColumn( $selbegin ); |
319
|
0
|
0
|
|
|
|
|
return unless $line; |
320
|
0
|
|
|
|
|
|
$line--; |
321
|
0
|
|
|
|
|
|
move_selection( _nearest_grid_pos($line, $col) - $selbegin );
|
322
|
|
|
|
|
|
|
} |
323
|
0
|
|
|
|
|
|
else { move_lines( -1, $ep ) }
|
324
|
|
|
|
|
|
|
}
|
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
sub selection_move_down {
|
327
|
0
|
|
0
|
0
|
0
|
|
my $ep = shift || _ep_ref();
|
328
|
0
|
|
|
|
|
|
my ($selbegin, $selend) = $ep->GetSelection(); |
329
|
0
|
|
|
|
|
|
my $firstline = $ep->LineFromPosition( $selbegin ); |
330
|
0
|
|
|
|
|
|
my $lastline = $ep->LineFromPosition( $selend ); |
331
|
|
|
|
|
|
|
|
332
|
0
|
0
|
0
|
|
|
|
if ($selbegin != $selend and $firstline == $lastline) {
|
333
|
0
|
|
|
|
|
|
my $line = $firstline; |
334
|
0
|
|
|
|
|
|
my $col = $ep->GetColumn( $selbegin ); |
335
|
0
|
0
|
|
|
|
|
return if $line+1 == $ep->GetLineCount(); |
336
|
0
|
|
|
|
|
|
$line++; |
337
|
0
|
|
|
|
|
|
move_selection( _nearest_grid_pos($line, $col) - $selend ); |
338
|
|
|
|
|
|
|
} |
339
|
0
|
|
|
|
|
|
else { move_lines( 1, $ep ) }
|
340
|
|
|
|
|
|
|
}
|
341
|
|
|
|
|
|
|
|
342
|
|
|
|
|
|
|
sub selection_move_page_up {
|
343
|
0
|
|
0
|
0
|
0
|
|
my $ep = shift || _ep_ref();
|
344
|
0
|
|
|
|
|
|
my ($selbegin, $selend) = $ep->GetSelection(); |
345
|
0
|
|
|
|
|
|
my $firstline = $ep->LineFromPosition( $selbegin ); |
346
|
0
|
|
|
|
|
|
my $lastline = $ep->LineFromPosition( $selend ); |
347
|
0
|
|
|
|
|
|
my $linedelta = $ep->LinesOnScreen; |
348
|
|
|
|
|
|
|
|
349
|
0
|
0
|
0
|
|
|
|
if ($selbegin != $selend and $firstline == $lastline) {
|
350
|
0
|
|
|
|
|
|
my $line = $firstline; |
351
|
0
|
|
|
|
|
|
my $col = $ep->GetColumn( $selbegin ); |
352
|
0
|
0
|
|
|
|
|
return unless $line; |
353
|
0
|
|
|
|
|
|
$line -= $linedelta; |
354
|
0
|
0
|
|
|
|
|
$line = 0 if $line < 0; |
355
|
0
|
|
|
|
|
|
move_selection( _nearest_grid_pos($line, $col) - $selbegin ); |
356
|
|
|
|
|
|
|
} |
357
|
0
|
|
|
|
|
|
else { move_lines( -$linedelta, $ep ) }
|
358
|
|
|
|
|
|
|
}
|
359
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
sub selection_move_page_down {
|
361
|
0
|
|
0
|
0
|
0
|
|
my $ep = shift || _ep_ref(); |
362
|
0
|
|
|
|
|
|
my ($selbegin, $selend) = $ep->GetSelection(); |
363
|
0
|
|
|
|
|
|
my $firstline = $ep->LineFromPosition( $selbegin ); |
364
|
0
|
|
|
|
|
|
my $lastline = $ep->LineFromPosition( $selend ); |
365
|
0
|
|
|
|
|
|
my $linedelta = $ep->LinesOnScreen; |
366
|
|
|
|
|
|
|
|
367
|
0
|
0
|
0
|
|
|
|
if ($selbegin != $selend and $firstline == $lastline) { |
368
|
0
|
|
|
|
|
|
my $line = $firstline; |
369
|
0
|
|
|
|
|
|
my $col = $ep->GetColumn( $selbegin ); |
370
|
0
|
0
|
|
|
|
|
return if $line+1 == $ep->GetLineCount(); |
371
|
0
|
|
|
|
|
|
$line += $linedelta; |
372
|
0
|
0
|
|
|
|
|
$line = $ep->GetLineCount()-1 if $line >= $ep->GetLineCount(); |
373
|
0
|
|
|
|
|
|
move_selection( _nearest_grid_pos($line, $col) - $selend );
|
374
|
|
|
|
|
|
|
} |
375
|
0
|
|
|
|
|
|
else { move_lines( $linedelta, $ep ) }
|
376
|
|
|
|
|
|
|
}
|
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
#
|
379
|
|
|
|
|
|
|
sub insert {
|
380
|
0
|
|
|
0
|
0
|
|
my ($text, $pos) = @_;
|
381
|
0
|
0
|
|
|
|
|
return unless $text;
|
382
|
0
|
|
|
|
|
|
my $ep = _ep_ref();
|
383
|
0
|
0
|
|
|
|
|
$pos = $ep->GetCurrentPos unless defined $pos;
|
384
|
0
|
|
|
|
|
|
$ep->InsertText($pos, $text);
|
385
|
0
|
|
|
|
|
|
$pos += length $text;
|
386
|
0
|
|
|
|
|
|
$ep->SetSelection($pos, $pos);
|
387
|
|
|
|
|
|
|
}
|
388
|
0
|
|
|
0
|
0
|
|
sub insert_text { insert(@_) }
|
389
|
0
|
|
|
0
|
0
|
|
sub insert_at_pos { insert(@_) }
|
390
|
|
|
|
|
|
|
#
|
391
|
|
|
|
|
|
|
# Edit Line
|
392
|
|
|
|
|
|
|
#
|
393
|
0
|
|
|
0
|
0
|
|
sub cut_current_line { _ep_ref()->CmdKeyExecute(&Wx::wxSTC_CMD_LINECUT) }
|
394
|
0
|
|
|
0
|
0
|
|
sub copy_current_line{ _ep_ref()->CmdKeyExecute(&Wx::wxSTC_CMD_LINECOPY)}
|
395
|
|
|
|
|
|
|
sub double_current_line {
|
396
|
0
|
|
|
0
|
0
|
|
my $ep = _ep_ref();
|
397
|
0
|
|
|
|
|
|
my $pos = $ep->GetCurrentPos;
|
398
|
0
|
|
|
|
|
|
$ep->BeginUndoAction;
|
399
|
0
|
|
|
|
|
|
$ep->CmdKeyExecute(&Wx::wxSTC_CMD_LINECOPY);
|
400
|
0
|
|
|
|
|
|
$ep->CmdKeyExecute(&Wx::wxSTC_CMD_PASTE);
|
401
|
0
|
|
|
|
|
|
$ep->GotoPos($pos);
|
402
|
0
|
|
|
|
|
|
$ep->EndUndoAction;
|
403
|
|
|
|
|
|
|
}
|
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
sub replace_current_line {
|
406
|
0
|
|
|
0
|
0
|
|
my $ep = _ep_ref();
|
407
|
0
|
|
|
|
|
|
my $line = $ep->GetCurrentLine;
|
408
|
0
|
|
|
|
|
|
$ep->BeginUndoAction;
|
409
|
0
|
|
|
|
|
|
$ep->GotoLine($line);
|
410
|
0
|
|
|
|
|
|
$ep->Paste;
|
411
|
0
|
|
|
|
|
|
$ep->SetSelection(
|
412
|
|
|
|
|
|
|
$ep->GetSelectionEnd,
|
413
|
|
|
|
|
|
|
$ep->GetLineEndPosition( $ep->GetCurrentLine )
|
414
|
|
|
|
|
|
|
);
|
415
|
0
|
|
|
|
|
|
$ep->Cut;
|
416
|
0
|
|
|
|
|
|
$ep->GotoLine($line);
|
417
|
0
|
|
|
|
|
|
$ep->EndUndoAction;
|
418
|
|
|
|
|
|
|
}
|
419
|
|
|
|
|
|
|
|
420
|
0
|
|
|
0
|
0
|
|
sub del_current_line{_ep_ref()->CmdKeyExecute(&Wx::wxSTC_CMD_LINEDELETE)}
|
421
|
0
|
|
|
0
|
0
|
|
sub del_line_left {_ep_ref()->DelLineLeft() }
|
422
|
0
|
|
|
0
|
0
|
|
sub del_line_right {_ep_ref()->DelLineRight()}
|
423
|
|
|
|
|
|
|
|
424
|
0
|
|
|
0
|
0
|
|
sub eval_newline_sub{}
|
425
|
|
|
|
|
|
|
1;
|
426
|
|
|
|
|
|
|
__END__
|