SynEdit tests

git-svn-id: trunk@39083 -
This commit is contained in:
martin 2012-10-14 19:48:15 +00:00
parent 3b90468c10
commit ad7aed810e
4 changed files with 796 additions and 432 deletions

1
.gitattributes vendored
View File

@ -2820,6 +2820,7 @@ components/synedit/test/testhighlightmulti.pas svneol=native#text/pascal
components/synedit/test/testhighlightpas.pas svneol=native#text/pascal
components/synedit/test/testhighlightxml.pas svneol=native#text/pascal
components/synedit/test/testmarkupwordgroup.pas svneol=native#text/pascal
components/synedit/test/testnavigation.pas svneol=native#text/pascal
components/synedit/test/testsearch.pas svneol=native#text/pascal
components/synedit/test/testsynbeautifier.pas svneol=native#text/pascal
components/synedit/test/testsyncroedit.pas svneol=native#text/pascal

View File

@ -4,7 +4,7 @@ program SynTest;
uses
Interfaces, Forms, GuiTestRunner, TestBase,
TestBasicSynEdit, TestSynSelection, TestBlockIndent, TestBookMarks,
TestBasicSynEdit, TestNavigation, TestSynSelection, TestBlockIndent, TestBookMarks,
TestSearch, TestSynBeautifier, TestTrimSpace, TestSyncroEdit, TestSynTextArea,
TestHighlightPas, TestHighlightXml, TestHighlightMulti,
TestMarkupwordGroup, TestFoldedView, TestSynSharedEdits, TestHighlighterLfm,

View File

