~ubuntu-branches/ubuntu/vivid/lazarus/vivid

« back to all changes in this revision

Viewing changes to components/synedit/test/testnavigation.pas

  • Committer: Package Import Robot
  • Author(s): Paul Gevers, Abou Al Montacir, Paul Gevers
  • Date: 2014-02-22 10:25:57 UTC
  • mfrom: (1.1.11)
  • Revision ID: package-import@ubuntu.com-20140222102557-ors9d31r84nz31jq
Tags: 1.2~rc2+dfsg-1
[ Abou Al Montacir ]
* New upstream pre-release.
  + Moved ideintf to components directory.
  + Added new package cairocanvas.
* Remove usage of depreciated parameters form of find. (Closes: Bug#724776)
* Bumped standard version to 3.9.5.
* Clean the way handling make files generation and removal.

[ Paul Gevers ]
* Remove nearly obsolete bzip compression for binary packages
  (See https://lists.debian.org/debian-devel/2014/01/msg00542.html)
* Update d/copyright for newly added dir in examples and components
* Update Vcs-* fields with new packaging location
* Update d/watch file to properly (Debian way) change upstreams versions
* Prevent 46MB of package size by sym linking duplicate files
* Patches
  - refresh to remove fuzz
  - add more Lintian found spelling errors
  - new patch to add shbang to two scripts in lazarus-src
* Drop lcl-# from Provides list of lcl-units-#
* Make lazarus-ide-qt4-# an arch all until it really contains stuff
* Make all metapackages arch all as the usecase for arch any doesn't
  seem to warrant the addition archive hit
* Fix permissions of non-scripts in lazarus-src-#

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
unit TestNavigation;
 
2
 
 
3
(* TODO:
 
4
     Word Left/Right: Need tests with fold, trim, selection
 
5
*)
 
6
 
 
7
{$mode objfpc}{$H+}
 
8
 
 
9
interface
 
10
 
 
11
uses
 
12
  SysUtils, testregistry, LCLProc, Forms, TestBase,
 
13
  SynEdit, SynEditKeyCmds;
 
14
 
 
15
type
 
16
 
 
17
  { TTestSynNavigation }
 
18
 
 
19
  TTestSynNavigation = class(TTestBase)
 
20
  published
 
21
    procedure TestCaretHomeEnd;
 
22
    procedure TestCaretLeftRight;
 
23
    procedure TestCaretMoveLeftRightWord;
 
24
    //procedure TestCaretMoveLeftRightPartWord;
 
25
  end;
 
26
 
 
27
implementation
 
28
 
 
29
{ TTestSynNavigation }
 
30
 
 
31
procedure TTestSynNavigation.TestCaretHomeEnd;
 
32
  procedure DoInit1;
 
33
  begin
 
34
    ReCreateEdit;
 
35
    SynEdit.TabWidth := 6;
 
36
    SyneDit.Options := [];
 
37
    SyneDit.Options2 := [];
 
38
    SetLines(['',           //1
 
39
              '',
 
40
 
 
41
              'test',       // 3
 
42
              '',
 
43
              '',
 
44
              '                                                      ',
 
45
              'test',       // 3
 
46
              #9#9#9#9#9,
 
47
 
 
48
              '   spaced',  // 9
 
49
              '',
 
50
              '',
 
51
              '                                                      ',
 
52
              '   spaced',
 
53
              #9#9#9#9#9,
 
54
 
 
55
              #9'tabbed',    // 15
 
56
              '',
 
57
              '',
 
58
              '                                                      ',
 
59
              #9'tabbed',
 
60
              #9#9#9#9#9,
 
61
 
 
62
              #9'   tabbed spaced', // 21
 
63
              '',
 
64
              '',
 
65
              '                                                      ',
 
66
              #9'   tabbed spaced',
 
67
              #9#9#9#9#9,
 
68
 
 
69
              '   ', // 27  (space only)
 
70
              '',
 
71
              '',
 
72
              '                                                      ',
 
73
              #9'   ',
 
74
              #9#9#9#9#9,
 
75
 
 
76
              '        spaced 9 for tab',  // 33
 
77
              #9#9#9#9#9,
 
78
 
 
79
              ' X   ', // 35
 
80
              ' X'#9, // 36
 
81
 
 
82
              ''
 
83
              ]);
 
84
 
 
85
  end;
 
86
 
 
87
  procedure TestHome(Name:String; X, Y, ExpX1, ExpX2, ExpX3: Integer; ExpLTxTStartX: Integer = -1);
 
88
  begin
 
89
    SetCaretPhys(X, Y);
 
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
 
97
      SetCaretPhys(X, Y);
 
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);
 
104
    end;
 
105
  end;
 
106
 
 
107
  procedure TestEnd(Name:String; X, Y, ExpX1, ExpX2, ExpX3: Integer);
 
108
  begin
 
109
    SetCaretPhys(X, Y);
 
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);
 
