4
Word Left/Right: Need tests with fold, trim, selection
12
SysUtils, testregistry, LCLProc, Forms, TestBase,
13
SynEdit, SynEditKeyCmds;
17
{ TTestSynNavigation }
19
TTestSynNavigation = class(TTestBase)
21
procedure TestCaretHomeEnd;
22
procedure TestCaretLeftRight;
23
procedure TestCaretMoveLeftRightWord;
24
//procedure TestCaretMoveLeftRightPartWord;
29
{ TTestSynNavigation }
31
procedure TTestSynNavigation.TestCaretHomeEnd;
35
SynEdit.TabWidth := 6;
36
SyneDit.Options := [];
37
SyneDit.Options2 := [];
62
#9' tabbed spaced', // 21
69
' ', // 27 (space only)
76
' spaced 9 for tab', // 33
87
procedure TestHome(Name:String; X, Y, ExpX1, ExpX2, ExpX3: Integer; ExpLTxTStartX: Integer = -1);
90
synedit.CommandProcessor(ecLineStart, '', nil);
91
TestIsCaretPhys(Name + '(1st home)', ExpX1,Y);
92
synedit.CommandProcessor(ecLineStart, '', nil);
93
TestIsCaretPhys(Name + '(2nd home)', ExpX2,Y);
94
synedit.CommandProcessor(ecLineStart, '', nil);
95
TestIsCaretPhys(Name + '(3rd home)', ExpX3,Y);
96
if ExpLTxTStartX > 0 then begin
98
synedit.CommandProcessor(ecLineTextStart, '', nil);
99
TestIsCaretPhys(Name + '(1st line-text-start)', ExpLTxTStartX,Y);
100
synedit.CommandProcessor(ecLineTextStart, '', nil);
101
TestIsCaretPhys(Name + '(2nd line-text-start)', ExpLTxTStartX,Y);
102
synedit.CommandProcessor(ecLineTextStart, '', nil);
103
TestIsCaretPhys(Name + '(3rd line-text-start)', ExpLTxTStartX,Y);
107
procedure TestEnd(Name:String; X, Y, ExpX1, ExpX2, ExpX3: Integer);
110
synedit.CommandProcessor(ecLineEnd, '', nil);
111
TestIsCaretPhys(Name + '(1st end)', ExpX1,Y);
112
synedit.CommandProcessor(ecLineEnd, '', nil);
113
TestIsCaretPhys(Name + '(2nd end)', ExpX2,Y);
114
synedit.CommandProcessor(ecLineEnd, '', nil);
115
TestIsCaretPhys(Name + '(3rd end)', ExpX3,Y);
120
// Caret goes x=1, then x=indend
122
// Caret goes x=indent, then 1, IF AFTER indent, or at x=1
123
// Caret goes x=1, then x=indend, IF at x=indent, or inside indent
125
// Caret does not go past eol, unless explicitly enabled
126
// if spaces/tab exist at start of otherwise empty line, caret will go to prev-line indent
130
PushBaseName('no smart / no past-eol');
132
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
133
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
135
TestHome('unindented line', 1, 3, 1,1,1, 1);
136
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
137
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
138
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
139
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
140
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
142
TestHome('space indented line', 1, 9, 4,1,4, 4);
143
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4); // go to indent, after absolute home
144
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
145
TestHome('space indented line x-in-line', 6, 9, 1,4,1, 4);
146
TestHome('1st after space indented line', 1,10, 1,1,1, 1);
147
TestHome('2nd after space indented line', 1,11, 1,1,1, 1);
148
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
149
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
150
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
151
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
152
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
153
TestHome('#9 after long space indented line [skipT]', 1,34, 7,1,7, 1);
154
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
155
TestHome('#9 after long space indented line [skipT]', 13,34, 1,7,1, 1);
156
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
158
TestHome('tab indented line', 1,15, 7,1,7, 7);
159
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
160
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
161
TestHome('tab indented line x-in-line', 9,15, 1,7,1, 7);
162
TestHome('1st after tab indented line', 1,16, 1,1,1, 1);
163
TestHome('2nd after tab indented line', 1,17, 1,1,1, 1);
164
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
165
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
170
SyneDit.Options := [eoScrollPastEol];
171
PopPushBaseName('no smart / past-eol');
173
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
174
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
176
TestHome('unindented line', 1, 3, 1,1,1, 1);
177
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
178
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
179
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
180
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
181
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
183
TestHome('space indented line', 1, 9, 4,1,4, 4);
184
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4); // go to indent, after absolute home
185
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
186
TestHome('space indented line x-in-line', 6, 9, 1,4,1, 4);
187
TestHome('1st after space indented line', 1,10, 4,1,4, 1);
188
TestHome('1st after space indented line (x)', 2,10, 1,4,1, 1);
189
TestHome('2nd after space indented line', 1,11, 4,1,4, 1);
190
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
191
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
192
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
193
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
194
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
195
TestHome('#9 after long space indented line [skipT]', 1,34, 7,1,7, 1);
196
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
197
TestHome('#9 after long space indented line [skipT]', 13,34, 1,7,1, 1);
198
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
200
TestHome('tab indented line', 1,15, 7,1,7, 7);
201
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
202
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
203
TestHome('tab indented line x-in-line', 9,15, 1,7,1, 7);
204
TestHome('1st after tab indented line', 1,16, 7,1,7, 1);
205
TestHome('1st after tab indented line(x)', 2,16, 1,7,1, 1);
206
TestHome('2nd after tab indented line', 1,17, 7,1,7, 1);
207
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
208
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
214
SyneDit.Options := [eoEnhanceHomeKey];
216
PopPushBaseName('smart home / no past-eol');
218
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
219
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
221
TestHome('unindented line', 1, 3, 1,1,1, 1);
222
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
223
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
224
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
225
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
226
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
228
TestHome('space indented line', 1, 9, 4,1,4, 4); // go to absolut home (x-=1), after indent
229
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4);
230
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
231
TestHome('space indented line x-in-line', 6, 9, 4,1,4, 4);
232
TestHome('1st after space indented line', 1,10, 1,1,1, 1);
233
TestHome('2nd after space indented line', 1,11, 1,1,1, 1);
234
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
235
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
236
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
237
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
238
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
239
TestHome('#9 after long space indented line [skipT]', 1,34, 7,1,7, 1);
240
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
241
TestHome('#9 after long space indented line [skipT]', 13,34, 7,1,7, 1);
242
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
244
TestHome('tab indented line', 1,15, 7,1,7, 7);
245
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
246
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
247
TestHome('tab indented line x-in-line', 9,15, 7,1,7, 7);
248
TestHome('1st after tab indented line', 1,16, 1,1,1, 1);
249
TestHome('2nd after tab indented line', 1,17, 1,1,1, 1);
250
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
251
TestHome('3rd #32 after tab indented line', 11,18, 7,1,7, 1);
252
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
258
SyneDit.Options := [eoEnhanceHomeKey, eoScrollPastEol];
260
PopPushBaseName('smart home / past-eol');
262
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
263
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
265
TestHome('unindented line', 1, 3, 1,1,1, 1);
266
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
267
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
268
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
269
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
270
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
272
TestHome('space indented line', 1, 9, 4,1,4, 4); // go to absolut home (x-=1), after indent
273
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4);
274
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
275
TestHome('space indented line x-in-line', 6, 9, 4,1,4, 4);
276
TestHome('1st after space indented line', 1,10, 4,1,4, 1);
277
TestHome('2nd after space indented line', 1,11, 4,1,4, 1);
278
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
279
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
280
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
281
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
282
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
283
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
284
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
286
TestHome('tab indented line', 1,15, 7,1,7, 7);
287
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
288
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
289
TestHome('tab indented line x-in-line', 9,15, 7,1,7, 7);
290
TestHome('1st after tab indented line', 1,16, 7,1,7, 1);
291
TestHome('1st after tab indented line (x)', 2,16, 1,7,1, 1);
292
TestHome('2nd after tab indented line', 1,17, 7,1,7, 1);
293
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
294
TestHome('3rd #32 after tab indented line', 11,18, 7,1,7, 1);
295
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
298
PopPushBaseName('NO smart end/ NO past-eol');
300
TestEnd ('empty 1st line', 1,1, 1,1,1);
301
TestEnd ('end', 1,35, 6,3,6);
302
TestEnd ('end tab', 1,36, 7,3,7);
304
PopPushBaseName('smart end/ NO past-eol');
306
SyneDit.Options2 := [eoEnhanceEndKey];
307
TestEnd ('end', 1,35, 3,6,3);
308
TestEnd ('end tab', 1,36, 3,7,3);
310
//SyneDit.Options := [eoScrollPastEol, eoEnhanceHomeKey];
311
//SyneDit.Options2 := [eoEnhanceEndKey];
315
procedure TTestSynNavigation.TestCaretLeftRight;
317
procedure SetTextLeftRight;
320
SetLines([ 'ああああああああああああああああああああああ', // 1: Double width at odd pos (start at 1, then every 2)
321
' ああああああああああああああああああああああ', // 2: Double width at even pos
323
#9#9#9#9#9#9#9#9, // 4: tabs
324
'abc'#9'def', // 5: text+tabs
325
'abc def üüü xyz', // 6: utf8 multibyte
326
'abc def ü'#9'üü xyz', // 7: utf8 multibyte + tabs
327
'abc あdefあ123', // 8: Double withs
328
'abc あdef'#9'あ'#9'123', // 9: Double withs + tabs
329
'Aa'#$CC#$81'B', // 10: a-accent, in 2 (combining) codepoints)
334
procedure TestLeftRight(AName: String; ALine: Integer; AStartPhysX: Integer; ACommand:TSynEditorCommand;
335
ExpPhysX, ExpLogX: Integer; ExpRepeatPhysX: Integer = -1; ExpRepeatLogX: Integer = -1;
336
DoReverse: Boolean = True; DoKeepXDWidth: Boolean = True;
337
ASelectXEnd: Integer = -1; ExpCaretY: integer = -1);
340
TestLogFirst: Boolean;
345
then SetCaretPhys(AStartPhysX, ALine)
346
else SetCaretAndSelPhys(ASelectXEnd, ALine, AStartPhysX, ALine);
347
SynEdit.ExecuteCommand(ACommand, '', nil);
352
if not TestLogFirst then
353
TestIsCaretPhys(Name2+'[1]', ExpPhysX, ExpCaretY);
354
TestIsCaret(Name2+'[1]', ExpLogX, ExpCaretY);
355
TestIsCaretPhys(Name2+'[1]', ExpPhysX, ExpCaretY);
358
procedure DoCmdRepeat;
360
if ExpRepeatPhysX < 0 then exit;
361
SynEdit.ExecuteCommand(ACommand, '', nil);
363
procedure TestCmdRepeat;
365
if ExpRepeatPhysX < 0 then exit;
367
if not TestLogFirst then
368
TestIsCaretPhys(Name2+'[2]', ExpRepeatPhysX, ExpCaretY);
369
if ExpRepeatLogX > 0 then
370
TestIsCaret(Name2+'[2]', ExpRepeatLogX, ExpCaretY);
371
TestIsCaretPhys(Name2+'[2]', ExpRepeatPhysX, ExpCaretY);
374
procedure DoCmdReverse(AfterRepeat: Boolean = false);
376
if not DoReverse then exit;
377
if AfterRepeat and (ExpRepeatPhysX < 0) then exit; // was never repeated
380
then SynEdit.ExecuteCommand(ecRight, '', nil)
381
else SynEdit.ExecuteCommand(ecLeft, '', nil);
383
procedure TestCmdReverse(AfterRepeat: Boolean = false);
385
if not DoReverse then exit;
386
if AfterRepeat and (ExpRepeatPhysX < 0) then exit; // was never repeated
388
DoCmdReverse(AfterRepeat);
389
if AfterRepeat then begin
390
if not TestLogFirst then
391
TestIsCaretPhys(Name2+'[R,'+dbgs(AfterRepeat)+']', ExpPhysX, ExpCaretY);
392
TestIsCaret(Name2, ExpLogX, ExpCaretY);
393
TestIsCaretPhys(Name2+'[R,'+dbgs(AfterRepeat)+']', ExpPhysX, ExpCaretY);
395
TestIsCaretPhys(Name2+'[R,'+dbgs(AfterRepeat)+']', AStartPhysX, ALine);
399
procedure DoKeepXOnEmpty;
401
if (ExpPhysX > 1) and not(eoScrollPastEol in SynEdit.Options) then begin
402
SynEdit.CaretObj.LinePos := 3; // empty line
403
SynEdit.CaretObj.LinePos := ExpCaretY;
406
procedure TestKeepXOnEmpty(TestBetween: Boolean = False);
408
if (ExpPhysX > 1) and not(eoScrollPastEol in SynEdit.Options) then begin
409
SynEdit.CaretObj.LinePos := 3; // empty line
411
AssertEquals(Name2+'empty line at pos 1', 1, SynEdit.CaretObj.CharPos);
412
SynEdit.CaretObj.LinePos := ExpCaretY;
413
if eoKeepCaretX in SynEdit.Options
414
then AssertEquals(Name2+'after empty line at pos 1', ExpPhysX, SynEdit.CaretObj.CharPos)
415
else AssertEquals(Name2+'after empty line at pos 1', 1, SynEdit.CaretObj.CharPos);
419
procedure DoKeepXOnDWidth;
421
if (ExpPhysX > 1) and DoKeepXDWidth then begin
422
if (ExpPhysX and 1) = 0
423
then SynEdit.CaretObj.LinePos := 1 // double width odd
424
else SynEdit.CaretObj.LinePos := 2; // double width even
425
SynEdit.CaretObj.LinePos := ExpCaretY;
428
procedure TestKeepXOnDWidth(TestBetween: Boolean = False);
430
if (ExpPhysX > 1) and DoKeepXDWidth then begin
431
if (ExpPhysX and 1) = 0
432
then SynEdit.CaretObj.LinePos := 1 // double width odd
433
else SynEdit.CaretObj.LinePos := 2; // double width even
435
AssertFalse(Name2+'after dwidth line at pos 1', ExpPhysX = SynEdit.CaretObj.CharPos);
436
SynEdit.CaretObj.LinePos := ExpCaretY;
437
AssertTrue(Name2+'after dwidth line at pos 1',
438
(ExpPhysX = SynEdit.CaretObj.CharPos) = (eoKeepCaretX in SynEdit.Options));
445
if ExpCaretY < 0 then ExpCaretY := ALine;
447
EditorCommandToIdent(ACommand, s{%H-});
448
AName := Format('%s (%s Y=%d, X=%d) ', [AName, s, ALine, AStartPhysX]);
450
{%region NO eoKeepCaretX}
451
SynEdit.Options := SynEdit.Options - [eoKeepCaretX];
452
Name2 := AName + 'NO eoKeepCaretX: ';
454
TestLogFirst := False;
461
TestCmdReverse(True);
469
TestCmdReverse(True);
472
TestLogFirst := True;
479
TestCmdReverse(True);
483
TestKeepXOnEmpty(False);
486
TestKeepXOnEmpty(True);
489
TestKeepXOnDWidth(False);
492
TestKeepXOnDWidth(True);
494
{%endregion NO eoKeepCaretX}
497
{%region WITH eoKeepCaretX}
498
SynEdit.Options := SynEdit.Options + [eoKeepCaretX];
499
Name2 := Name2 + 'WITH eoKeepCaretX: ';
501
TestLogFirst := False;
508
TestCmdReverse(True);
516
TestCmdReverse(True);
519
TestLogFirst := True;
526
TestCmdReverse(True);
530
TestKeepXOnEmpty(False);
531
if ASelectXEnd < 0 then
535
TestKeepXOnEmpty(True);
536
if ASelectXEnd < 0 then
540
TestKeepXOnEmpty(False);
544
TestKeepXOnDWidth(False);
545
if ASelectXEnd < 0 then
549
TestKeepXOnDWidth(True);
550
if ASelectXEnd < 0 then
554
TestKeepXOnDWidth(False);
557
{%endregion WITH eoKeepCaretX}
563
// EOL/BOL at first/last (visible) line (with folding)
564
// Multybyte char at EOL
568
PushBaseName('No opts');
570
SynEdit.TabWidth := 6;
571
SynEdit.MaxLeftChar := 200;
572
SynEdit.Options := [];
573
SynEdit.Options2 := [];
575
TestLeftRight('Simple right', 5, 2, ecRight, 3, 3, 4, 4);
577
TestLeftRight('After tab right', 5, 7, ecRight, 8, 6, 9, 7);
578
TestLeftRight('Before tab right', 5, 4, ecRight, 5, 4, 6, 4);
579
TestLeftRight('Mid tab right', 5, 5, ecRight, 6, 4, 7, 5);
580
TestLeftRight('tab to tab right', 4, 6, ecRight, 7, 2, 8, 2);
582
TestLeftRight('Umlaut right', 6, 9, ecRight, 10,11, 11,13);
583
TestLeftRight('Double W right', 8, 5, ecRight, 7, 8, 8, 9);
584
TestLeftRight('combining right', 10, 2, ecRight, 3, 5, 4, 6);
586
TestLeftRight('at EOL right', 5, 10, ecRight, 1, 1, 2, 2, True, True, -1 , 6);
588
PopPushBaseName('eoScrollPastEol');
589
SynEdit.Options := [eoScrollPastEol];
591
TestLeftRight('at EOL right', 5, 10, ecRight, 11, 9, 12,10);
592
TestLeftRight('at Max-left right', 5,199, ecRight, 200,198, 200,198, False, False);
595
PopPushBaseName('eoCaretSkipTab');
596
SynEdit.Options := [];
597
SynEdit.Options2 := [eoCaretSkipTab];
599
TestLeftRight('Simple right', 5, 2, ecRight, 3, 3, 4, 4);
601
TestLeftRight('After tab right', 5, 7, ecRight, 8, 6, 9, 7);
602
TestLeftRight('Before tab right', 5, 4, ecRight, 7, 5, 8, 6);
603
TestLeftRight('tab to tab right', 4, 7, ecRight, 13, 3, 19, 4);
606
PopPushBaseName('eoCaretSkipsSelection');
607
SynEdit.Options2 := [eoCaretSkipsSelection];
609
TestLeftRight('Selected right', 5, 2, ecRight, 8, 6, -1, -1, True, False, 8);
614
SynEdit.Options := [];
615
SynEdit.Options2 := [];
617
TestLeftRight('Simple left', 5, 3, ecLeft, 2, 2, 1, 1);
619
TestLeftRight('After tab left', 5, 7, ecLeft, 6, 4, 5, 4);
620
TestLeftRight('Before tab left', 5, 4, ecLeft, 3, 3, 2, 2);
621
TestLeftRight('Mid tab left', 5, 5, ecLeft, 4, 4, 3, 3);
622
TestLeftRight('tab to tab left', 4, 8, ecLeft, 7, 2, 6, 1);
624
TestLeftRight('Umlaut left', 6, 10, ecLeft, 9, 9, 8, 8);
625
TestLeftRight('Double W left', 8, 7, ecLeft, 5, 5, 4, 4);
626
TestLeftRight('combining left', 10, 3, ecLeft, 2, 2, 1, 1);
628
TestLeftRight('at BOL left', 6, 1, ecLeft, 10, 8, 9, 7, True, True, -1 , 5);
630
PopPushBaseName('eoScrollPastEol');
631
SynEdit.Options := [eoScrollPastEol];
633
TestLeftRight('at BOL left', 6, 1, ecLeft, 1, 1, 1, 1, False, False);
636
PopPushBaseName('eoCaretSkipTab');
637
SynEdit.Options := [];
638
SynEdit.Options2 := [eoCaretSkipTab];
640
TestLeftRight('Simple left', 5, 3, ecLeft, 2, 2, 1, 1);
642
TestLeftRight('After tab left', 5, 7, ecLeft, 4, 4, 3, 3);
643
TestLeftRight('tab to tab left', 4, 13, ecLeft, 7, 2, 1, 1);
646
PopPushBaseName('eoCaretSkipsSelection');
647
SynEdit.Options2 := [eoCaretSkipsSelection];
649
TestLeftRight('Selected left', 5, 8, ecLeft, 3, 3, -1, -1, True, False, 3);
657
procedure TTestSynNavigation.TestCaretMoveLeftRightWord;
663
SynEdit.TabWidth := 7;
665
SetLines(['Some text to test', //1
669
#9'Other line with tab', // 3
671
'tab'#9'in the middle', // 4
673
'tab'#9' in the middle with space', // 5
675
'umlaute äää in text', // 6
678
' untrimmed spaces around line ', // 8
681
#9'tab'#9'only'#9'line'#9, // 10
686
' ', // space only empty line // 14
695
procedure TestWordLeft(Name:String; X, Y, ExpX1, ExpY1: Integer;
696
ExpX2: Integer = -1; ExpY2: Integer = -1);
699
SynEdit.CommandProcessor(ecWordLeft, '', nil);
700
TestIsCaretPhys(Name + '(1st WordLeft)', ExpX1, ExpY1);
701
if ExpY2 > 0 then begin
702
SynEdit.CommandProcessor(ecWordLeft, '', nil);
703
TestIsCaretPhys(Name + '(2nd WordLeft)', ExpX2, ExpY2);
707
procedure TestWordRight(Name:String; X, Y, ExpX1, ExpY1: Integer;
708
ExpX2: Integer = -1; ExpY2: Integer = -1);
711
SynEdit.CommandProcessor(ecWordRight, '', nil);
712
TestIsCaretPhys(Name + '(1st WordRight)', ExpX1, ExpY1);
713
if ExpY2 > 0 then begin
714
SynEdit.CommandProcessor(ecWordRight, '', nil);
715
TestIsCaretPhys(Name + '(2nd WordRight)', ExpX2, ExpY2);
722
TestWordLeft('simple "te|st"', 16, 1, 14, 1, 11, 1);
723
TestWordLeft('simple EOW "test|"', 18, 1, 14, 1, 11, 1);
724
TestWordLeft('simple BOW "|test"', 14, 1, 11, 1, 6, 1);
725
TestWordLeft('simple > BOT "So|me"', 3, 1, 1, 1, 1, 1);
726
TestWordLeft('simple > prev-line "F|oo"', 2, 2, 1, 2, 18, 1);
727
TestWordLeft('simple > prev-line "|Foo"', 1, 2, 18, 1, 14, 1);
729
TestWordLeft('tab "wi|th"', 21, 3, 19, 3, 14, 3);
730
TestWordLeft('tab EOW "with|"', 23, 3, 19, 3, 14, 3);
731
TestWordLeft('tab BOW "|with"', 19, 3, 14, 3, 8, 3);
732
TestWordLeft('tab > prev-line "O|ther"', 9, 3, 8, 3, 12, 2);
734
TestWordLeft('M-tab "i|n"', 9, 4, 8, 4, 1, 4);
735
TestWordLeft('M-tab > prev-line-tab "ta|b"', 3, 4, 1, 4, 27, 3);
737
TestWordLeft('M-S-tab "i|n"', 10, 5, 9, 5, 1, 5);
738
TestWordLeft('M-S-EOW tab "in|"', 11, 5, 9, 5, 1, 5);
739
TestWordLeft('M-S-BOW tab "|in"', 9, 5, 1, 5, 21, 4);
740
TestWordLeft('M-S-tab "#9| in"', 8, 5, 1, 5);
742
TestWordLeft('Umlaut "ää|ä"', 11, 6, 9, 6, 1, 6);
743
TestWordLeft('Umlaut EOW "äää|"', 12, 6, 9, 6, 1, 6);
744
TestWordLeft('Umlaut BOW "|äää"', 9, 6, 1, 6, 33, 5);
745
TestWordLeft('Umlaut "i|n"', 14, 6, 13, 6, 9, 6);
746
TestWordLeft('After Umlaut > prev line', 1, 7, 20, 6, 16, 6);
748
TestWordLeft('untrimmed "un|trimmed"', 6, 8, 4, 8, 12, 7);
749
TestWordLeft('After untrimmed > prev', 1, 9, 35, 8, 28, 8);
750
TestWordLeft('untrimmed tab "t|ab"', 9,10, 8,10, 12, 9);
751
TestWordLeft('After untrimmed tab > prev', 1,11, 29,10, 22,10);
753
TestWordLeft('After empty > prev', 1,13, 1,12);
754
TestWordLeft('After space empty > prev', 1,15, 6,14);
756
TestWordLeft('single char at eol "A B|"', 4,17, 3,17, 1,17);
760
TestWordRight('simple "te|xt"', 8, 1, 11, 1, 14, 1);
761
TestWordRight('simple EOW "text|"', 10, 1, 11, 1, 14, 1);
762
TestWordRight('simple BOW "|text"', 6, 1, 11, 1, 14, 1);
763
TestWordRight('simple EOT "li|ne"', 10,18, 12,18, 12,18);
764
TestWordRight('simple > EOL, next line "te|st"', 16, 1, 18, 1, 1, 2);
766
TestWordRight('tab "li|ne"', 16, 3, 19, 3, 24, 3);
767
TestWordRight('tab EOW "line|"', 18, 3, 19, 3, 24, 3);
768
TestWordRight('tab BOW "|line"', 14, 3, 19, 3, 24, 3);
769
TestWordRight('tab > EOL, next-line', 25, 3, 27, 3, 1, 4);
771
TestWordRight('M-tab "t|ab"', 2, 4, 8, 4, 11, 4);
772
TestWordRight('M-tab "tab|"', 4, 4, 8, 4, 11, 4);
773
TestWordRight('M-tab > EOL, next-line-tab', 17, 4, 21, 4, 1, 5);
775
TestWordRight('M-S-tab BOW "t|ab"', 2, 5, 9, 5, 12, 5);
776
TestWordRight('M-S-tab EOW "tab|"', 4, 5, 9, 5, 12, 5);
777
TestWordRight('M-S-tab BOW "|tab"', 1, 5, 9, 5, 12, 5);
778
TestWordRight('M-S-tab "tab#9| "', 5, 5, 9, 5, 12, 5);
780
TestWordRight('Umlaut "ää|ä"', 11, 6, 13, 6, 16, 6);
781
TestWordRight('Umlaut EOW "äää|"', 12, 6, 13, 6, 16, 6);
782
TestWordRight('Umlaut BOW "|äää"', 9, 6, 13, 6, 16, 6);
783
TestWordRight('Umlaut "um|laute"', 2, 6, 9, 6, 13, 6);
784
TestWordRight('After Umlaut > EOL, next line', 18, 6, 20, 6, 1, 7);
786
TestWordRight('Before untrimmed > next', 12, 7, 4, 8, 14, 8);
787
TestWordRight('untrimmed > EOL, next', 30, 8, 35, 8, 1, 9);
788
TestWordRight('Before untrimmed tab > next', 12, 9, 8,10, 15,10);
789
TestWordRight('untrimmed tab > EOL, next', 24,10, 29,10, 1,11);
791
TestWordRight('Before empty > next', 12,11, 1,12);
792
TestWordRight('Before space empty > next', 12,13, 1,14, 6, 14);
798
RegisterTest(TTestSynNavigation);