@ -3,8 +3,6 @@ unit TestBasicSynEdit;
(* TODO:
- TestEditEmpty:
Test with different sets of VirtualViews (with/without trimming (enabled/module present at all)
Word Left/Right: Need tests with fold, trim, selection
*)
{$mode objfpc}{$H+}
@ -31,8 +29,6 @@ type
procedure TestEditTabs;
procedure TestPhysicalLogical;
procedure TestCaretAutoMove;
procedure TestEditHomeEnd;
procedure TestCaretMoveLeftRightWord;
procedure TestCaretDeleteWord_LastWord;
end;
@ -475,433 +471,6 @@ begin
end;
procedure TTestBasicSynEdit.TestEditHomeEnd;
procedure DoInit1;
begin
InsertFlag := False;
TrimType := settIgnoreAll;
ReCreateEdit;
SynEdit.TabWidth := 6;
SyneDit.Options := [];
SyneDit.Options2 := [];
SetLines(['', //1
'',
'test', // 3
'',
'',
' ',
'test', // 3
#9#9#9#9#9,
' spaced', // 9
'',
'',
' ',
' spaced',
#9#9#9#9#9,
#9'tabbed', // 15
'',
'',
' ',
#9'tabbed',
#9#9#9#9#9,
#9' tabbed spaced', // 21
'',
'',
' ',
#9' tabbed spaced',
#9#9#9#9#9,
' ', // 27 (space only)
'',
'',
' ',
#9' ',
#9#9#9#9#9,
' spaced 9 for tab', // 33
#9#9#9#9#9,
' X ', // 35
' X'#9, // 36
''
]);
end;
procedure TestHome(Name:String; X, Y, ExpX1, ExpX2, ExpX3: Integer; ExpLTxTStartX: Integer = -1);
begin
SetCaretPhys(X, Y);
synedit.CommandProcessor(ecLineStart, '', nil);
TestIsCaretPhys(Name + '(1st home)', ExpX1,Y);
synedit.CommandProcessor(ecLineStart, '', nil);
TestIsCaretPhys(Name + '(2nd home)', ExpX2,Y);
synedit.CommandProcessor(ecLineStart, '', nil);
TestIsCaretPhys(Name + '(3rd home)', ExpX3,Y);
if ExpLTxTStartX > 0 then begin
SetCaretPhys(X, Y);
synedit.CommandProcessor(ecLineTextStart, '', nil);
TestIsCaretPhys(Name + '(1st line-text-start)', ExpLTxTStartX,Y);
synedit.CommandProcessor(ecLineTextStart, '', nil);
TestIsCaretPhys(Name + '(2nd line-text-start)', ExpLTxTStartX,Y);
synedit.CommandProcessor(ecLineTextStart, '', nil);
TestIsCaretPhys(Name + '(3rd line-text-start)', ExpLTxTStartX,Y);
end;
end;
procedure TestEnd(Name:String; X, Y, ExpX1, ExpX2, ExpX3: Integer);
begin
SetCaretPhys(X, Y);
synedit.CommandProcessor(ecLineEnd, '', nil);
TestIsCaretPhys(Name + '(1st end)', ExpX1,Y);
synedit.CommandProcessor(ecLineEnd, '', nil);
TestIsCaretPhys(Name + '(2nd end)', ExpX2,Y);
synedit.CommandProcessor(ecLineEnd, '', nil);
TestIsCaretPhys(Name + '(3rd end)', ExpX3,Y);
end;
begin
// None Smart-Home:
// Caret goes x=1, then x=indend
// Smart-Home:
// Caret goes x=indent, then 1, IF AFTER indent, or at x=1
// Caret goes x=1, then x=indend, IF at x=indent, or inside indent
// Both
// Caret does not go past eol, unless explicitly enabled
// if spaces/tab exist at start of otherwise empty line, caret will go to prev-line indent
{%region}
DoInit1;
PushBaseName('no smart / no past-eol');
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
TestHome('unindented line', 1, 3, 1,1,1, 1);
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
TestHome('space indented line', 1, 9, 4,1,4, 4);
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4); // go to indent, after absolute home
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
TestHome('space indented line x-in-line', 6, 9, 1,4,1, 4);
TestHome('1st after space indented line', 1,10, 1,1,1, 1);
TestHome('2nd after space indented line', 1,11, 1,1,1, 1);
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
TestHome('#9 after long space indented line [skipT]', 1,34, 7,1,7, 1);
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
TestHome('#9 after long space indented line [skipT]', 13,34, 1,7,1, 1);
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
TestHome('tab indented line', 1,15, 7,1,7, 7);
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
TestHome('tab indented line x-in-line', 9,15, 1,7,1, 7);
TestHome('1st after tab indented line', 1,16, 1,1,1, 1);
TestHome('2nd after tab indented line', 1,17, 1,1,1, 1);
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
{%endregion}
{%region}
DoInit1;
SyneDit.Options := [eoScrollPastEol];
PopPushBaseName('no smart / past-eol');
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
TestHome('unindented line', 1, 3, 1,1,1, 1);
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
TestHome('space indented line', 1, 9, 4,1,4, 4);
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4); // go to indent, after absolute home
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
TestHome('space indented line x-in-line', 6, 9, 1,4,1, 4);
TestHome('1st after space indented line', 1,10, 4,1,4, 1);
TestHome('1st after space indented line (x)', 2,10, 1,4,1, 1);
TestHome('2nd after space indented line', 1,11, 4,1,4, 1);
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
TestHome('#9 after long space indented line [skipT]', 1,34, 7,1,7, 1);
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
TestHome('#9 after long space indented line [skipT]', 13,34, 1,7,1, 1);
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
TestHome('tab indented line', 1,15, 7,1,7, 7);
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
TestHome('tab indented line x-in-line', 9,15, 1,7,1, 7);
TestHome('1st after tab indented line', 1,16, 7,1,7, 1);
TestHome('1st after tab indented line(x)', 2,16, 1,7,1, 1);
TestHome('2nd after tab indented line', 1,17, 7,1,7, 1);
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
{%endregion}
{%region}
DoInit1;
SyneDit.Options := [eoEnhanceHomeKey];
PopPushBaseName('smart home / no past-eol');
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
TestHome('unindented line', 1, 3, 1,1,1, 1);
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
TestHome('space indented line', 1, 9, 4,1,4, 4); // go to absolut home (x-=1), after indent
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4);
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
TestHome('space indented line x-in-line', 6, 9, 4,1,4, 4);
TestHome('1st after space indented line', 1,10, 1,1,1, 1);
TestHome('2nd after space indented line', 1,11, 1,1,1, 1);
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
TestHome('#9 after long space indented line [skipT]', 1,34, 7,1,7, 1);
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
TestHome('#9 after long space indented line [skipT]', 13,34, 7,1,7, 1);
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
TestHome('tab indented line', 1,15, 7,1,7, 7);
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
TestHome('tab indented line x-in-line', 9,15, 7,1,7, 7);
TestHome('1st after tab indented line', 1,16, 1,1,1, 1);
TestHome('2nd after tab indented line', 1,17, 1,1,1, 1);
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
TestHome('3rd #32 after tab indented line', 11,18, 7,1,7, 1);
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
{%endregion}
{%region}
DoInit1;
SyneDit.Options := [eoEnhanceHomeKey, eoScrollPastEol];
PopPushBaseName('smart home / past-eol');
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
TestHome('unindented line', 1, 3, 1,1,1, 1);
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
TestHome('space indented line', 1, 9, 4,1,4, 4); // go to absolut home (x-=1), after indent
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4);
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
TestHome('space indented line x-in-line', 6, 9, 4,1,4, 4);
TestHome('1st after space indented line', 1,10, 4,1,4, 1);
TestHome('2nd after space indented line', 1,11, 4,1,4, 1);
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
TestHome('tab indented line', 1,15, 7,1,7, 7);
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
TestHome('tab indented line x-in-line', 9,15, 7,1,7, 7);
TestHome('1st after tab indented line', 1,16, 7,1,7, 1);
TestHome('1st after tab indented line (x)', 2,16, 1,7,1, 1);
TestHome('2nd after tab indented line', 1,17, 7,1,7, 1);
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
TestHome('3rd #32 after tab indented line', 11,18, 7,1,7, 1);
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
{%endregion}
PopPushBaseName('NO smart end/ NO past-eol');
DoInit1;
TestEnd ('empty 1st line', 1,1, 1,1,1);
TestEnd ('end', 1,35, 6,3,6);
TestEnd ('end tab', 1,36, 7,3,7);
PopPushBaseName('smart end/ NO past-eol');
DoInit1;
SyneDit.Options2 := [eoEnhanceEndKey];
TestEnd ('end', 1,35, 3,6,3);
TestEnd ('end tab', 1,36, 3,7,3);
//SyneDit.Options := [eoScrollPastEol, eoEnhanceHomeKey];
//SyneDit.Options2 := [eoEnhanceEndKey];
end;
procedure TTestBasicSynEdit.TestCaretMoveLeftRightWord;
procedure DoInit;
begin
InsertFlag := False;
TrimEnabled := False;;
ReCreateEdit;
SynEdit.TabWidth := 7;
// 1 6 11 14
SetLines(['Some text to test', //1
// 1 5 9
'Foo bar abc', // 2
// 8 14 19 24
#9'Other line with tab', // 3
// 1 8 11 15
'tab'#9'in the middle', // 4
// 1 9 12 16 23 28
'tab'#9' in the middle with space', // 5
// 1 9 13 16
'umlaute äää in text', // 6
'normal line',
// 4 14 21 28 32
' untrimmed spaces around line ', // 8
'normal line',
// 8 15 22 26
#9'tab'#9'only'#9'line'#9, // 10
// 1 8
'normal line',
'', // 12 (empty)
'normal line',
' ', // space only empty line // 14
'normal line',
'',
'A B', // 17
'normal line', // 18
''
]);
end;
procedure TestWordLeft(Name:String; X, Y, ExpX1, ExpY1: Integer;
ExpX2: Integer = -1; ExpY2: Integer = -1);
begin
SetCaretPhys(X,Y);
SynEdit.CommandProcessor(ecWordLeft, '', nil);
TestIsCaretPhys(Name + '(1st WordLeft)', ExpX1, ExpY1);
if ExpY2 > 0 then begin
SynEdit.CommandProcessor(ecWordLeft, '', nil);
TestIsCaretPhys(Name + '(2nd WordLeft)', ExpX2, ExpY2);
end;
end;
procedure TestWordRight(Name:String; X, Y, ExpX1, ExpY1: Integer;
ExpX2: Integer = -1; ExpY2: Integer = -1);
begin
SetCaretPhys(X,Y);
SynEdit.CommandProcessor(ecWordRight, '', nil);
TestIsCaretPhys(Name + '(1st WordRight)', ExpX1, ExpY1);
if ExpY2 > 0 then begin
SynEdit.CommandProcessor(ecWordRight, '', nil);
TestIsCaretPhys(Name + '(2nd WordRight)', ExpX2, ExpY2);
end;
end;
begin
DoInit;
{%region word left}
TestWordLeft('simple "te|st"', 16, 1, 14, 1, 11, 1);
TestWordLeft('simple EOW "test|"', 18, 1, 14, 1, 11, 1);
TestWordLeft('simple BOW "|test"', 14, 1, 11, 1, 6, 1);
TestWordLeft('simple > BOT "So|me"', 3, 1, 1, 1, 1, 1);
TestWordLeft('simple > prev-line "F|oo"', 2, 2, 1, 2, 18, 1);
TestWordLeft('simple > prev-line "|Foo"', 1, 2, 18, 1, 14, 1);
TestWordLeft('tab "wi|th"', 21, 3, 19, 3, 14, 3);
TestWordLeft('tab EOW "with|"', 23, 3, 19, 3, 14, 3);
TestWordLeft('tab BOW "|with"', 19, 3, 14, 3, 8, 3);
TestWordLeft('tab > prev-line "O|ther"', 9, 3, 8, 3, 12, 2);
TestWordLeft('M-tab "i|n"', 9, 4, 8, 4, 1, 4);
TestWordLeft('M-tab > prev-line-tab "ta|b"', 3, 4, 1, 4, 27, 3);
TestWordLeft('M-S-tab "i|n"', 10, 5, 9, 5, 1, 5);
TestWordLeft('M-S-EOW tab "in|"', 11, 5, 9, 5, 1, 5);
TestWordLeft('M-S-BOW tab "|in"', 9, 5, 1, 5, 21, 4);
TestWordLeft('M-S-tab "#9| in"', 8, 5, 1, 5);
TestWordLeft('Umlaut "ää|ä"', 11, 6, 9, 6, 1, 6);
TestWordLeft('Umlaut EOW "äää|"', 12, 6, 9, 6, 1, 6);
TestWordLeft('Umlaut BOW "|äää"', 9, 6, 1, 6, 33, 5);
TestWordLeft('Umlaut "i|n"', 14, 6, 13, 6, 9, 6);
TestWordLeft('After Umlaut > prev line', 1, 7, 20, 6, 16, 6);
TestWordLeft('untrimmed "un|trimmed"', 6, 8, 4, 8, 12, 7);
TestWordLeft('After untrimmed > prev', 1, 9, 35, 8, 28, 8);
TestWordLeft('untrimmed tab "t|ab"', 9,10, 8,10, 12, 9);
TestWordLeft('After untrimmed tab > prev', 1,11, 29,10, 22,10);
TestWordLeft('After empty > prev', 1,13, 1,12);
TestWordLeft('After space empty > prev', 1,15, 6,14);
TestWordLeft('single char at eol "A B|"', 4,17, 3,17, 1,17);
{%endregion}
{%region word right}
TestWordRight('simple "te|xt"', 8, 1, 11, 1, 14, 1);
TestWordRight('simple EOW "text|"', 10, 1, 11, 1, 14, 1);
TestWordRight('simple BOW "|text"', 6, 1, 11, 1, 14, 1);
TestWordRight('simple EOT "li|ne"', 10,18, 12,18, 12,18);
TestWordRight('simple > EOL, next line "te|st"', 16, 1, 18, 1, 1, 2);
TestWordRight('tab "li|ne"', 16, 3, 19, 3, 24, 3);
TestWordRight('tab EOW "line|"', 18, 3, 19, 3, 24, 3);
TestWordRight('tab BOW "|line"', 14, 3, 19, 3, 24, 3);
TestWordRight('tab > EOL, next-line', 25, 3, 27, 3, 1, 4);
TestWordRight('M-tab "t|ab"', 2, 4, 8, 4, 11, 4);
TestWordRight('M-tab "tab|"', 4, 4, 8, 4, 11, 4);
TestWordRight('M-tab > EOL, next-line-tab', 17, 4, 21, 4, 1, 5);
TestWordRight('M-S-tab BOW "t|ab"', 2, 5, 9, 5, 12, 5);
TestWordRight('M-S-tab EOW "tab|"', 4, 5, 9, 5, 12, 5);
TestWordRight('M-S-tab BOW "|tab"', 1, 5, 9, 5, 12, 5);
TestWordRight('M-S-tab "tab#9| "', 5, 5, 9, 5, 12, 5);
TestWordRight('Umlaut "ää|ä"', 11, 6, 13, 6, 16, 6);
TestWordRight('Umlaut EOW "äää|"', 12, 6, 13, 6, 16, 6);
TestWordRight('Umlaut BOW "|äää"', 9, 6, 13, 6, 16, 6);
TestWordRight('Umlaut "um|laute"', 2, 6, 9, 6, 13, 6);
TestWordRight('After Umlaut > EOL, next line', 18, 6, 20, 6, 1, 7);
TestWordRight('Before untrimmed > next', 12, 7, 4, 8, 14, 8);
TestWordRight('untrimmed > EOL, next', 30, 8, 35, 8, 1, 9);
TestWordRight('Before untrimmed tab > next', 12, 9, 8,10, 15,10);
TestWordRight('untrimmed tab > EOL, next', 24,10, 29,10, 1,11);
TestWordRight('Before empty > next', 12,11, 1,12);
TestWordRight('Before space empty > next', 12,13, 1,14, 6, 14);
{%endregion}
end;
procedure TTestBasicSynEdit.TestCaretDeleteWord_LastWord;
var
AllowPastEOL: Boolean;