116
  end;
 
117
 
 
118
begin
 
119
  // None Smart-Home:
 
120
  //   Caret goes x=1, then x=indend
 
121
  // Smart-Home:
 
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
 
124
  // Both
 
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
 
127
 
 
128
  {%region}
 
129
  DoInit1;
 
130
  PushBaseName('no smart / no past-eol');
 
131
 
 
132
  TestHome('empty 1st line',                      1, 1,  1,1,1,   1);
 
133
  TestHome('empty 2nd line',                      1, 2,  1,1,1,   1);
 
134
 
 
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);
 
141
 
 
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];
 
157
 
 
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);
 
166
  {%endregion}
 
167
 
 
168
  {%region}
 
169
  DoInit1;
 
170
  SyneDit.Options := [eoScrollPastEol];
 
171
  PopPushBaseName('no smart / past-eol');
 
172
 
 
173
  TestHome('empty 1st line',                      1, 1,  1,1,1,   1);
 
174
  TestHome('empty 2nd line',                      1, 2,  1,1,1,   1);
 
175
 
 
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);
 
182
 
 
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];
 
199
 
 
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);
 
209
  {%endregion}
 
210
 
 
211
 
 
212
  {%region}
 
213
  DoInit1;
 
214
  SyneDit.Options := [eoEnhanceHomeKey];
 
215
 
 
216
  PopPushBaseName('smart home / no past-eol');
 
217
 
 
218
  TestHome('empty 1st line',                      1, 1,  1,1,1,   1);
 
219
  TestHome('empty 2nd line',                      1, 2,  1,1,1,   1);
 
220
 
 
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);
 
227
 
 
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];
 
243
 
 
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);
 
253
  {%endregion}
 
254
 
 
255
 
 
256
  {%region}
 
257
  DoInit1;
 
258
  SyneDit.Options := [eoEnhanceHomeKey, eoScrollPastEol];
 
259
 
 
260
  PopPushBaseName('smart home / past-eol');
 
261
 
 
262
  TestHome('empty 1st line',                      1, 1,  1,1,1,   1);
 
263
  TestHome('empty 2nd line',                      1, 2,  1,1,1,   1);
 
264
 
 
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);
 
271
 
 
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];
 
285
 
 
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);
 
296
  {%endregion}
 
297
 
 
298
  PopPushBaseName('NO smart end/ NO past-eol');
 
299
  DoInit1;
 
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);
 
303
 
 
304
  PopPushBaseName('smart end/ NO past-eol');
 
305
  DoInit1;
 
306
  SyneDit.Options2 := [eoEnhanceEndKey];
 
307
  TestEnd ('end',       1,35,  3,6,3);
 
308
  TestEnd ('end tab',   1,36,  3,7,3);
 
309
 
 
310
  //SyneDit.Options := [eoScrollPastEol, eoEnhanceHomeKey];
 
311
  //SyneDit.Options2 := [eoEnhanceEndKey];
 
312
 
 
313
end;
 
314
 
 
315
procedure TTestSynNavigation.TestCaretLeftRight;
 
316
 
 
317
  procedure SetTextLeftRight;
 
318
  begin
 
319
    ReCreateEdit;
 
320
    SetLines([ 'ああああああああああああああああああああああ',   //  1: Double width at odd pos (start at 1, then every 2)
 
321
               ' ああああああああああああああああああああああ',  //  2: Double width at even pos
 
322
               '',                                               //  3: empty
 
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)
 
330
               ''
 
331
           ]);
 
332
  end;
 
333
 
 
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);
 
338
  var
 
339
    Name2: String;
 
340
    TestLogFirst: Boolean;
 
341
 
 
342
    procedure DoCmd;
 
343
    begin
 
344
      if ASelectXEnd < 0
 
345
      then SetCaretPhys(AStartPhysX, ALine)
 
346
      else SetCaretAndSelPhys(ASelectXEnd, ALine, AStartPhysX, ALine);
 
347
      SynEdit.ExecuteCommand(ACommand, '', nil);
 
348
    end;
 
349
    procedure TestCmd;
 
350
    begin
 
351
      DoCmd;
 
352
      if not TestLogFirst then
 
353
        TestIsCaretPhys(Name2+'[1]', ExpPhysX, ExpCaretY);
 
354
      TestIsCaret(Name2+'[1]', ExpLogX, ExpCaretY);
 
355
      TestIsCaretPhys(Name2+'[1]', ExpPhysX, ExpCaretY);
 
356
    end;
 
357
 
 
358
    procedure DoCmdRepeat;
 
359
    begin
 
360
      if ExpRepeatPhysX < 0 then exit;
 
361
      SynEdit.ExecuteCommand(ACommand, '', nil);
 
362
    end;
 
363
    procedure TestCmdRepeat;
 
364
    begin
 
365
      if ExpRepeatPhysX < 0 then exit;
 
366
      DoCmdRepeat;
 
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);
 
372
    end;
 
373
 
 
374
    procedure DoCmdReverse(AfterRepeat: Boolean = false);
 
375
    begin
 
376
      if not DoReverse then exit;
 
377
      if AfterRepeat and (ExpRepeatPhysX < 0) then exit; // was never repeated
 
378
 
 
379
      if ACommand = ecLeft
 
380
      then SynEdit.ExecuteCommand(ecRight, '', nil)
 
381
      else SynEdit.ExecuteCommand(ecLeft, '', nil);
 
382
    end;
 
383
    procedure TestCmdReverse(AfterRepeat: Boolean = false);
 
384
    begin
 
385
      if not DoReverse then exit;
 
386
      if AfterRepeat and (ExpRepeatPhysX < 0) then exit; // was never repeated
 
387
 
 
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);
 
394
      end else begin
 
395
        TestIsCaretPhys(Name2+'[R,'+dbgs(AfterRepeat)+']', AStartPhysX, ALine);
 
396
      end;
 
397
    end;
 
398
 
 
399
    procedure DoKeepXOnEmpty;
 
400
    begin
 
401
      if (ExpPhysX > 1) and not(eoScrollPastEol in SynEdit.Options) then begin
 
402
        SynEdit.CaretObj.LinePos := 3; // empty line
 
403
        SynEdit.CaretObj.LinePos := ExpCaretY;
 
404
      end;
 
405
    end;
 
406
    procedure TestKeepXOnEmpty(TestBetween: Boolean = False);
 
407
    begin
 
408
      if (ExpPhysX > 1) and not(eoScrollPastEol in SynEdit.Options) then begin
 
409
        SynEdit.CaretObj.LinePos := 3; // empty line
 
410
        if TestBetween then
 
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);
 
416
      end;
 
417
    end;
 
418
 
 
419
    procedure DoKeepXOnDWidth;
 
420
    begin
 
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;
 
426
      end;
 
427
    end;
 
428
    procedure TestKeepXOnDWidth(TestBetween: Boolean = False);
 
429
    begin
 
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
 
434
        if TestBetween then
 
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));
 
439
      end;
 
440
    end;
 
441
 
 
442
  var
 
443
    s: string;
 
444
  begin
 
445
    if ExpCaretY < 0 then ExpCaretY := ALine;
 
446
 
 
447
    EditorCommandToIdent(ACommand, s{%H-});
 
448
    AName := Format('%s (%s Y=%d, X=%d) ', [AName, s, ALine, AStartPhysX]);
 
449
 
 
450
    {%region NO eoKeepCaretX}
 
451
      SynEdit.Options := SynEdit.Options - [eoKeepCaretX];
 
452
      Name2 := AName + 'NO eoKeepCaretX: ';
 
453
 
 
454
      TestLogFirst := False;
 
455
 
 
456
      TestCmd;
 
457
      TestCmdReverse;
 
458
 
 
459
      TestCmd;
 
460
      TestCmdRepeat;
 
461
      TestCmdReverse(True);
 
462
      TestCmdReverse;
 
463
 
 
464
      DoCmd;
 
465
      TestCmdReverse;
 
466
 
 
467
      DoCmd;
 
468
      DoCmdRepeat;
 
469
      TestCmdReverse(True);
 
470
      TestCmdReverse;
 
471
 
 
472
      TestLogFirst := True;
 
473
 
 
474
      TestCmd;
 
475
      TestCmdReverse;
 
476
 
 
477
      TestCmd;
 
478
      TestCmdRepeat;
 
479
      TestCmdReverse(True);
 
480
      TestCmdReverse;
 
481
 
 
482
      TestCmd;
 
483
      TestKeepXOnEmpty(False);
 
484
 
 
485
      TestCmd;
 
486
      TestKeepXOnEmpty(True);
 