View File

@ -0,0 +1,794 @@
unit TestNavigation;
(* TODO:
Word Left/Right: Need tests with fold, trim, selection
*)
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, testregistry, LCLProc, LCLType, Forms, TestBase,
SynEdit, SynEditTextTrimmer, SynEditKeyCmds, LazSynEditText;
type
{ TTestSynNavigation }
TTestSynNavigation = class(TTestBase)
published
procedure TestCaretHomeEnd;
procedure TestCaretLeftRight;
procedure TestCaretMoveLeftRightWord;
//procedure TestCaretMoveLeftRightPartWord;
end;
implementation
{ TTestSynNavigation }
procedure TTestSynNavigation.TestCaretHomeEnd;
procedure DoInit1;
begin
ReCreateEdit;
SynEdit.TabWidth := 6;
SyneDit.Options := [];
SyneDit.Options2 := [];
SetLines(['', //1
'',
'test', // 3
'',
'',
' ',
'test', // 3
#9#9#9#9#9,
' spaced', // 9
'',
'',
' ',
' spaced',
#9#9#9#9#9,
#9'tabbed', // 15
'',
'',
' ',
#9'tabbed',
#9#9#9#9#9,
#9' tabbed spaced', // 21
'',
'',
' ',
#9' tabbed spaced',
#9#9#9#9#9,
' ', // 27 (space only)
'',
'',
' ',
#9' ',
#9#9#9#9#9,
' spaced 9 for tab', // 33
#9#9#9#9#9,
' X ', // 35
' X'#9, // 36
''
]);
end;
procedure TestHome(Name:String; X, Y, ExpX1, ExpX2, ExpX3: Integer; ExpLTxTStartX: Integer = -1);
begin
SetCaretPhys(X, Y);
synedit.CommandProcessor(ecLineStart, '', nil);
TestIsCaretPhys(Name + '(1st home)', ExpX1,Y);
synedit.CommandProcessor(ecLineStart, '', nil);
TestIsCaretPhys(Name + '(2nd home)', ExpX2,Y);
synedit.CommandProcessor(ecLineStart, '', nil);
TestIsCaretPhys(Name + '(3rd home)', ExpX3,Y);
if ExpLTxTStartX > 0 then begin
SetCaretPhys(X, Y);
synedit.CommandProcessor(ecLineTextStart, '', nil);
TestIsCaretPhys(Name + '(1st line-text-start)', ExpLTxTStartX,Y);
synedit.CommandProcessor(ecLineTextStart, '', nil);
TestIsCaretPhys(Name + '(2nd line-text-start)', ExpLTxTStartX,Y);
synedit.CommandProcessor(ecLineTextStart, '', nil);
TestIsCaretPhys(Name + '(3rd line-text-start)', ExpLTxTStartX,Y);
end;
end;
procedure TestEnd(Name:String; X, Y, ExpX1, ExpX2, ExpX3: Integer);
begin
SetCaretPhys(X, Y);
synedit.CommandProcessor(ecLineEnd, '', nil);
TestIsCaretPhys(Name + '(1st end)', ExpX1,Y);
synedit.CommandProcessor(ecLineEnd, '', nil);
TestIsCaretPhys(Name + '(2nd end)', ExpX2,Y);
synedit.CommandProcessor(ecLineEnd, '', nil);
TestIsCaretPhys(Name + '(3rd end)', ExpX3,Y);
end;
begin
// None Smart-Home:
// Caret goes x=1, then x=indend
// Smart-Home:
// Caret goes x=indent, then 1, IF AFTER indent, or at x=1
// Caret goes x=1, then x=indend, IF at x=indent, or inside indent
// Both
// Caret does not go past eol, unless explicitly enabled
// if spaces/tab exist at start of otherwise empty line, caret will go to prev-line indent
{%region}
DoInit1;
PushBaseName('no smart / no past-eol');
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
TestHome('unindented line', 1, 3, 1,1,1, 1);
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
TestHome('space indented line', 1, 9, 4,1,4, 4);
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4); // go to indent, after absolute home
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
TestHome('space indented line x-in-line', 6, 9, 1,4,1, 4);
TestHome('1st after space indented line', 1,10, 1,1,1, 1);
TestHome('2nd after space indented line', 1,11, 1,1,1, 1);
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
TestHome('#9 after long space indented line [skipT]', 1,34, 7,1,7, 1);
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
TestHome('#9 after long space indented line [skipT]', 13,34, 1,7,1, 1);
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
TestHome('tab indented line', 1,15, 7,1,7, 7);
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
TestHome('tab indented line x-in-line', 9,15, 1,7,1, 7);
TestHome('1st after tab indented line', 1,16, 1,1,1, 1);
TestHome('2nd after tab indented line', 1,17, 1,1,1, 1);
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
{%endregion}
{%region}
DoInit1;
SyneDit.Options := [eoScrollPastEol];
PopPushBaseName('no smart / past-eol');
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
TestHome('unindented line', 1, 3, 1,1,1, 1);
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
TestHome('space indented line', 1, 9, 4,1,4, 4);
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4); // go to indent, after absolute home
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
TestHome('space indented line x-in-line', 6, 9, 1,4,1, 4);
TestHome('1st after space indented line', 1,10, 4,1,4, 1);
TestHome('1st after space indented line (x)', 2,10, 1,4,1, 1);
TestHome('2nd after space indented line', 1,11, 4,1,4, 1);
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
TestHome('#9 after long space indented line [skipT]', 1,34, 7,1,7, 1);
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
TestHome('#9 after long space indented line [skipT]', 13,34, 1,7,1, 1);
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
TestHome('tab indented line', 1,15, 7,1,7, 7);
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
TestHome('tab indented line x-in-line', 9,15, 1,7,1, 7);
TestHome('1st after tab indented line', 1,16, 7,1,7, 1);
TestHome('1st after tab indented line(x)', 2,16, 1,7,1, 1);
TestHome('2nd after tab indented line', 1,17, 7,1,7, 1);
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
{%endregion}
{%region}
DoInit1;
SyneDit.Options := [eoEnhanceHomeKey];
PopPushBaseName('smart home / no past-eol');
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
TestHome('unindented line', 1, 3, 1,1,1, 1);
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
TestHome('space indented line', 1, 9, 4,1,4, 4); // go to absolut home (x-=1), after indent
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4);
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
TestHome('space indented line x-in-line', 6, 9, 4,1,4, 4);
TestHome('1st after space indented line', 1,10, 1,1,1, 1);
TestHome('2nd after space indented line', 1,11, 1,1,1, 1);
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
TestHome('#9 after long space indented line [skipT]', 1,34, 7,1,7, 1);
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
TestHome('#9 after long space indented line [skipT]', 13,34, 7,1,7, 1);
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
TestHome('tab indented line', 1,15, 7,1,7, 7);
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
TestHome('tab indented line x-in-line', 9,15, 7,1,7, 7);
TestHome('1st after tab indented line', 1,16, 1,1,1, 1);
TestHome('2nd after tab indented line', 1,17, 1,1,1, 1);
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
TestHome('3rd #32 after tab indented line', 11,18, 7,1,7, 1);
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
{%endregion}
{%region}
DoInit1;
SyneDit.Options := [eoEnhanceHomeKey, eoScrollPastEol];
PopPushBaseName('smart home / past-eol');
TestHome('empty 1st line', 1, 1, 1,1,1, 1);
TestHome('empty 2nd line', 1, 2, 1,1,1, 1);
TestHome('unindented line', 1, 3, 1,1,1, 1);
TestHome('unindented line x-in-line', 4, 3, 1,1,1, 1);
TestHome('1st line after unindendet', 1, 4, 1,1,1, 1);
TestHome('2nd line after unindendet', 1, 5, 1,1,1, 1);
TestHome('3rd #32 line after unindendet', 2, 6, 1,1,1, 1);
TestHome('4th #9 line after unindendet', 2, 8, 1,1,1, 1);
TestHome('space indented line', 1, 9, 4,1,4, 4); // go to absolut home (x-=1), after indent
TestHome('space indented line x-after-indent', 4, 9, 1,4,1, 4);
TestHome('space indented line x-in-indent', 3, 9, 1,4,1, 4);
TestHome('space indented line x-in-line', 6, 9, 4,1,4, 4);
TestHome('1st after space indented line', 1,10, 4,1,4, 1);
TestHome('2nd after space indented line', 1,11, 4,1,4, 1);
TestHome('3rd #32 after space indented line', 2,12, 1,4,1, 1);
TestHome('4th #9 after space indented line', 2,14, 1,4,1, 1);
TestHome('#9 after long space indented line', 2,34, 1,9,1, 1);
SyneDit.Options2 := SyneDit.Options2 + [eoCaretSkipTab];
TestHome('4th #9 after space indented line [skipT]', 7,14, 1,1,1, 1);
TestHome('#9 after long space indented line [skipT]', 7,34, 1,7,1, 1);
SyneDit.Options2 := SyneDit.Options2 - [eoCaretSkipTab];
TestHome('tab indented line', 1,15, 7,1,7, 7);
TestHome('tab indented line x-after-indent', 7,15, 1,7,1, 7);
TestHome('tab indented line x-in-indent', 5,15, 1,7,1, 7);
TestHome('tab indented line x-in-line', 9,15, 7,1,7, 7);
TestHome('1st after tab indented line', 1,16, 7,1,7, 1);
TestHome('1st after tab indented line (x)', 2,16, 1,7,1, 1);
TestHome('2nd after tab indented line', 1,17, 7,1,7, 1);
TestHome('3rd #32 after tab indented line', 2,18, 1,7,1, 1);
TestHome('3rd #32 after tab indented line', 11,18, 7,1,7, 1);
TestHome('4th #9 after tab indented line', 2,20, 1,7,1, 1);
{%endregion}
PopPushBaseName('NO smart end/ NO past-eol');
DoInit1;
TestEnd ('empty 1st line', 1,1, 1,1,1);
TestEnd ('end', 1,35, 6,3,6);
TestEnd ('end tab', 1,36, 7,3,7);
PopPushBaseName('smart end/ NO past-eol');
DoInit1;
SyneDit.Options2 := [eoEnhanceEndKey];
TestEnd ('end', 1,35, 3,6,3);
TestEnd ('end tab', 1,36, 3,7,3);
//SyneDit.Options := [eoScrollPastEol, eoEnhanceHomeKey];
//SyneDit.Options2 := [eoEnhanceEndKey];
end;
procedure TTestSynNavigation.TestCaretLeftRight;
procedure SetTextLeftRight;
begin
ReCreateEdit;
SetLines([ 'ああああああああああああああああああああああ', // 1: Double width at odd pos (start at 1, then every 2)
' ああああああああああああああああああああああ', // 2: Double width at even pos
'', // 3: empty
#9#9#9#9#9#9#9#9, // 4: tabs
'abc'#9'def', // 5: text+tabs
'abc def üüü xyz', // 6: utf8 multibyte
'abc def ü'#9'üü xyz', // 7: utf8 multibyte + tabs
'abc あdefあ123', // 8: Double withs
'abc あdef'#9'あ'#9'123', // 9: Double withs + tabs
''
]);
end;
procedure TestLeftRight(AName: String; ALine: Integer; AStartPhysX: Integer; ACommand:TSynEditorCommand;
ExpPhysX, ExpLogX: Integer; ExpRepeatPhysX: Integer = -1; ExpRepeatLogX: Integer = -1;
DoReverse: Boolean = True; DoKeepXDWidth: Boolean = True;
ASelectXEnd: Integer = -1; ExpCaretY: integer = -1);
var
Name2: String;
TestLogFirst: Boolean;
procedure DoCmd;
begin
if ASelectXEnd < 0
then SetCaretPhys(AStartPhysX, ALine)
else SetCaretAndSelPhys(ASelectXEnd, ALine, AStartPhysX, ALine);
SynEdit.ExecuteCommand(ACommand, '', nil);
end;
procedure TestCmd;
begin
DoCmd;
if not TestLogFirst then
TestIsCaretPhys(Name2+'[1]', ExpPhysX, ExpCaretY);
TestIsCaret(Name2+'[1]', ExpLogX, ExpCaretY);
TestIsCaretPhys(Name2+'[1]', ExpPhysX, ExpCaretY);
end;
procedure DoCmdRepeat;
begin
if ExpRepeatPhysX < 0 then exit;
SynEdit.ExecuteCommand(ACommand, '', nil);
end;
procedure TestCmdRepeat;
begin
if ExpRepeatPhysX < 0 then exit;
DoCmdRepeat;
if not TestLogFirst then
TestIsCaretPhys(Name2+'[2]', ExpRepeatPhysX, ExpCaretY);
if ExpRepeatLogX > 0 then
TestIsCaret(Name2+'[2]', ExpRepeatLogX, ExpCaretY);
TestIsCaretPhys(Name2+'[2]', ExpRepeatPhysX, ExpCaretY);
end;
procedure DoCmdReverse(AfterRepeat: Boolean = false);
begin
if not DoReverse then exit;
if AfterRepeat and (ExpRepeatPhysX < 0) then exit; // was never repeated
if ACommand = ecLeft
then SynEdit.ExecuteCommand(ecRight, '', nil)
else SynEdit.ExecuteCommand(ecLeft, '', nil);
end;
procedure TestCmdReverse(AfterRepeat: Boolean = false);
begin
if not DoReverse then exit;
if AfterRepeat and (ExpRepeatPhysX < 0) then exit; // was never repeated
DoCmdReverse(AfterRepeat);
if AfterRepeat then begin
if not TestLogFirst then
TestIsCaretPhys(Name2+'[R,'+dbgs(AfterRepeat)+']', ExpPhysX, ExpCaretY);
TestIsCaret(Name2, ExpLogX, ExpCaretY);
TestIsCaretPhys(Name2+'[R,'+dbgs(AfterRepeat)+']', ExpPhysX, ExpCaretY);
end else begin
TestIsCaretPhys(Name2+'[R,'+dbgs(AfterRepeat)+']', AStartPhysX, ALine);
end;
end;
procedure DoKeepXOnEmpty;
begin
if (ExpPhysX > 1) and not(eoScrollPastEol in SynEdit.Options) then begin
SynEdit.CaretObj.LinePos := 3; // empty line
SynEdit.CaretObj.LinePos := ExpCaretY;
end;
end;
procedure TestKeepXOnEmpty(TestBetween: Boolean = False);
begin
if (ExpPhysX > 1) and not(eoScrollPastEol in SynEdit.Options) then begin
SynEdit.CaretObj.LinePos := 3; // empty line
if TestBetween then
AssertEquals(Name2+'empty line at pos 1', 1, SynEdit.CaretObj.CharPos);
SynEdit.CaretObj.LinePos := ExpCaretY;
if eoKeepCaretX in SynEdit.Options
then AssertEquals(Name2+'after empty line at pos 1', ExpPhysX, SynEdit.CaretObj.CharPos)
else AssertEquals(Name2+'after empty line at pos 1', 1, SynEdit.CaretObj.CharPos);
end;
end;
procedure DoKeepXOnDWidth;
begin
if (ExpPhysX > 1) and DoKeepXDWidth then begin
if (ExpPhysX and 1) = 0
then SynEdit.CaretObj.LinePos := 1 // double width odd
else SynEdit.CaretObj.LinePos := 2; // double width even
SynEdit.CaretObj.LinePos := ExpCaretY;
end;
end;
procedure TestKeepXOnDWidth(TestBetween: Boolean = False);
begin
if (ExpPhysX > 1) and DoKeepXDWidth then begin
if (ExpPhysX and 1) = 0
then SynEdit.CaretObj.LinePos := 1 // double width odd
else SynEdit.CaretObj.LinePos := 2; // double width even
if TestBetween then
AssertFalse(Name2+'after dwidth line at pos 1', ExpPhysX = SynEdit.CaretObj.CharPos);
SynEdit.CaretObj.LinePos := ExpCaretY;
AssertTrue(Name2+'after dwidth line at pos 1',
(ExpPhysX = SynEdit.CaretObj.CharPos) = (eoKeepCaretX in SynEdit.Options));
end;
end;
var
s: string;
begin
if ExpCaretY < 0 then ExpCaretY := ALine;
EditorCommandToIdent(ACommand, s);
AName := Format('%s (%s Y=%d, X=%d) ', [AName, s, ALine, AStartPhysX]);
{%region NO eoKeepCaretX}
SynEdit.Options := SynEdit.Options - [eoKeepCaretX];
Name2 := AName + 'NO eoKeepCaretX: ';
TestLogFirst := False;
TestCmd;
TestCmdReverse;
TestCmd;
TestCmdRepeat;
TestCmdReverse(True);
TestCmdReverse;
DoCmd;
TestCmdReverse;
DoCmd;
DoCmdRepeat;
TestCmdReverse(True);
TestCmdReverse;
TestLogFirst := True;
TestCmd;
TestCmdReverse;
TestCmd;
TestCmdRepeat;
TestCmdReverse(True);
TestCmdReverse;
TestCmd;
TestKeepXOnEmpty(False);
TestCmd;
TestKeepXOnEmpty(True);
TestCmd;
TestKeepXOnDWidth(False);
TestCmd;
TestKeepXOnDWidth(True);
{%endregion NO eoKeepCaretX}
{%region WITH eoKeepCaretX}
SynEdit.Options := SynEdit.Options + [eoKeepCaretX];
Name2 := Name2 + 'WITH eoKeepCaretX: ';
TestLogFirst := False;
TestCmd;
TestCmdReverse;
TestCmd;
TestCmdRepeat;
TestCmdReverse(True);
TestCmdReverse;
DoCmd;
TestCmdReverse;
DoCmd;
DoCmdRepeat;
TestCmdReverse(True);
TestCmdReverse;
TestLogFirst := True;
TestCmd;
TestCmdReverse;
TestCmd;
TestCmdRepeat;
TestCmdReverse(True);
TestCmdReverse;
TestCmd;
TestKeepXOnEmpty(False);
if ASelectXEnd < 0 then
TestCmdReverse;
TestCmd;
TestKeepXOnEmpty(True);
if ASelectXEnd < 0 then
TestCmdReverse;
TestCmd;
TestKeepXOnEmpty(False);
TestCmdRepeat;
TestCmd;
TestKeepXOnDWidth(False);
if ASelectXEnd < 0 then
TestCmdReverse;
TestCmd;
TestKeepXOnDWidth(True);
if ASelectXEnd < 0 then
TestCmdReverse;
TestCmd;
TestKeepXOnDWidth(False);
TestCmdRepeat;
{%endregion WITH eoKeepCaretX}
end;
begin
SetTextLeftRight;
{%region ecRight}
PushBaseName('No opts');
SynEdit.TabWidth := 6;
SynEdit.MaxLeftChar := 200;
SynEdit.Options := [];
SynEdit.Options2 := [];
TestLeftRight('Simple right', 5, 2, ecRight, 3, 3, 4, 4);
TestLeftRight('After tab right', 5, 7, ecRight, 8, 6, 9, 7);
TestLeftRight('Before tab right', 5, 4, ecRight, 5, 4, 6, 4);
TestLeftRight('Mid tab right', 5, 5, ecRight, 6, 4, 7, 5);
TestLeftRight('tab to tab right', 4, 6, ecRight, 7, 2, 8, 2);
TestLeftRight('Umlaut right', 6, 9, ecRight, 10,11, 11,13);
TestLeftRight('Double W right', 8, 5, ecRight, 7, 8, 8, 9);
TestLeftRight('at EOL right', 5, 10, ecRight, 1, 1, 2, 2, True, True, -1 , 6);
PopPushBaseName('eoScrollPastEol');
SynEdit.Options := [eoScrollPastEol];
TestLeftRight('at EOL right', 5, 10, ecRight, 11, 9, 12,10);
TestLeftRight('at Max-left right', 5,199, ecRight, 200,198, 200,198, False, False);
PopPushBaseName('eoCaretSkipTab');
SynEdit.Options := [];
SynEdit.Options2 := [eoCaretSkipTab];
TestLeftRight('Simple right', 5, 2, ecRight, 3, 3, 4, 4);
TestLeftRight('After tab right', 5, 7, ecRight, 8, 6, 9, 7);
TestLeftRight('Before tab right', 5, 4, ecRight, 7, 5, 8, 6);
TestLeftRight('tab to tab right', 4, 7, ecRight, 13, 3, 19, 4);
PopPushBaseName('eoCaretSkipsSelection');
SynEdit.Options2 := [eoCaretSkipsSelection];
TestLeftRight('Selected right', 5, 2, ecRight, 8, 6, -1, -1, True, False, 8);
{%region ecRight}
{%region ecLeft}
SynEdit.Options := [];
SynEdit.Options2 := [];
TestLeftRight('Simple left', 5, 3, ecLeft, 2, 2, 1, 1);
TestLeftRight('After tab left', 5, 7, ecLeft, 6, 4, 5, 4);
TestLeftRight('Before tab left', 5, 4, ecLeft, 3, 3, 2, 2);
TestLeftRight('Mid tab left', 5, 5, ecLeft, 4, 4, 3, 3);
TestLeftRight('tab to tab left', 4, 8, ecLeft, 7, 2, 6, 1);
TestLeftRight('Umlaut left', 6, 10, ecLeft, 9, 9, 8, 8);
TestLeftRight('Double W left', 8, 7, ecLeft, 5, 5, 4, 4);
TestLeftRight('at BOL left', 6, 1, ecLeft, 10, 8, 9, 7, True, True, -1 , 5);
PopPushBaseName('eoScrollPastEol');
SynEdit.Options := [eoScrollPastEol];
TestLeftRight('at BOL left', 6, 1, ecLeft, 1, 1, 1, 1, False, False);
PopPushBaseName('eoCaretSkipTab');
SynEdit.Options := [];
SynEdit.Options2 := [eoCaretSkipTab];
TestLeftRight('Simple left', 5, 3, ecLeft, 2, 2, 1, 1);
TestLeftRight('After tab left', 5, 7, ecLeft, 4, 4, 3, 3);
TestLeftRight('tab to tab left', 4, 13, ecLeft, 7, 2, 1, 1);
PopPushBaseName('eoCaretSkipsSelection');
SynEdit.Options2 := [eoCaretSkipsSelection];
TestLeftRight('Selected left', 5, 8, ecLeft, 3, 3, -1, -1, True, False, 3);
{%endregion ecLeft}
PopBaseName;
end;
procedure TTestSynNavigation.TestCaretMoveLeftRightWord;
procedure DoInit;
begin
ReCreateEdit;
SynEdit.TabWidth := 7;
// 1 6 11 14
SetLines(['Some text to test', //1
// 1 5 9
'Foo bar abc', // 2
// 8 14 19 24
#9'Other line with tab', // 3
// 1 8 11 15
'tab'#9'in the middle', // 4
// 1 9 12 16 23 28
'tab'#9' in the middle with space', // 5
// 1 9 13 16
'umlaute äää in text', // 6
'normal line',
// 4 14 21 28 32
' untrimmed spaces around line ', // 8
'normal line',
// 8 15 22 26
#9'tab'#9'only'#9'line'#9, // 10
// 1 8
'normal line',
'', // 12 (empty)
'normal line',
' ', // space only empty line // 14
'normal line',
'',
'A B', // 17
'normal line', // 18
''
]);
end;
procedure TestWordLeft(Name:String; X, Y, ExpX1, ExpY1: Integer;
ExpX2: Integer = -1; ExpY2: Integer = -1);
begin
SetCaretPhys(X,Y);
SynEdit.CommandProcessor(ecWordLeft, '', nil);
TestIsCaretPhys(Name + '(1st WordLeft)', ExpX1, ExpY1);
if ExpY2 > 0 then begin
SynEdit.CommandProcessor(ecWordLeft, '', nil);
TestIsCaretPhys(Name + '(2nd WordLeft)', ExpX2, ExpY2);
end;
end;
procedure TestWordRight(Name:String; X, Y, ExpX1, ExpY1: Integer;
ExpX2: Integer = -1; ExpY2: Integer = -1);
begin
SetCaretPhys(X,Y);
SynEdit.CommandProcessor(ecWordRight, '', nil);
TestIsCaretPhys(Name + '(1st WordRight)', ExpX1, ExpY1);
if ExpY2 > 0 then begin
SynEdit.CommandProcessor(ecWordRight, '', nil);
TestIsCaretPhys(Name + '(2nd WordRight)', ExpX2, ExpY2);
end;
end;
begin
DoInit;
{%region word left}
TestWordLeft('simple "te|st"', 16, 1, 14, 1, 11, 1);
TestWordLeft('simple EOW "test|"', 18, 1, 14, 1, 11, 1);
TestWordLeft('simple BOW "|test"', 14, 1, 11, 1, 6, 1);
TestWordLeft('simple > BOT "So|me"', 3, 1, 1, 1, 1, 1);
TestWordLeft('simple > prev-line "F|oo"', 2, 2, 1, 2, 18, 1);
TestWordLeft('simple > prev-line "|Foo"', 1, 2, 18, 1, 14, 1);
TestWordLeft('tab "wi|th"', 21, 3, 19, 3, 14, 3);
TestWordLeft('tab EOW "with|"', 23, 3, 19, 3, 14, 3);
TestWordLeft('tab BOW "|with"', 19, 3, 14, 3, 8, 3);
TestWordLeft('tab > prev-line "O|ther"', 9, 3, 8, 3, 12, 2);
TestWordLeft('M-tab "i|n"', 9, 4, 8, 4, 1, 4);
TestWordLeft('M-tab > prev-line-tab "ta|b"', 3, 4, 1, 4, 27, 3);
TestWordLeft('M-S-tab "i|n"', 10, 5, 9, 5, 1, 5);
TestWordLeft('M-S-EOW tab "in|"', 11, 5, 9, 5, 1, 5);
TestWordLeft('M-S-BOW tab "|in"', 9, 5, 1, 5, 21, 4);
TestWordLeft('M-S-tab "#9| in"', 8, 5, 1, 5);
TestWordLeft('Umlaut "ää|ä"', 11, 6, 9, 6, 1, 6);
TestWordLeft('Umlaut EOW "äää|"', 12, 6, 9, 6, 1, 6);
TestWordLeft('Umlaut BOW "|äää"', 9, 6, 1, 6, 33, 5);
TestWordLeft('Umlaut "i|n"', 14, 6, 13, 6, 9, 6);
TestWordLeft('After Umlaut > prev line', 1, 7, 20, 6, 16, 6);
TestWordLeft('untrimmed "un|trimmed"', 6, 8, 4, 8, 12, 7);
TestWordLeft('After untrimmed > prev', 1, 9, 35, 8, 28, 8);
TestWordLeft('untrimmed tab "t|ab"', 9,10, 8,10, 12, 9);
TestWordLeft('After untrimmed tab > prev', 1,11, 29,10, 22,10);
TestWordLeft('After empty > prev', 1,13, 1,12);
TestWordLeft('After space empty > prev', 1,15, 6,14);
TestWordLeft('single char at eol "A B|"', 4,17, 3,17, 1,17);
{%endregion}
{%region word right}
TestWordRight('simple "te|xt"', 8, 1, 11, 1, 14, 1);
TestWordRight('simple EOW "text|"', 10, 1, 11, 1, 14, 1);
TestWordRight('simple BOW "|text"', 6, 1, 11, 1, 14, 1);
TestWordRight('simple EOT "li|ne"', 10,18, 12,18, 12,18);
TestWordRight('simple > EOL, next line "te|st"', 16, 1, 18, 1, 1, 2);
TestWordRight('tab "li|ne"', 16, 3, 19, 3, 24, 3);
TestWordRight('tab EOW "line|"', 18, 3, 19, 3, 24, 3);
TestWordRight('tab BOW "|line"', 14, 3, 19, 3, 24, 3);
TestWordRight('tab > EOL, next-line', 25, 3, 27, 3, 1, 4);
TestWordRight('M-tab "t|ab"', 2, 4, 8, 4, 11, 4);
TestWordRight('M-tab "tab|"', 4, 4, 8, 4, 11, 4);
TestWordRight('M-tab > EOL, next-line-tab', 17, 4, 21, 4, 1, 5);
TestWordRight('M-S-tab BOW "t|ab"', 2, 5, 9, 5, 12, 5);
TestWordRight('M-S-tab EOW "tab|"', 4, 5, 9, 5, 12, 5);
TestWordRight('M-S-tab BOW "|tab"', 1, 5, 9, 5, 12, 5);
TestWordRight('M-S-tab "tab#9| "', 5, 5, 9, 5, 12, 5);
TestWordRight('Umlaut "ää|ä"', 11, 6, 13, 6, 16, 6);
TestWordRight('Umlaut EOW "äää|"', 12, 6, 13, 6, 16, 6);
TestWordRight('Umlaut BOW "|äää"', 9, 6, 13, 6, 16, 6);
TestWordRight('Umlaut "um|laute"', 2, 6, 9, 6, 13, 6);
TestWordRight('After Umlaut > EOL, next line', 18, 6, 20, 6, 1, 7);
TestWordRight('Before untrimmed > next', 12, 7, 4, 8, 14, 8);
TestWordRight('untrimmed > EOL, next', 30, 8, 35, 8, 1, 9);
TestWordRight('Before untrimmed tab > next', 12, 9, 8,10, 15,10);
TestWordRight('untrimmed tab > EOL, next', 24,10, 29,10, 1,11);
TestWordRight('Before empty > next', 12,11, 1,12);
TestWordRight('Before space empty > next', 12,13, 1,14, 6, 14);
{%endregion}
end;
initialization
RegisterTest(TTestSynNavigation);
end.