487
 
 
488
      TestCmd;
 
489
      TestKeepXOnDWidth(False);
 
490
 
 
491
      TestCmd;
 
492
      TestKeepXOnDWidth(True);
 
493
 
 
494
    {%endregion NO eoKeepCaretX}
 
495
 
 
496
 
 
497
    {%region WITH eoKeepCaretX}
 
498
      SynEdit.Options := SynEdit.Options + [eoKeepCaretX];
 
499
      Name2 := Name2 + 'WITH eoKeepCaretX: ';
 
500
 
 
501
      TestLogFirst := False;
 
502
 
 
503
      TestCmd;
 
504
      TestCmdReverse;
 
505
 
 
506
      TestCmd;
 
507
      TestCmdRepeat;
 
508
      TestCmdReverse(True);
 
509
      TestCmdReverse;
 
510
 
 
511
      DoCmd;
 
512
      TestCmdReverse;
 
513
 
 
514
      DoCmd;
 
515
      DoCmdRepeat;
 
516
      TestCmdReverse(True);
 
517
      TestCmdReverse;
 
518
 
 
519
      TestLogFirst := True;
 
520
 
 
521
      TestCmd;
 
522
      TestCmdReverse;
 
523
 
 
524
      TestCmd;
 
525
      TestCmdRepeat;
 
526
      TestCmdReverse(True);
 
527
      TestCmdReverse;
 
528
 
 
529
      TestCmd;
 
530
      TestKeepXOnEmpty(False);
 
531
      if ASelectXEnd < 0 then
 
532
        TestCmdReverse;
 
533
 
 
534
      TestCmd;
 
535
      TestKeepXOnEmpty(True);
 
536
      if ASelectXEnd < 0 then
 
537
        TestCmdReverse;
 
538
 
 
539
      TestCmd;
 
540
      TestKeepXOnEmpty(False);
 
541
      TestCmdRepeat;
 
542
 
 
543
      TestCmd;
 
544
      TestKeepXOnDWidth(False);
 
545
      if ASelectXEnd < 0 then
 
546
        TestCmdReverse;
 
547
 
 
548
      TestCmd;
 
549
      TestKeepXOnDWidth(True);
 
550
      if ASelectXEnd < 0 then
 
551
        TestCmdReverse;
 
552
 
 
553
      TestCmd;
 
554
      TestKeepXOnDWidth(False);
 
555
      TestCmdRepeat;
 
556
 
 
557
    {%endregion WITH eoKeepCaretX}
 
558
 
 
559
  end;
 
560
 
 
561
begin
 
562
  // TODO:
 
563
  //  EOL/BOL at first/last (visible) line (with folding)
 
564
  //  Multybyte char at EOL
 
565
  SetTextLeftRight;
 
566
 
 
567
  {%region ecRight}
 
568
  PushBaseName('No opts');
 
569
 
 
570
  SynEdit.TabWidth := 6;
 
571
  SynEdit.MaxLeftChar := 200;
 
572
  SynEdit.Options := [];
 
573
  SynEdit.Options2 := [];
 
574
 
 
575
  TestLeftRight('Simple right',        5,  2, ecRight,  3, 3,    4, 4);
 
576
 
 
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);
 
581
 
 
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);
 
585
 
 
586
  TestLeftRight('at EOL right',        5, 10, ecRight,  1, 1,    2, 2, True, True, -1 , 6);
 
587
 
 
588
  PopPushBaseName('eoScrollPastEol');
 
589
  SynEdit.Options := [eoScrollPastEol];
 
590
 
 
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);
 
593
 
 
594
 
 
595
  PopPushBaseName('eoCaretSkipTab');
 
596
  SynEdit.Options := [];
 
597
  SynEdit.Options2 := [eoCaretSkipTab];
 
598
 
 
599
  TestLeftRight('Simple right',        5,  2, ecRight,  3, 3,    4, 4);
 
600
 
 
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);
 
604
 
 
605
 
 
606
  PopPushBaseName('eoCaretSkipsSelection');
 
607
  SynEdit.Options2 := [eoCaretSkipsSelection];
 
608
 
 
609
  TestLeftRight('Selected right',      5,  2, ecRight,  8, 6,   -1, -1,   True, False, 8);
 
610
 
 
611
  {%region ecRight}
 
612
 
 
613
  {%region ecLeft}
 
614
  SynEdit.Options := [];
 
615
  SynEdit.Options2 := [];
 
616
 
 
617
  TestLeftRight('Simple left',        5,  3, ecLeft,  2, 2,    1, 1);
 
618
 
 
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);
 
623
 
 
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);
 
627
 
 
628
  TestLeftRight('at BOL left',       6,  1, ecLeft, 10, 8,    9, 7, True, True, -1 , 5);
 
629
 
 
630
  PopPushBaseName('eoScrollPastEol');
 
631
  SynEdit.Options := [eoScrollPastEol];
 
632
 
 
633
  TestLeftRight('at BOL left',        6,  1, ecLeft,  1, 1,   1, 1,   False, False);
 
634
 
 
635
 
 
636
  PopPushBaseName('eoCaretSkipTab');
 
637
  SynEdit.Options := [];
 
638
  SynEdit.Options2 := [eoCaretSkipTab];
 
639
 
 
640
  TestLeftRight('Simple left',        5,  3, ecLeft,  2, 2,    1, 1);
 
641
 
 
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);
 
644
 
 
645
 
 
646
  PopPushBaseName('eoCaretSkipsSelection');
 
647
  SynEdit.Options2 := [eoCaretSkipsSelection];
 
648
 
 
649
  TestLeftRight('Selected left',      5,  8, ecLeft,  3, 3,   -1, -1,   True, False, 3);
 
650
 
 
651
  {%endregion ecLeft}
 
652
 
 
653
 
 
654
  PopBaseName;
 
655
end;
 
656
 
 
657
procedure TTestSynNavigation.TestCaretMoveLeftRightWord;
 
658
 
 
659
  procedure DoInit;
 
660
  begin
 
661
    ReCreateEdit;
 
662
 
 
663
    SynEdit.TabWidth := 7;
 
664
            // 1    6    11 14
 
665
    SetLines(['Some text to test',                 //1
 
666
            // 1   5   9
 
667
              'Foo bar abc',                       // 2
 
668
            //   8     14   19   24
 
669
              #9'Other line with tab',             // 3
 
670
            // 1      8  11  15
 
671
              'tab'#9'in the middle',              // 4
 
672
            // 1       9  12  16     23   28
 
673
              'tab'#9' in the middle with space',  // 5
 
674
            // 1       9   13 16
 
675
              'umlaute äää in text',               // 6
 
676
              'normal line',
 
677
            //    4         14     21     28  32
 
678
              '   untrimmed spaces around line   ', // 8
 
679
              'normal line',
 
680
            //   8      15      22  26
 
681
              #9'tab'#9'only'#9'line'#9,            // 10
 
682
            // 1      8
 
683
              'normal line',
 
684
              '',                                    // 12 (empty)
 
685
              'normal line',
 
686
              '     ', // space only empty line      // 14
 
687
              'normal line',
 
688
              '',
 
689
              'A B',                 // 17
 
690
              'normal line',         // 18
 
691
              ''
 
692
             ]);
 
693
  end;
 
694
 
 
695
  procedure TestWordLeft(Name:String; X, Y, ExpX1, ExpY1: Integer;
 
696
                         ExpX2: Integer = -1; ExpY2: Integer = -1);
 
697
  begin
 
698
    SetCaretPhys(X,Y);
 
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);
 
704
    end;
 
705
  end;
 
706
 
 
707
  procedure TestWordRight(Name:String; X, Y, ExpX1, ExpY1: Integer;
 
708
                         ExpX2: Integer = -1; ExpY2: Integer = -1);
 
709
  begin
 
710
    SetCaretPhys(X,Y);
 
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);
 
716
    end;
 
717
  end;
 
718
 
 
719
begin
 
720
  DoInit;
 
721
  {%region word left}
 
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);
 
728
 
 
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);
 
733
 
 
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);
 
736
 
 
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);
 
741
 
 
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);
 
747
 
 
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);
 
752
 
 
753
  TestWordLeft('After empty > prev',                1,13,    1,12);
 
754
  TestWordLeft('After space empty > prev',          1,15,    6,14);
 
755
 
 
756
  TestWordLeft('single char at eol "A B|"',         4,17,    3,17,   1,17);
 
757
  {%endregion}
 
758
 
 
759
  {%region word right}
 
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);
 
765
 
 
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);
 
770
 
 
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);
 
774
 
 
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);
 
779
 
 
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);
 
785
 
 
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);
 
790
 
 
791
  TestWordRight('Before empty > next',                12,11,    1,12);
 
792
  TestWordRight('Before space empty > next',          12,13,    1,14,   6, 14);
 
793
  {%endregion}
 
794
end;
 
795
 
 
796
initialization
 
797
 
 
798
  RegisterTest(TTestSynNavigation);
 
799
end.
 
800