Subversion Repositories Kolibri OS

Rev

Rev 9599 | Rev 9668 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8728 leency 1
(*
9560 akron1 2
    Copyright 2021, 2022 Anton Krotov
8728 leency 3
 
4
    This file is part of CEdit.
5
 
6
    CEdit is free software: you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License as published by
8
    the Free Software Foundation, either version 3 of the License, or
9
    (at your option) any later version.
10
 
11
    CEdit is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with CEdit. If not, see .
18
*)
19
 
20
MODULE Text;
21
 
22
IMPORT
23
    List, Lines,
24
    G := Graph,
25
    U := Utils,
26
    RW, Search,
27
    E := Encodings,
28
    CB := Clipboard,
9073 leency 29
    ChangeLog, File,
8728 leency 30
    Lang := Languages;
31
 
32
 
33
CONST
34
 
9174 akron1 35
    SPACE = Lines.SPACE;
36
    TAB = Lines.TAB;
37
    TAB1 = Lines.TAB1;
8728 leency 38
    lenEOL = CB.lenEOL;
39
 
40
    mark_width = 2;
41
    pad_left = mark_width + 3;
9060 leency 42
    pad_top = 0;
8728 leency 43
    inter = 2;
44
 
45
 
46
TYPE
47
 
9210 akron1 48
    tPoint* = RECORD
49
        X*, Y*: INTEGER
8728 leency 50
    END;
51
 
52
    pPoint = POINTER TO tPoint;
53
 
54
    tString* = ARRAY 1000 OF WCHAR;
55
 
56
    tLine = Lines.tLine;
57
 
58
    tGuard = POINTER TO RECORD (ChangeLog.tGuard)
59
        selected: BOOLEAN;
60
        cursor, select2, scroll: tPoint;
61
        CurX: INTEGER
62
    END;
63
 
64
    tText* = POINTER TO RECORD (List.tList)
65
        cursor, select, select2: pPoint;
66
        scroll: tPoint;
67
        CurX: INTEGER;
68
        modified*: BOOLEAN;
69
        edition*: tGuard;
70
        comments, numbers*, guard,
71
        search, cs, whole: BOOLEAN;
72
        curLine: tLine;
73
        lang*: INTEGER;
9336 akron1 74
        enc, eol: INTEGER;
8728 leency 75
        table: Search.IdxTable;
76
        foundList: List.tList;
77
        foundSel: INTEGER;
9050 leency 78
        searchText: tString;
79
        chLog*: ChangeLog.tLog;
9210 akron1 80
        maxLength*: INTEGER;
81
        fileName*: RW.tFileName
8728 leency 82
    END;
83
 
84
    tProcedure = PROCEDURE;
85
 
86
 
87
VAR
88
 
89
    pdelete: PROCEDURE (text: tText);
90
    ShowCursor: PROCEDURE;
91
 
92
    colors*: RECORD
8762 leency 93
                text, back, seltext, selback, modified, saved, curline, numtext, numback: INTEGER;
9413 akron1 94
                comment, string, escape, num, delim, key1, key2, key3: INTEGER
8728 leency 95
             END;
96
    canvas: G.tCanvas;
9174 akron1 97
    drawCursor: BOOLEAN;
8728 leency 98
    padding: RECORD left, top: INTEGER END;
99
    size, textsize: tPoint;
100
    charWidth, charHeight: INTEGER;
101
 
102
 
9210 akron1 103
PROCEDURE setLang* (text: tText; lang: INTEGER);
104
BEGIN
105
    text.lang := lang;
106
    text.comments := TRUE;
107
    Lang.setCurLang(text.lang)
108
END setLang;
109
 
110
 
8728 leency 111
PROCEDURE setName* (text: tText; name: RW.tFileName);
112
VAR
113
    ext: RW.tFileName;
114
BEGIN
115
    text.fileName := name;
9210 akron1 116
    U.getFileName(name, ext, ".");
8728 leency 117
    U.upcase(ext);
9210 akron1 118
    setLang(text, Lang.getLang(ext))
8728 leency 119
END setName;
120
 
121
 
122
PROCEDURE getPos* (text: tText; VAR x, y: INTEGER);
123
BEGIN
124
    x := text.cursor.X + 1;
125
    y := text.cursor.Y + 1
126
END getPos;
127
 
128
 
129
PROCEDURE getScroll* (text: tText; VAR x, y: INTEGER);
130
BEGIN
131
    x := text.scroll.X;
132
    y := text.scroll.Y
133
END getScroll;
134
 
135
 
136
PROCEDURE getTextSize* (VAR x, y: INTEGER);
137
BEGIN
138
    x := textsize.X;
139
    y := textsize.Y
140
END getTextSize;
141
 
142
 
143
PROCEDURE getTextRect* (VAR left, top, rigth, bottom: INTEGER);
144
BEGIN
145
    left := padding.left - 1;
146
    top := padding.top - 1;
147
    rigth := size.X - 1;
148
    bottom := top + size.Y - 1;
149
END getTextRect;
150
 
151
 
152
PROCEDURE toggleNumbers* (text: tText);
153
BEGIN
154
    text.numbers := ~text.numbers
155
END toggleNumbers;
156
 
157
 
158
PROCEDURE toggleCursor*;
159
BEGIN
160
    drawCursor := ~drawCursor
161
END toggleCursor;
162
 
163
 
9174 akron1 164
PROCEDURE showCursor*;
165
BEGIN
166
	drawCursor := TRUE
167
END showCursor;
168
 
169
 
170
PROCEDURE hideCursor*;
171
BEGIN
172
	drawCursor := FALSE
173
END hideCursor;
174
 
175
 
8728 leency 176
PROCEDURE getString (src: tLine; pos, cnt: INTEGER; VAR dst: ARRAY OF WCHAR): INTEGER;
177
VAR
178
    i: INTEGER;
179
BEGIN
180
    i := 0;
181
    WHILE (pos < src.length) & (cnt > 0) DO
182
        IF i < LEN(dst) - 1 THEN
9659 akron1 183
            dst[i] := Lines.getChar(src, pos);
8728 leency 184
            INC(i)
185
        END;
186
        INC(pos);
187
        DEC(cnt)
188
    END;
189
    dst[i] := 0X
190
    RETURN i
191
END getString;
192
 
193
 
194
PROCEDURE NextLine (VAR line: tLine);
195
BEGIN
196
    line := line.next(tLine)
197
END NextLine;
198
 
199
 
200
PROCEDURE PrevLine (VAR line: tLine);
201
BEGIN
202
    line := line.prev(tLine)
203
END PrevLine;
204
 
205
 
206
PROCEDURE SetColor (textColor, backColor: INTEGER);
207
BEGIN
208
    G.SetTextColor(canvas, textColor);
209
    G.SetBkColor(canvas, backColor)
210
END SetColor;
211
 
212
 
213
PROCEDURE ProcessComments (line: tLine; VAR depth, pos: INTEGER; minDepth, n: INTEGER; lang: INTEGER);
214
VAR
215
    cond: INTEGER;
216
BEGIN
217
    cond := 0;
218
    WHILE (pos <= n) & (depth > minDepth) DO
219
        Lang.comments(line, depth, cond, pos, n, lang);
220
        INC(pos)
221
    END;
222
    DEC(pos)
223
END ProcessComments;
224
 
225
 
226
PROCEDURE Comments (text: tText);
227
VAR
228
    line: tLine;
229
    i: INTEGER;
230
BEGIN
231
    line := text.first(tLine);
232
    line.cin := 0;
233
    line.cout := 0;
234
    i := 0;
235
    ProcessComments(line, line.cout, i, -1, line.length - 1, text.lang);
236
    NextLine(line);
237
    WHILE line # NIL DO
238
        line.cin := line.prev(tLine).cout;
239
        line.cout := line.cin;
240
        i := 0;
241
        ProcessComments(line, line.cout, i, -1, line.length - 1, text.lang);
242
        NextLine(line)
243
    END;
244
    text.comments := FALSE
245
END Comments;
246
 
247
 
248
PROCEDURE parse (text: tText; line: tLine; y: INTEGER; backColor: INTEGER; lang: INTEGER);
249
VAR
250
    c: WCHAR;
251
    i, n, k: INTEGER;
252
    cond, depth: INTEGER;
253
    color: INTEGER;
254
    hex: BOOLEAN;
255
    isDgt: PROCEDURE (c: WCHAR): BOOLEAN;
256
 
257
 
258
    PROCEDURE PrintLex (text: tText; line: tLine; lexStart, lexEnd: INTEGER; y: INTEGER; color, backColor: INTEGER);
259
    VAR
260
        lexLen: INTEGER;
261
    BEGIN
262
        SetColor(color, backColor);
263
        lexLen := MAX(MIN(line.length - lexStart, lexEnd - lexStart + 1), 0);
9193 akron1 264
        G.TextOut(canvas, padding.left + (lexStart - text.scroll.X) * charWidth, y, Lines.getPChar(line, lexStart), lexLen, color)
8728 leency 265
    END PrintLex;
266
 
267
 
9193 akron1 268
    PROCEDURE PrintComment (text: tText; line: tLine; VAR depth, i: INTEGER; w, y: INTEGER; backColor: INTEGER);
8728 leency 269
    VAR
270
        lexStart: INTEGER;
271
        color: INTEGER;
272
    BEGIN
273
        IF (text.lang = Lang.langLua) & ~ODD(depth) THEN
274
            color := colors.string
275
        ELSIF (text.lang = Lang.langIni) & (depth = 1) THEN
276
            color := colors.key2
277
        ELSIF (text.lang = Lang.langPascal) & (depth = 3) THEN
278
            color := colors.key3
279
        ELSE
280
            color := colors.comment
281
        END;
9193 akron1 282
        lexStart := MAX(i - w, 0);
8728 leency 283
        ProcessComments(line, depth, i, 0, line.length - 1, text.lang);
284
        PrintLex(text, line, lexStart, i, y, color, backColor)
285
    END PrintComment;
286
 
287
 
288
    PROCEDURE cap (c: WCHAR): WCHAR;
289
    BEGIN
290
        IF U.cap(c) THEN END
291
        RETURN c
292
    END cap;
293
 
294
 
295
    PROCEDURE UL (c: WCHAR): BOOLEAN;
296
        RETURN (cap(c) = "U") OR (cap(c) = "L")
297
    END UL;
298
 
299
 
300
    PROCEDURE FL (c: WCHAR): BOOLEAN;
301
        RETURN (cap(c) = "F") OR (cap(c) = "L")
302
    END FL;
303
 
304
 
305
    PROCEDURE ident (text: tText; VAR i: INTEGER; first, y: INTEGER; line: tLine; backColor: INTEGER; cs: BOOLEAN);
306
    VAR
307
        c: WCHAR;
308
        lexLen: INTEGER;
309
        s: ARRAY 32 OF WCHAR;
310
        color: INTEGER;
311
    BEGIN
9659 akron1 312
        c := Lines.getChar(line, i);
8728 leency 313
        WHILE U.isLetter(c) OR (c = "_") OR U.isDigit(c) DO
314
            INC(i);
9659 akron1 315
            c := Lines.getChar(line, i);
8728 leency 316
        END;
317
        DEC(i);
318
        lexLen := getString(line, first, i - first + 1, s);
319
        IF ~cs THEN
320
            U.upcase16(s)
321
        END;
322
        IF Lang.isKey(s, text.lang, 1) THEN
323
            color := colors.key1
324
        ELSIF Lang.isKey(s, text.lang, 2) THEN
325
            color := colors.key2
326
        ELSIF Lang.isKey(s, text.lang, 3) THEN
327
            color := colors.key3
328
        ELSE
329
            color := colors.text
330
        END;
331
        IF color # colors.text THEN
332
            PrintLex(text, line, first, i, y, color, backColor)
333
        END
334
    END ident;
335
 
336
 
337
    PROCEDURE String (text: tText; line: tLine; VAR i: INTEGER; y: INTEGER; backColor: INTEGER);
338
    VAR
9413 akron1 339
        k, j, Start, End: INTEGER;
340
        c: WCHAR;
8728 leency 341
    BEGIN
342
        k := i;
9413 akron1 343
        Lang.SkipString(line, i, line.length - 1, text.lang);
344
        PrintLex(text, line, k, i, y, colors.string, backColor);
345
        IF text.lang IN Lang.escLang THEN
346
	        Start := k + 1;
347
	        End := i - 1;
348
	        k := Start;
349
	        WHILE k <= End DO
9659 akron1 350
	        	c := Lines.getChar(line, k);
9413 akron1 351
	        	IF c = "\" THEN
352
	        		j := k;
353
	        		Lang.SkipEsc(line, k, line.length - 1, text.lang);
354
	        		PrintLex(text, line, j, k, y, colors.escape, backColor)
355
	        	END;
356
	        	INC(k)
357
	        END
358
        END
8728 leency 359
    END String;
360
 
361
 
362
BEGIN
363
    depth := line.cin;
364
    n := line.length - 1;
365
    i := 0;
366
    IF (depth > 0) & (n >= 0) THEN
9193 akron1 367
        PrintComment(text, line, depth, i, 2, y, backColor)
8728 leency 368
    END;
369
    cond := 0;
370
    WHILE i <= n DO
9659 akron1 371
        c := Lines.getChar(line, i);
8728 leency 372
 
373
        IF lang = Lang.langFasm THEN
374
 
375
            IF c = ";" THEN
376
                PrintLex(text, line, i, n, y, colors.comment, backColor);
377
                i := n
378
            ELSIF (c = "'") OR (c = '"') THEN
379
                String(text, line, i, y, backColor)
380
            ELSIF (U.isLetter(c) OR (c = "_")) THEN
9050 leency 381
                ident(text, i, i, y, line, backColor, Lang.isCS(lang))
8728 leency 382
            ELSIF U.isDigit(c) THEN
383
                hex := FALSE;
384
                k := i;
385
                INC(i);
9659 akron1 386
                c := Lines.getChar(line, i);
387
                IF (cap(c) = "X") & (Lines.getChar(line, i - 1) = "0") THEN
8728 leency 388
                    INC(i);
389
                    hex := TRUE
390
                END;
391
 
9659 akron1 392
                WHILE U.isHex(cap(Lines.getChar(line, i))) DO
8728 leency 393
                    INC(i)
394
                END;
395
 
9659 akron1 396
                IF (cap(Lines.getChar(line, i)) = "H") & ~hex THEN
8728 leency 397
                    INC(i)
398
                END;
399
 
400
                DEC(i);
401
                PrintLex(text, line, k, i, y, colors.num, backColor)
402
            END
403
 
9174 akron1 404
        ELSIF (lang = Lang.langC) OR (lang = Lang.langJSON) THEN
8728 leency 405
 
9210 akron1 406
	        IF depth = 0 THEN
407
	            IF c = "/" THEN
408
	                IF cond = 0 THEN
409
	                    cond := 1
410
	                ELSE
411
	                    PrintLex(text, line, i - 1, n, y, colors.comment, backColor);
412
	                    cond := 0;
413
	                    i := n
414
	                END
415
	            ELSIF (c = "*") & (cond = 1) THEN
416
	                depth := 1;
417
	                INC(i);
418
	                PrintComment(text, line, depth, i, 2, y, backColor);
419
	                cond := 0
420
	            ELSIF U.isLetter(c) OR (c = "_") OR (c = "'") OR (c = '"') THEN
421
	            	k := i;
422
	            	IF (c = "'") OR (c = '"') THEN
423
	            		String(text, line, i, y, backColor);
424
	            	ELSE
9659 akron1 425
	            		ident(text, i, i - ORD((lang = Lang.langC) & (i > 0) & (Lines.getChar(line, i - 1) = "#")), y, line, backColor, Lang.isCS(lang))
9210 akron1 426
	            	END;
427
	                IF lang = Lang.langJSON THEN
9659 akron1 428
		                WHILE Lines.isSpace(Lines.getChar(line, i + 1)) DO
9210 akron1 429
		                	INC(i)
430
		                END;
9659 akron1 431
		                IF Lines.getChar(line, i + 1) = ":" THEN
9210 akron1 432
		                	PrintLex(text, line, k, i, y, colors.key1, backColor)
433
		                END
9174 akron1 434
	                END;
9210 akron1 435
	                cond := 0
436
	            ELSIF U.isDigit(c) THEN
437
	                k := i;
438
	                INC(i);
9659 akron1 439
	                c := Lines.getChar(line, i);
9210 akron1 440
	                IF c = "." THEN
441
	                    DEC(i);
9659 akron1 442
	                    c := Lines.getChar(line, i)
9210 akron1 443
	                END;
9659 akron1 444
	                IF (cap(c) = "X") & (Lines.getChar(line, i - 1) = "0") THEN
9210 akron1 445
	                    REPEAT
446
	                        INC(i);
9659 akron1 447
	                        c := Lines.getChar(line, i)
9210 akron1 448
	                    UNTIL ~U.isHex(cap(c));
449
	                    IF UL(c) THEN
450
	                        INC(i)
451
	                    END
452
	                ELSIF UL(c) THEN
453
	                    INC(i)
454
	                ELSIF U.isDigit(c) THEN
455
	                    REPEAT
456
	                        INC(i)
9659 akron1 457
	                    UNTIL ~U.isDigit(Lines.getChar(line, i));
458
	                    c := Lines.getChar(line, i);
9210 akron1 459
	                    IF UL(c) THEN
460
	                        INC(i)
461
	                    ELSIF c = "." THEN
462
	                        INC(i);
9659 akron1 463
	                        WHILE U.isDigit(Lines.getChar(line, i)) DO
9210 akron1 464
	                            INC(i)
465
	                        END;
9659 akron1 466
	                        c := Lines.getChar(line, i);
9210 akron1 467
	                        IF cap(c) = "E" THEN
468
	                            INC(i);
9659 akron1 469
	                            c := Lines.getChar(line, i);
9210 akron1 470
	                            IF (c = "+") OR (c = "-") THEN
471
	                                INC(i)
472
	                            END;
9659 akron1 473
	                            IF U.isDigit(Lines.getChar(line, i)) THEN
474
	                                WHILE U.isDigit(Lines.getChar(line, i)) DO
9210 akron1 475
	                                    INC(i)
476
	                                END;
9659 akron1 477
	                                c := Lines.getChar(line, i);
9210 akron1 478
	                                IF FL(c) THEN
479
	                                    INC(i)
480
	                                END
481
	                            END
482
	                        ELSIF FL(c) THEN
483
	                            INC(i)
484
	                        END
485
	                    END
486
	                END;
487
	                DEC(i);
488
	                PrintLex(text, line, k, i, y, colors.num, backColor);
489
	                cond := 0
490
	            ELSE
491
	                cond := 0
492
	            END
493
	        ELSIF depth = 1 THEN
494
	            IF c = "*" THEN
495
	                cond := 1
496
	            ELSIF (c = "/") & (cond = 1) THEN
497
	                cond := 0;
498
	                depth := 0
499
	            ELSE
500
	                cond := 0
501
	            END
502
	        END
8728 leency 503
 
504
        ELSIF lang = Lang.langOberon THEN
505
 
9210 akron1 506
	        IF (depth = 0) & (c = "/") THEN
507
	            IF cond = 3 THEN
508
	                PrintLex(text, line, i - 1, n, y, colors.comment, backColor);
509
	                cond := 0;
510
	                i := n
511
	            ELSE
512
	                cond := 3
513
	            END
514
	        ELSIF (depth = 0) & ((c = "'") OR (c = '"')) THEN
515
	            String(text, line, i, y, backColor);
516
	            cond := 0
517
	        ELSIF (depth = 0) & U.isDigit(c) THEN
518
	            color := colors.num;
519
	            k := i;
520
	            INC(i);
9659 akron1 521
	            WHILE U.isHex(Lines.getChar(line, i)) DO
9210 akron1 522
	                INC(i)
523
	            END;
524
	            IF i <= n THEN
9659 akron1 525
	                IF Lines.getChar(line, i) = "." THEN
9210 akron1 526
	                    INC(i);
9659 akron1 527
	                    IF Lines.getChar(line, i) = "." THEN
9210 akron1 528
	                        DEC(i)
529
	                    END;
9659 akron1 530
	                    WHILE U.isDigit(Lines.getChar(line, i)) DO
9210 akron1 531
	                        INC(i)
532
	                    END;
9659 akron1 533
	                    IF Lines.getChar(line, i) = "E" THEN
9210 akron1 534
	                        INC(i);
9659 akron1 535
	                        IF (Lines.getChar(line, i) = "+") OR (Lines.getChar(line, i) = "-") THEN
9210 akron1 536
	                            INC(i)
537
	                        END;
9659 akron1 538
	                        WHILE U.isDigit(Lines.getChar(line, i)) DO
9210 akron1 539
	                            INC(i)
540
	                        END
541
	                    END
9659 akron1 542
	                ELSIF Lines.getChar(line, i) = "H" THEN
9210 akron1 543
	                    INC(i)
9659 akron1 544
	                ELSIF Lines.getChar(line, i) = "X" THEN
9210 akron1 545
	                    color := colors.string;
546
	                    INC(i)
547
	                END
548
	            END;
549
	            DEC(i);
550
	            PrintLex(text, line, k, i, y, color, backColor);
551
	            cond := 0
552
	        ELSIF (depth = 0) & (U.isLetter(c) OR (c = "_")) THEN
553
	            ident(text, i, i, y, line, backColor, Lang.isCS(lang));
554
	            cond := 0
555
	        ELSIF c = "(" THEN
556
	            cond := 1
557
	        ELSIF c = "*" THEN
558
	            IF cond = 1 THEN
559
	                INC(depth);
560
	                INC(i);
561
	                PrintComment(text, line, depth, i, 2, y, backColor);
562
	                cond := 0
563
	            ELSE
564
	                cond := 2
565
	            END
566
	        ELSIF c = ")" THEN
567
	            IF cond = 2 THEN
568
	                IF depth > 0 THEN
569
	                    DEC(depth)
570
	                END
571
	            END;
572
	            cond := 0
573
	        ELSE
574
	            cond := 0
575
	        END
8728 leency 576
 
577
        ELSIF lang = Lang.langLua THEN
578
 
9210 akron1 579
	        IF depth = 0 THEN
580
	            IF c = "-" THEN
581
	                IF cond = 1 THEN
582
	                    IF Lang.LuaLong(line, i + 1) >= 0 THEN
583
	                        depth := Lang.LuaLong(line, i + 1)*2 + 1;
584
	                        INC(i);
585
	                        PrintComment(text, line, depth, i, 2, y, backColor)
586
	                    ELSE
587
	                        PrintLex(text, line, i - 1, n, y, colors.comment, backColor);
588
	                        i := n
589
	                    END;
590
	                    cond := 0
591
	                ELSE
592
	                    cond := 1
593
	                END
594
	            ELSIF c = "[" THEN
595
	                cond := 0;
596
	                k := Lang.LuaLong(line, i);
597
	                IF k >= 0 THEN
598
	                    depth := (k + 1)*2;
599
	                    INC(i, 2);
600
	                    PrintComment(text, line, depth, i, 2, y, backColor);
601
	                    cond := 0
602
	                END
603
	            ELSIF (c = "'") OR (c = '"') THEN
604
	                String(text, line, i, y, backColor);
605
	                cond := 0
606
	            ELSIF U.isDigit(c) THEN
607
	                k := i;
9659 akron1 608
	                IF (c = "0") & (cap(Lines.getChar(line, i + 1)) = "X") THEN
9210 akron1 609
	                    isDgt := U.isHex;
610
	                    hex := TRUE;
611
	                    INC(i, 2)
612
	                ELSE
613
	                    isDgt := U.isDigit;
614
	                    hex := FALSE
615
	                END;
9659 akron1 616
	                WHILE isDgt(cap(Lines.getChar(line, i))) DO
9210 akron1 617
	                    INC(i)
618
	                END;
9659 akron1 619
	                IF Lines.getChar(line, i) = "." THEN
9210 akron1 620
	                    INC(i);
9659 akron1 621
	                    IF Lines.getChar(line, i) = "." THEN
9210 akron1 622
	                        DEC(i)
623
	                    END;
9659 akron1 624
	                    WHILE isDgt(cap(Lines.getChar(line, i))) DO
9210 akron1 625
	                        INC(i)
626
	                    END
627
	                END;
9659 akron1 628
	                IF (cap(Lines.getChar(line, i)) = "E") OR hex & (cap(Lines.getChar(line, i)) = "P") THEN
9210 akron1 629
	                    INC(i);
9659 akron1 630
	                    IF (Lines.getChar(line, i) = "-") OR (Lines.getChar(line, i) = "+") THEN
9210 akron1 631
	                        INC(i)
632
	                    END;
9659 akron1 633
	                    WHILE isDgt(cap(Lines.getChar(line, i))) DO
9210 akron1 634
	                        INC(i)
635
	                    END
636
	                END;
637
	                DEC(i);
638
	                PrintLex(text, line, k, i, y, colors.num, backColor);
639
	                cond := 0
640
	            ELSIF U.isLetter(c) OR (c = "_") THEN
641
	                ident(text, i, i, y, line, backColor, Lang.isCS(lang));
642
	                cond := 0
643
	            ELSE
644
	                cond := 0
645
	            END
8728 leency 646
 
9210 akron1 647
	        ELSIF depth > 0 THEN
648
	            IF (cond = 0) & (c = "]") THEN
649
	                cond := 1
650
	            ELSIF (cond >= 1) & (c = "=") THEN
651
	                INC(cond)
652
	            ELSIF (cond >= 1) & (c = "]") & (cond * 2 - depth MOD 2 = depth) THEN
653
	                depth := 0;
654
	                cond := 0
655
	            ELSE
656
	                cond := 0
657
	            END
658
	        END
8728 leency 659
 
660
        ELSIF lang = Lang.langPascal THEN
661
 
9210 akron1 662
	        IF depth = 0 THEN
663
	            IF c = "(" THEN
664
	                cond := 1
665
	            ELSIF (c = "*") & (cond = 1) THEN
666
	                depth := 2;
667
	                INC(i);
668
	                PrintComment(text, line, depth, i, 2, y, backColor);
669
	                cond := 0
670
	            ELSIF c = "/" THEN
671
	                IF cond = 2 THEN
672
	                    PrintLex(text, line, i - 1, n, y, colors.comment, backColor);
673
	                    cond := 0;
674
	                    i := n
675
	                ELSE
676
	                    cond := 2
677
	                END
678
	            ELSIF c = "'" THEN
679
	                String(text, line, i, y, backColor);
680
	                cond := 0
681
	            ELSIF c = "{" THEN
9659 akron1 682
	                IF Lines.getChar(line, i + 1) = "$" THEN
9210 akron1 683
	                    depth := 3
684
	                ELSE
685
	                    depth := 1
686
	                END;
687
	                INC(i);
688
	                PrintComment(text, line, depth, i, 1, y, backColor);
689
	                cond := 0
690
	            ELSIF c = "#" THEN
691
	                k := i;
692
	                INC(i);
9659 akron1 693
	                WHILE U.isDigit(Lines.getChar(line, i)) DO
9210 akron1 694
	                    INC(i)
695
	                END;
696
	                DEC(i);
697
	                PrintLex(text, line, k, i, y, colors.string, backColor);
698
	                cond := 0
699
	            ELSIF c = "$" THEN
9659 akron1 700
	                IF (i > 0 ) & (Lines.getChar(line, i - 1) = "#") THEN
9210 akron1 701
	                    color := colors.string
702
	                ELSE
703
	                    color := colors.num
704
	                END;
705
	                k := i;
706
	                INC(i);
9659 akron1 707
	                WHILE U.isHex(cap(Lines.getChar(line, i))) DO
9210 akron1 708
	                    INC(i)
709
	                END;
710
	                DEC(i);
711
	                PrintLex(text, line, k, i, y, color, backColor);
712
	                cond := 0
713
	            ELSIF U.isDigit(c) THEN
714
	                k := i;
9659 akron1 715
	                WHILE U.isDigit(Lines.getChar(line, i)) DO
9210 akron1 716
	                    INC(i)
717
	                END;
9659 akron1 718
	                IF Lines.getChar(line, i) = "." THEN
9210 akron1 719
	                    INC(i);
9659 akron1 720
	                    IF Lines.getChar(line, i) = "." THEN
9210 akron1 721
	                        DEC(i)
722
	                    END;
9659 akron1 723
	                    WHILE U.isDigit(Lines.getChar(line, i)) DO
9210 akron1 724
	                        INC(i)
725
	                    END;
9659 akron1 726
	                    IF cap(Lines.getChar(line, i)) = "E" THEN
9210 akron1 727
	                        INC(i);
9659 akron1 728
	                        IF (Lines.getChar(line, i) = "-") OR (Lines.getChar(line, i) = "+") THEN
9210 akron1 729
	                            INC(i)
730
	                        END;
9659 akron1 731
	                        WHILE U.isDigit(Lines.getChar(line, i)) DO
9210 akron1 732
	                            INC(i)
733
	                        END
734
	                    END
735
	                END;
736
	                DEC(i);
737
	                PrintLex(text, line, k, i, y, colors.num, backColor);
738
	                cond := 0
739
	            ELSIF (U.isLetter(c) OR (c = "_")) THEN
740
	                ident(text, i, i, y, line, backColor, Lang.isCS(lang));
741
	                cond := 0
742
	            ELSE
743
	                cond := 0
744
	            END
745
	        ELSIF depth IN {1, 3} THEN
746
	            IF c = "}" THEN
747
	                depth := 0
748
	            END
749
	        ELSIF depth = 2 THEN
750
	            IF c = "*" THEN
751
	                cond := 1
752
	            ELSIF (c = ")") & (cond = 1) THEN
753
	                depth := 0;
754
	                cond := 0
755
	            ELSE
756
	                cond := 0
757
	            END
758
	        END
8728 leency 759
 
760
        ELSIF lang = Lang.langIni THEN
761
 
9210 akron1 762
	        IF depth = 0 THEN
763
	            IF (c = ";") OR (c = "#") THEN
764
	                PrintLex(text, line, i, n, y, colors.comment, backColor);
765
	                i := n
766
	            ELSIF c = '"' THEN
767
	                String(text, line, i, y, backColor)
768
	            ELSIF c = "[" THEN
769
	                depth := 1;
770
	                INC(i);
771
	                PrintComment(text, line, depth, i, 1, y, backColor)
772
	            ELSIF U.isDigit(c) THEN
773
	                k := i;
9659 akron1 774
	                WHILE U.isDigit(Lines.getChar(line, i)) DO
9210 akron1 775
	                    INC(i)
776
	                END;
777
	                DEC(i);
778
	                PrintLex(text, line, k, i, y, colors.num, backColor)
779
	            ELSIF (U.isLetter(c) OR (c = "_")) THEN
780
	                ident(text, i, i, y, line, backColor, Lang.isCS(lang))
781
	            END
782
	        ELSIF depth = 1 THEN
783
	            IF c = "]" THEN
784
	                depth := 0
785
	            END
786
	        END
8728 leency 787
 
788
        END;
789
        INC(i)
790
    END
791
END parse;
792
 
793
 
794
PROCEDURE leadingSpaces (line: tLine): INTEGER;
795
VAR
796
    i: INTEGER;
797
BEGIN
798
    i := 0;
9659 akron1 799
    WHILE Lines.isSpace(Lines.getChar(line, i)) DO
8728 leency 800
        INC(i)
801
    END
802
    RETURN i
803
END leadingSpaces;
804
 
805
 
9599 akron1 806
PROCEDURE plain (text: tText): CB.tBuffer;
8728 leency 807
VAR
808
    buf: CB.tBuffer;
809
    size: INTEGER;
810
    line: tLine;
811
BEGIN
812
    size := 0;
813
    line := text.first(tLine);
814
    WHILE line # NIL DO
815
        line.pos := size;
816
        INC(size, line.length);
817
        NextLine(line);
818
        IF line # NIL THEN
819
            INC(size, CB.lenEOL)
820
        END
821
    END;
9599 akron1 822
    buf := CB.create(size + 2);
8728 leency 823
    line := text.first(tLine);
824
    WHILE line # NIL DO
825
        CB.append(buf, line, 0, line.length - 1);
826
        NextLine(line);
827
        IF line # NIL THEN
828
            CB.eol(buf)
829
        END
830
    END;
9599 akron1 831
    CB.appends(buf, 0X, 0, 0);
832
    CB.appends(buf, 0X, 0, 0)
8728 leency 833
    RETURN buf
834
END plain;
835
 
836
 
837
PROCEDURE search* (text: tText; s: ARRAY OF WCHAR; cs, whole: BOOLEAN): BOOLEAN;
838
VAR
9599 akron1 839
	pos: List.tItem;
840
	res: BOOLEAN;
841
	plainText, idxData: Search.tBuffer;
8728 leency 842
BEGIN
9599 akron1 843
	res := TRUE;
844
	plainText := NIL;
845
	idxData := NIL;
846
	WHILE text.foundList.count # 0 DO
847
		pos := List.pop(text.foundList);
848
		DISPOSE(pos)
849
	END;
850
	text.whole := whole;
851
	text.cs := cs;
852
	text.searchText := s;
853
	IF ~cs THEN
854
		U.upcase16(text.searchText)
855
	END;
856
	IF text.searchText # "" THEN
857
		plainText := plain(text);
858
		idxData := Search.index(plainText, text.table, cs);
859
		Search.find(plainText, text.table, text.searchText, whole, text.foundList);
860
		res := text.foundList.count > 0
861
	END;
862
	CB.destroy(plainText);
863
	CB.destroy(idxData);
864
	text.search := FALSE;
865
	text.foundSel := 0
866
	RETURN res
8728 leency 867
END search;
868
 
869
 
870
PROCEDURE modify (text: tText);
871
BEGIN
872
    text.modified := TRUE;
873
    text.comments := TRUE;
874
    text.search := TRUE;
875
    text.guard := TRUE
876
END modify;
877
 
878
 
9336 akron1 879
PROCEDURE setEnc* (text: tText; enc: INTEGER);
880
BEGIN
881
	IF text.enc # enc THEN
882
		ChangeLog.changeInt(text.enc, enc);
883
		text.enc := enc;
884
		modify(text)
885
	END
886
END setEnc;
887
 
888
 
889
PROCEDURE setEol* (text: tText; eol: INTEGER);
890
BEGIN
891
	IF text.eol # eol THEN
892
		ChangeLog.changeInt(text.eol, eol);
893
		text.eol := eol;
894
		modify(text)
895
	END
896
END setEol;
897
 
898
 
899
PROCEDURE getEnc* (text: tText): INTEGER;
900
	RETURN text.enc
901
END getEnc;
902
 
903
 
904
PROCEDURE getEol* (text: tText): INTEGER;
905
	RETURN text.eol
906
END getEol;
907
 
908
 
8728 leency 909
PROCEDURE DelLine (text: tText; line: tLine);
910
BEGIN
911
    List._delete(text, line);
912
    Lines.destroy(line);
913
    modify(text)
914
END DelLine;
915
 
916
 
917
PROCEDURE setSelect (text: tText);
918
BEGIN
919
    IF text.select = text.cursor THEN
920
        text.select2^ := text.cursor^;
921
        text.select := text.select2
922
    END
923
END setSelect;
924
 
925
 
926
PROCEDURE resetSelect* (text: tText);
927
BEGIN
928
    text.select := text.cursor
929
END resetSelect;
930
 
931
 
932
PROCEDURE getLine (text: tText; n: INTEGER): tLine;
933
VAR
934
    item: List.tItem;
935
BEGIN
936
    item := List.getItem(text, n);
937
    RETURN item(tLine)
938
END getLine;
939
 
940
 
941
PROCEDURE SetPos* (text: tText; x, y: INTEGER);
942
VAR
9174 akron1 943
    deltaY, n, L, R: INTEGER;
8728 leency 944
    cursor: pPoint;
9174 akron1 945
    c: WCHAR;
8728 leency 946
   (* trimLength: INTEGER; *)
947
BEGIN
948
    cursor := text.cursor;
949
    y := MIN(MAX(y, 0), text.count - 1);
950
    deltaY := y - cursor.Y;
951
    IF deltaY # 0 THEN
952
        cursor.Y := y;
953
(*        trimLength := Lines.trimLength(text.curLine);
954
        IF text.curLine.length # trimLength THEN
955
            Lines.setChar(text.curLine, trimLength, 0X);
956
            text.curLine.length := trimLength
957
        END;*)
958
        IF deltaY = 1 THEN
959
            NextLine(text.curLine)
960
        ELSIF deltaY = -1 THEN
961
            PrevLine(text.curLine)
962
        ELSE
963
            text.curLine := getLine(text, y)
964
        END
965
    END;
966
    cursor.X := MIN(MAX(x, 0), text.curLine.length);
9659 akron1 967
    c := Lines.getChar(text.curLine, cursor.X);
9174 akron1 968
    IF c = TAB1 THEN
969
        n := cursor.X;
9659 akron1 970
        WHILE Lines.getChar(text.curLine, n) = TAB1 DO
9174 akron1 971
            INC(n)
972
        END;
973
        R := n - cursor.X;
974
        n := cursor.X;
9659 akron1 975
        WHILE Lines.getChar(text.curLine, n) # TAB DO
9174 akron1 976
            DEC(n)
977
        END;
978
        L := cursor.X - n;
979
        IF L < R THEN
980
            DEC(cursor.X, L)
981
        ELSE
982
            INC(cursor.X, R)
983
        END
984
    END;
8728 leency 985
    IF text.scroll.Y > cursor.Y THEN
986
        text.scroll.Y := cursor.Y
987
    ELSIF text.scroll.Y + textsize.Y <= cursor.Y THEN
988
        text.scroll.Y := cursor.Y - textsize.Y + 1
989
    END;
990
    IF text.scroll.X > cursor.X THEN
991
        text.scroll.X := cursor.X
992
    ELSIF text.scroll.X + textsize.X <= cursor.X THEN
993
        text.scroll.X := cursor.X - textsize.X + 1
994
    END;
995
    IF (text.select.Y = cursor.Y) & (text.select.X > text.curLine.length) THEN
996
        text.select.X := text.curLine.length
997
    END;
998
    setSelect(text);
999
    text.foundSel := 0;
1000
    ShowCursor;
1001
    text.CurX := -1
1002
END SetPos;
1003
 
1004
 
1005
PROCEDURE getSelect (text: tText; VAR selBeg, selEnd: tPoint);
1006
BEGIN
1007
    selBeg := text.cursor^;
1008
    selEnd := text.select^;
1009
    IF (selBeg.Y > selEnd.Y) OR (selBeg.Y = selEnd.Y) & (selBeg.X > selEnd.X) THEN
1010
        selBeg := text.select^;
1011
        selEnd := text.cursor^
1012
    END
1013
END getSelect;
1014
 
1015
 
1016
PROCEDURE selected* (text: tText): BOOLEAN;
1017
    RETURN (text.cursor.X # text.select.X) OR (text.cursor.Y # text.select.Y)
1018
END selected;
1019
 
1020
 
1021
PROCEDURE delSelect (text: tText);
1022
VAR
1023
    selBeg, selEnd: tPoint;
1024
    line, last, cur: tLine;
1025
BEGIN
1026
    getSelect(text, selBeg, selEnd);
1027
    IF (selBeg.Y = selEnd.Y) & (selBeg.X < selEnd.X) THEN
1028
        line := text.curLine;
1029
        Lines.delCharN(line, selBeg.X, selEnd.X - selBeg.X);
1030
        Lines.modify(line);
1031
        text.cursor^ := selBeg;
1032
        resetSelect(text);
1033
        SetPos(text, text.cursor.X, text.cursor.Y);
1034
        modify(text)
1035
    ELSIF selBeg.Y < selEnd.Y THEN
1036
        SetPos(text, selBeg.X, selBeg.Y);
1037
        line := text.curLine;
1038
        Lines.delCharN(line, selBeg.X, line.length - selBeg.X);
1039
        last := getLine(text, selEnd.Y);
1040
        Lines.delCharN(last, 0, selEnd.X);
1041
        cur := line.next(tLine);
1042
        WHILE cur # last DO
1043
            DelLine(text, cur);
1044
            cur := line.next(tLine)
1045
        END;
1046
        resetSelect(text);
1047
        SetPos(text, text.cursor.X, text.cursor.Y);
1048
        pdelete(text);
1049
        modify(text)
1050
    END;
1051
    resetSelect(text)
1052
END delSelect;
1053
 
1054
 
1055
PROCEDURE delete (text: tText);
1056
VAR
9174 akron1 1057
    i, n: INTEGER;
8728 leency 1058
    nextLine, curLine: tLine;
1059
BEGIN
1060
    IF selected(text) THEN
1061
        delSelect(text)
1062
    ELSE
1063
        i := text.cursor.X;
1064
        curLine := text.curLine;
1065
        IF i < curLine.length THEN
9174 akron1 1066
            n := i;
1067
            INC(i);
9659 akron1 1068
            IF Lines.getChar(curLine, i - 1) = TAB THEN
1069
                WHILE Lines.getChar(curLine, i) = TAB1 DO
9174 akron1 1070
                    INC(i)
1071
                END
1072
            END;
1073
            Lines.delCharN(curLine, n, i - n);
8728 leency 1074
            Lines.modify(curLine);
1075
            modify(text)
1076
        ELSE
1077
            nextLine := curLine.next(tLine);
1078
            IF nextLine # NIL THEN
9174 akron1 1079
                Lines.insert2(curLine, i, nextLine);
1080
                DelLine(text, nextLine);
8728 leency 1081
                Lines.modify(curLine);
9174 akron1 1082
                modify(text)
8728 leency 1083
            END
1084
        END
1085
    END;
1086
    setSelect(text)
1087
END delete;
1088
 
1089
 
9174 akron1 1090
PROCEDURE move (text: tText; d: INTEGER);
1091
VAR
1092
    pos: INTEGER;
1093
BEGIN
1094
    pos := text.cursor.X + d;
9659 akron1 1095
    WHILE Lines.getChar(text.curLine, pos) = TAB1 DO
9174 akron1 1096
        INC(pos, d)
1097
    END;
1098
    SetPos(text, pos, text.cursor.Y)
1099
END move;
1100
 
1101
 
8728 leency 1102
PROCEDURE BkSpace (text: tText);
1103
VAR
9174 akron1 1104
    i, k, n: INTEGER;
1105
    curLine, line, line2: tLine;
8728 leency 1106
BEGIN
1107
    IF selected(text) THEN
1108
        delSelect(text)
1109
    ELSE
1110
        resetSelect(text);
1111
        curLine := text.curLine;
9174 akron1 1112
        IF text.cursor.X > 0 THEN
1113
            i := text.cursor.X;
8728 leency 1114
            n := leadingSpaces(curLine);
9175 akron1 1115
            modify(text);
8728 leency 1116
            IF n < i THEN
9174 akron1 1117
                move(text, -1);
1118
                delete(text)
8728 leency 1119
            ELSE
1120
                n := i;
1121
                line := curLine.prev(tLine);
9174 akron1 1122
                line2 := line;
8728 leency 1123
                k := n;
1124
                WHILE (line # NIL) & (k >= n) DO
1125
                    IF Lines.trimLength(line) # 0 THEN
9174 akron1 1126
                        k := leadingSpaces(line);
1127
                        line2 := line;
8728 leency 1128
                    END;
1129
                    PrevLine(line)
1130
                END;
1131
                IF k >= n THEN
1132
                    k := 0
1133
                END;
9174 akron1 1134
                n := k;
1135
                Lines.delCharN(curLine, 0, i);
1136
                Lines.insert3(curLine, 0, k);
1137
                WHILE k > 0 DO
9659 akron1 1138
                    Lines.setChar(curLine, k - 1, Lines.getChar(line2, k - 1));
9174 akron1 1139
                    DEC(k)
1140
                END;
8728 leency 1141
                Lines.modify(curLine);
9174 akron1 1142
                SetPos(text, n, text.cursor.Y)
1143
            END
8728 leency 1144
        ELSE
1145
            PrevLine(curLine);
1146
            IF curLine # NIL THEN
1147
                SetPos(text, curLine.length, text.cursor.Y - 1);
1148
                delete(text)
1149
            END
1150
        END
1151
    END;
1152
    setSelect(text)
1153
END BkSpace;
1154
 
1155
 
1156
PROCEDURE enter (text: tText);
1157
VAR
1158
    n: INTEGER;
9174 akron1 1159
    curLine, newLine, line, line2: tLine;
8728 leency 1160
BEGIN
1161
    delSelect(text);
1162
    newLine := Lines.create(FALSE);
1163
    modify(text);
1164
    curLine := text.curLine;
1165
    IF text.cursor.X < curLine.length THEN
9174 akron1 1166
        Lines.wrap(curLine, newLine, text.cursor.X);
1167
        Lines.modify(curLine)
8728 leency 1168
    END;
1169
    List._insert(text, curLine, newLine);
1170
    SetPos(text, 0, text.cursor.Y + 1);
1171
    line := text.curLine.prev(tLine);
1172
    n := -1;
1173
    WHILE (line # NIL) & (n = -1) DO
1174
        IF (*line.length*)Lines.trimLength(line) # 0 THEN
9174 akron1 1175
            n := leadingSpaces(line);
1176
            line2 := line
8728 leency 1177
        END;
1178
        PrevLine(line)
1179
    END;
1180
    IF n = -1 THEN
1181
        n := 0
1182
    END;
1183
    Lines.insert3(text.curLine, 0, n);
1184
    SetPos(text, n, text.cursor.Y);
1185
    resetSelect(text);
1186
    WHILE n > 0 DO
9659 akron1 1187
        Lines.setChar(text.curLine, n - 1, Lines.getChar(line2, n - 1));
8728 leency 1188
        DEC(n)
9174 akron1 1189
    END;
1190
    Lines.modify(newLine)
8728 leency 1191
END enter;
1192
 
1193
 
9174 akron1 1194
PROCEDURE incIndent (line: tLine);
1195
VAR
1196
	c: WCHAR;
1197
	i: INTEGER;
1198
BEGIN
1199
	Lines.modify(line);
1200
	Lines.insert3(line, 0, Lines.tab);
1201
	IF Lines.tabs THEN
1202
		c := TAB1
1203
	ELSE
1204
		c := SPACE
1205
	END;
1206
	i := Lines.tab - 1;
1207
	WHILE i >= 0 DO
1208
		Lines.setChar(line, i, c);
1209
		DEC(i)
1210
	END;
1211
	IF Lines.tabs THEN
1212
		Lines.setChar(line, 0, TAB)
1213
	END
1214
END incIndent;
1215
 
1216
 
1217
PROCEDURE decIndent (line: tLine): BOOLEAN;
1218
VAR
1219
	n: INTEGER;
1220
BEGIN
1221
	n := leadingSpaces(line);
1222
	IF n > 0 THEN
1223
		Lines.delCharN(line, 0, MIN(Lines.tab, n));
1224
		Lines.modify(line)
1225
	END
1226
	RETURN n > 0
1227
END decIndent;
1228
 
1229
 
1230
PROCEDURE Indent* (text: tText; incr: BOOLEAN);
1231
VAR
1232
    i: INTEGER;
1233
    line: tLine;
1234
    selBeg, selEnd: tPoint;
1235
    modified: BOOLEAN;
1236
BEGIN
1237
	getSelect(text, selBeg, selEnd);
1238
	i := selEnd.Y - selBeg.Y + 1;
1239
	line := getLine(text, selBeg.Y);
1240
	modified := incr;
1241
	WHILE i > 0 DO
1242
		IF incr THEN
1243
			incIndent(line)
1244
		ELSE
1245
    		modified := decIndent(line) OR modified
1246
		END;
1247
		NextLine(line);
1248
		DEC(i)
1249
	END;
1250
	line := getLine(text, selEnd.Y);
1251
	text.select^ := selBeg;
1252
	text.select.X := 0;
1253
	SetPos(text, line.length, selEnd.Y);
1254
	IF modified THEN
1255
   		modify(text)
1256
	END
1257
END Indent;
1258
 
1259
 
8728 leency 1260
PROCEDURE input* (text: tText; code: INTEGER);
1261
VAR
1262
    curLine: tLine;
1263
 
9174 akron1 1264
 
8728 leency 1265
    PROCEDURE tab (text: tText);
1266
    VAR
1267
        i, x: INTEGER;
1268
        curLine: tLine;
9174 akron1 1269
        c: WCHAR;
8728 leency 1270
    BEGIN
9174 akron1 1271
		delSelect(text);
1272
		curLine := text.curLine;
1273
		x := text.cursor.X;
1274
		i := Lines.tab - x MOD Lines.tab;
1275
		Lines.insert3(curLine, x, i);
1276
		SetPos(text, x + i, text.cursor.Y);
1277
		IF Lines.tabs THEN
1278
			c := TAB1
1279
		ELSE
1280
			c := SPACE
1281
		END;
1282
		WHILE i > 0 DO
1283
			Lines.setChar(curLine, x + i - 1, c);
1284
			DEC(i)
1285
		END;
1286
		IF Lines.tabs THEN
1287
			Lines.setChar(curLine, x + i, TAB)
1288
		END;
1289
		Lines.modify(curLine);
1290
		modify(text)
8728 leency 1291
    END tab;
1292
 
9174 akron1 1293
 
8728 leency 1294
BEGIN
1295
    IF (code >= ORD(SPACE)) & (code # 127) THEN
1296
        delSelect(text);
1297
        curLine := text.curLine;
1298
        Lines.insert(curLine, text.cursor.X, WCHR(code));
1299
        Lines.modify(curLine);
1300
        modify(text);
1301
        SetPos(text, text.cursor.X + 1, text.cursor.Y)
1302
    ELSIF code = 8 THEN
9174 akron1 1303
		BkSpace(text)
1304
    ELSIF code = -8 THEN
1305
    	IF selected(text) THEN
1306
    		Indent(text, FALSE)
1307
        END
8728 leency 1308
    ELSIF code = 9 THEN
9174 akron1 1309
    	IF selected(text) THEN
1310
    		Indent(text, TRUE)
1311
    	ELSE
1312
	        tab(text)
1313
        END
8728 leency 1314
    ELSIF code = 13 THEN
1315
        enter(text)
1316
    END
1317
END input;
1318
 
1319
 
1320
PROCEDURE scroll* (text: tText; h, v: INTEGER);
1321
BEGIN
1322
    INC(text.scroll.X, h);
1323
    INC(text.scroll.Y, v);
9050 leency 1324
    text.scroll.X := MIN(MAX(text.scroll.X, 0), text.maxLength);
8728 leency 1325
    text.scroll.Y := MIN(MAX(text.scroll.Y, 0), text.count - 1)
1326
END scroll;
1327
 
1328
 
9180 akron1 1329
PROCEDURE save* (text: tText; name: RW.tFileName): BOOLEAN;
9073 leency 1330
CONST
1331
    tempFile = "/tmp0/1/cedit~.tmp";
8728 leency 1332
VAR
1333
    line: tLine;
1334
    file: RW.tOutput;
1335
    res: BOOLEAN;
1336
BEGIN
9073 leency 1337
    ChangeLog.setGuard(text.edition);
9180 akron1 1338
    file := RW.create(tempFile, text.enc, text.eol);
8728 leency 1339
    IF file # NIL THEN
9073 leency 1340
        ChangeLog.delSaved;
8728 leency 1341
        line := text.first(tLine);
9522 akron1 1342
        WHILE line # NIL DO
1343
            RW.putString(file, line, Lines.trimLength(line));
8728 leency 1344
            NextLine(line);
1345
            IF line # NIL THEN
9522 akron1 1346
                RW.newLine(file)
8728 leency 1347
            END
1348
        END;
9522 akron1 1349
        res := RW.close(file)
8728 leency 1350
    ELSE
1351
        res := FALSE
1352
    END;
9073 leency 1353
    IF res THEN
1354
        res := File.Copy(tempFile, name);
1355
        IF res THEN
1356
            text.modified := FALSE;
1357
            ChangeLog.save(text.edition);
9452 akron1 1358
 
1359
	        line := text.first(tLine);
1360
	        WHILE line # NIL DO
1361
	            IF line.modified THEN
1362
	                Lines.save(line)
1363
	            END;
1364
	            NextLine(line)
9522 akron1 1365
	        END
9073 leency 1366
        END
1367
    END;
9522 akron1 1368
    IF File.Delete(tempFile) THEN END;
9073 leency 1369
    IF ~res THEN
1370
        ChangeLog.delCurSaved
1371
    END
8728 leency 1372
    RETURN res
1373
END save;
1374
 
1375
 
1376
PROCEDURE redoGuard (text: tText; guard: tGuard);
1377
BEGIN
1378
    text.edition := guard;
1379
    text.cursor^ := guard.cursor;
1380
    text.select2^ := guard.select2;
1381
    text.scroll := guard.scroll;
1382
    text.CurX := guard.CurX;
1383
    IF guard.selected THEN
1384
        text.select := text.select2
1385
    ELSE
1386
        text.select := text.cursor
1387
    END;
1388
    text.curLine := getLine(text, text.cursor.Y);
1389
    text.comments := TRUE;
1390
    text.search := TRUE
1391
END redoGuard;
1392
 
1393
 
1394
PROCEDURE undo* (text: tText);
1395
VAR
1396
    item: List.tItem;
1397
    guard: tGuard;
1398
BEGIN
1399
    guard := text.edition;
1400
    item := guard.prev;
1401
    WHILE (item # NIL) & ~(item IS tGuard) DO
1402
        item := item.prev
1403
    END;
1404
 
1405
    IF item # NIL THEN
1406
        guard := item(tGuard);
9073 leency 1407
        text.edition := guard
8728 leency 1408
    END;
1409
 
9050 leency 1410
    item := ChangeLog.CL.Log.first;
8728 leency 1411
    WHILE item # guard DO
1412
        ChangeLog.redo(item);
1413
        item := item.next
1414
    END;
1415
    redoGuard(text, guard);
9073 leency 1416
    ChangeLog.setGuard(guard);
9174 akron1 1417
    text.modified := ~guard.saved;
1418
    ShowCursor
8728 leency 1419
END undo;
1420
 
1421
 
1422
PROCEDURE redo* (text: tText);
1423
VAR
1424
    item: List.tItem;
1425
    guard: tGuard;
1426
BEGIN
1427
    guard := text.edition;
1428
    item := guard.next;
1429
    WHILE (item # NIL) & ~(item IS tGuard) DO
1430
        ChangeLog.redo(item);
1431
        item := item.next
1432
    END;
1433
    IF item # NIL THEN
1434
        guard := item(tGuard);
1435
        redoGuard(text, guard)
1436
    END;
9073 leency 1437
    ChangeLog.setGuard(guard);
9174 akron1 1438
    text.modified := ~guard.saved;
1439
    ShowCursor
8728 leency 1440
END redo;
1441
 
1442
 
9462 akron1 1443
PROCEDURE getSelCnt* (text: tText; VAR chars, lines: INTEGER);
1444
VAR
1445
	selBeg, selEnd: tPoint;
1446
	first, last, line: tLine;
1447
 
1448
	PROCEDURE charCnt (line: tLine; first, last: INTEGER): INTEGER;
1449
	VAR
1450
		i, res: INTEGER;
1451
	BEGIN
1452
		res := 0;
1453
		FOR i := first TO last DO
9659 akron1 1454
			IF Lines.getChar(line, i) # TAB1 THEN
9462 akron1 1455
				INC(res)
1456
			END
1457
		END
1458
		RETURN res
1459
	END charCnt;
1460
 
1461
BEGIN
1462
	IF selected(text) THEN
1463
		getSelect(text, selBeg, selEnd);
1464
		first := getLine(text, selBeg.Y);
1465
		last  := getLine(text, selEnd.Y);
1466
		lines := selEnd.Y - selBeg.Y + 1;
1467
 
1468
		IF lines > 1 THEN
1469
			chars := charCnt(first, selBeg.X, first.length - 1) + charCnt(last, 0, selEnd.X - 1) + lenEOL;
9659 akron1 1470
			line := first.next(tLine);
1471
			WHILE line # last DO
1472
				INC(chars, charCnt(line, 0, line.length - 1) + lenEOL);
1473
				NextLine(line)
1474
			END
9462 akron1 1475
		ELSE
9659 akron1 1476
			chars := charCnt(first, selBeg.X, selEnd.X - 1)
9462 akron1 1477
		END
1478
	ELSE
1479
		chars := 0;
1480
		lines := 0
1481
	END
1482
END getSelCnt;
1483
 
1484
 
8728 leency 1485
PROCEDURE copy (text: tText);
1486
VAR
1487
    selBeg, selEnd: tPoint;
1488
    first, line: tLine;
1489
    cnt, n: INTEGER;
1490
    buffer: CB.tBuffer;
1491
 
1492
 
1493
    PROCEDURE append (buffer: CB.tBuffer; line: tLine; first, last: INTEGER);
1494
    BEGIN
1495
        IF first <= last THEN
1496
            CB.append(buffer, line, first, last)
1497
        ELSE
1498
            IF U.OS = "KOS" THEN
1499
                CB.appends(buffer, SPACE, 0, 0)
1500
            END
1501
        END
1502
    END append;
1503
 
1504
 
1505
BEGIN
1506
    getSelect(text, selBeg, selEnd);
1507
 
1508
    first := getLine(text, selBeg.Y);
1509
    line := first;
1510
 
1511
    n := selEnd.Y - selBeg.Y;
1512
    cnt := 0;
1513
    WHILE n >= 0 DO
9457 akron1 1514
        INC(cnt, line.length + (lenEOL + ORD(U.OS = "KOS")));
8728 leency 1515
        NextLine(line);
1516
        DEC(n)
1517
    END;
1518
 
9599 akron1 1519
    buffer := CB.create(cnt + 2); (* +2 wchars EOT *)
8728 leency 1520
 
1521
    n := selEnd.Y - selBeg.Y;
1522
    line := first;
1523
    IF n = 0 THEN
9457 akron1 1524
        append(buffer, line, selBeg.X, selEnd.X - 1)
8728 leency 1525
    ELSE
1526
        append(buffer, line, selBeg.X, line.length - 1);
1527
        REPEAT
1528
            DEC(n);
1529
            CB.eol(buffer);
1530
            NextLine(line);
1531
            IF n > 0 THEN
1532
                append(buffer, line, 0, line.length - 1)
1533
            END
1534
        UNTIL n = 0;
1535
        append(buffer, line, 0, selEnd.X - 1)
1536
    END;
1537
    CB.eot(buffer);
1538
    CB.put(buffer);
1539
    CB.destroy(buffer)
1540
END copy;
1541
 
1542
 
1543
PROCEDURE paste (text: tText);
1544
VAR
1545
    line, newLine, curLine: tLine;
9174 akron1 1546
    w: INTEGER;
8728 leency 1547
    cliptext: RW.tInput;
1548
    eol: BOOLEAN;
1549
    cursor: pPoint;
9174 akron1 1550
 
1551
 
1552
    PROCEDURE lineWidth (line: tLine; pos: INTEGER): INTEGER;
1553
    VAR
1554
    	i, res: INTEGER;
1555
    	c: WCHAR;
1556
    BEGIN
1557
    	res := pos;
1558
    	i := 0;
1559
    	REPEAT
9659 akron1 1560
	    	c := Lines.getChar(line, i);
9174 akron1 1561
	    	IF c = TAB THEN
1562
	    		INC(res, Lines.tab - res MOD Lines.tab)
1563
	    	ELSIF c # TAB1 THEN
1564
	    		INC(res)
1565
	    	END;
1566
	    	INC(i)
1567
    	UNTIL c = 0X
1568
    	RETURN res - pos - 1
1569
    END lineWidth;
1570
 
1571
 
8728 leency 1572
BEGIN
1573
    line := Lines.create(TRUE);
1574
    cliptext := RW.clipboard();
1575
    delSelect(text);
1576
    cursor := text.cursor;
9174 akron1 1577
    WHILE (cliptext # NIL) & (RW.getString(cliptext, line, Lines.tabs, eol) >= 0) DO
1578
        IF line.length > 0 THEN
1579
        	w := lineWidth(line, cursor.X);
8728 leency 1580
            Lines.insert2(text.curLine, cursor.X, line);
1581
            Lines.modify(text.curLine);
1582
            modify(text);
9174 akron1 1583
            SetPos(text, cursor.X + w, cursor.Y);
8728 leency 1584
            resetSelect(text)
1585
        END;
1586
        IF eol THEN
1587
            newLine := Lines.create(FALSE);
1588
            modify(text);
1589
            curLine := text.curLine;
1590
            IF cursor.X < curLine.length THEN
9174 akron1 1591
                Lines.wrap(curLine, newLine, cursor.X);
1592
                Lines.modify(curLine)
8728 leency 1593
            END;
1594
            List._insert(text, curLine, newLine);
9174 akron1 1595
            Lines.modify(newLine);
8728 leency 1596
            SetPos(text, 0, cursor.Y + 1);
1597
            resetSelect(text)
1598
        END;
1599
        Lines.destroy(line);
1600
        line := Lines.create(TRUE)
1601
    END;
1602
    Lines.destroy(line);
1603
    RW.destroy(cliptext)
1604
END paste;
1605
 
1606
 
1607
PROCEDURE searchScroll (text: tText; n: INTEGER);
1608
BEGIN
1609
    IF n - text.scroll.Y > textsize.Y - 1 THEN
1610
        text.scroll.Y := MAX(n - 2 * textsize.Y DIV 3, 0)
1611
    ELSIF n < text.scroll.Y THEN
1612
        text.scroll.Y := MAX(n - textsize.Y DIV 3, 0)
1613
    END
1614
END searchScroll;
1615
 
1616
 
1617
PROCEDURE goto* (text: tText; n: INTEGER): BOOLEAN;
1618
VAR
1619
    res: BOOLEAN;
1620
BEGIN
1621
    DEC(n);
1622
    IF (0 <= n) & (n < text.count) THEN
1623
        resetSelect(text);
1624
        searchScroll(text, n);
1625
        SetPos(text, 0, n);
1626
        res := TRUE
1627
    ELSE
1628
        res := FALSE
1629
    END
1630
    RETURN res
1631
END goto;
1632
 
1633
 
9060 leency 1634
PROCEDURE toggleLabel* (text: tText);
1635
BEGIN
1636
    text.curLine.label := ~text.curLine.label
1637
END toggleLabel;
1638
 
1639
 
1640
PROCEDURE gotoLabel* (text: tText; frw: BOOLEAN);
1641
VAR
1642
    line: tLine;
1643
    n: INTEGER;
9073 leency 1644
 
1645
    PROCEDURE search (VAR line: tLine; VAR n: INTEGER; frw: BOOLEAN);
1646
    BEGIN
1647
        IF frw THEN
1648
            WHILE (line # NIL) & ~line.label DO
1649
                NextLine(line);
1650
                INC(n)
1651
            END
1652
        ELSE
1653
            WHILE (line # NIL) & ~line.label DO
1654
                PrevLine(line);
1655
                DEC(n)
1656
            END
1657
        END
1658
    END search;
1659
 
9060 leency 1660
BEGIN
1661
    n := text.cursor.Y;
1662
    line := text.curLine;
1663
    IF frw THEN
9073 leency 1664
        NextLine(line);
1665
        INC(n)
9060 leency 1666
    ELSE
9073 leency 1667
        PrevLine(line);
1668
        DEC(n)
9060 leency 1669
    END;
9073 leency 1670
    search(line, n, frw);
1671
    IF line = NIL THEN
1672
        IF frw THEN
1673
            n := 0;
1674
            line := text.first(tLine)
1675
        ELSE
1676
            n := text.count - 1;
1677
            line := text.last(tLine)
1678
        END;
1679
        search(line, n, frw)
1680
    END;
9060 leency 1681
    IF line # NIL THEN
1682
        IF goto(text, n + 1) THEN END
1683
    END
1684
END gotoLabel;
1685
 
1686
 
8728 leency 1687
PROCEDURE changeCase (text: tText; upper: BOOLEAN);
1688
VAR
1689
    i: INTEGER;
1690
    line: tLine;
1691
BEGIN
1692
    line := text.curLine;
1693
    i := text.cursor.X - 1;
1694
 
9659 akron1 1695
    WHILE (i >= 0) & U.isLetter(Lines.getChar(line, i)) DO
8728 leency 1696
        DEC(i)
1697
    END;
1698
 
1699
    IF Lines.chCase(line, i + 1, text.cursor.X - 1, upper) THEN
1700
        modify(text)
1701
    END
1702
END changeCase;
1703
 
1704
 
1705
PROCEDURE chCase* (text: tText; upper: BOOLEAN);
1706
VAR
1707
    selBeg, selEnd: tPoint;
1708
    first, line: Lines.tLine;
1709
    cnt: INTEGER;
1710
    modified: BOOLEAN;
1711
BEGIN
1712
    modified := FALSE;
1713
    IF selected(text) THEN
1714
        getSelect(text, selBeg, selEnd);
1715
        first := getLine(text, selBeg.Y);
1716
        line := first;
1717
        cnt := selEnd.Y - selBeg.Y;
1718
        IF cnt = 0 THEN
1719
            IF Lines.chCase(line, selBeg.X, selEnd.X - 1, upper) THEN
1720
                modified := TRUE
1721
            END
1722
        ELSE
1723
            IF Lines.chCase(line, selBeg.X, line.length - 1, upper) THEN
1724
                modified := TRUE
1725
            END;
1726
            WHILE cnt > 1 DO
1727
                NextLine(line);
1728
                IF Lines.chCase(line, 0, line.length - 1, upper) THEN
1729
                    modified := TRUE
1730
                END;
1731
                DEC(cnt)
1732
            END;
1733
            NextLine(line);
1734
            IF Lines.chCase(line, 0, selEnd.X - 1, upper) THEN
1735
                modified := TRUE
1736
            END
1737
        END
1738
    END;
1739
    IF modified THEN
1740
        modify(text)
1741
    END
1742
END chCase;
1743
 
1744
 
1745
PROCEDURE UpDown (text: tText; step: INTEGER);
1746
VAR
1747
    temp: INTEGER;
1748
BEGIN
1749
    IF text.CurX = -1 THEN
1750
        text.CurX := text.cursor.X
1751
    END;
1752
    temp := text.CurX;
1753
    SetPos(text, temp, text.cursor.Y + step);
1754
    text.CurX := temp
1755
END UpDown;
1756
 
1757
 
1758
PROCEDURE delLine* (text: tText);
1759
BEGIN
1760
    resetSelect(text);
1761
    IF text.curLine.length > 0 THEN
1762
        Lines.delCharN(text.curLine, 0, text.curLine.length)
1763
    END;
1764
    SetPos(text, 0, text.cursor.Y);
1765
    IF text.cursor.Y = text.count - 1 THEN
1766
        BkSpace(text)
1767
    ELSE
1768
        delete(text)
1769
    END
1770
END delLine;
1771
 
1772
 
9174 akron1 1773
PROCEDURE dupLine* (text: tText);
9010 leency 1774
VAR
1775
    newLine, curLine: tLine;
1776
BEGIN
1777
    curLine := text.curLine;
1778
    newLine := Lines.create(FALSE);
1779
    modify(text);
1780
    Lines.insert3(newLine, 0, curLine.length);
1781
    List._insert(text, curLine, newLine);
9174 akron1 1782
    Lines.move(curLine, newLine);
1783
    Lines.modify(newLine)
9010 leency 1784
END dupLine;
1785
 
1786
 
9413 akron1 1787
PROCEDURE MoveLines* (text: tText; down: BOOLEAN);
1788
VAR
9560 akron1 1789
	last, first, line: tLine;
9413 akron1 1790
	selBeg, selEnd, temp: tPoint;
9560 akron1 1791
	step: INTEGER;
9413 akron1 1792
	frw: BOOLEAN;
1793
BEGIN
1794
	getSelect(text, selBeg, selEnd);
9560 akron1 1795
	IF ((selBeg.Y > 0) & ~down OR (selEnd.Y < text.count - 1) & down) THEN
1796
		modify(text);
1797
		step := ORD(down)*2 - 1;
1798
		IF selBeg.Y # selEnd.Y THEN
1799
			frw := (text.cursor.X = selEnd.X) & (text.cursor.Y = selEnd.Y);
1800
 
9413 akron1 1801
			IF down # frw THEN
1802
				temp := text.cursor^;
1803
				SetPos(text, 0, text.select.Y);
1804
				setSelect(text);
1805
				text.select^ := temp
1806
			END;
9560 akron1 1807
 
1808
			ASSERT(selBeg.Y < selEnd.Y);
1809
 
1810
			first := getLine(text, selBeg.Y);
9413 akron1 1811
			last := getLine(text, selEnd.Y);
9560 akron1 1812
 
1813
			line := first;
1814
			Lines.modify(line);
1815
			REPEAT
1816
				NextLine(line);
1817
				Lines.modify(line)
1818
			UNTIL line = last;
1819
 
1820
			IF down THEN
1821
				text.curLine := last.prev(tLine)
1822
			ELSE
1823
				text.curLine := first.next(tLine)
1824
			END;
9413 akron1 1825
			selBeg.X := 0;
1826
			selEnd.X := last.length;
9560 akron1 1827
			IF down THEN
1828
				last := last.next(tLine);
1829
				List._delete(text, last);
1830
				List._insert(text, first.prev, last)
1831
			ELSE
1832
				first := first.prev(tLine);
1833
				List._delete(text, first);
1834
				List._insert(text, last, first)
1835
			END;
1836
			IF down THEN
1837
				temp := selBeg;
1838
				selBeg := selEnd;
1839
				selEnd := temp;
1840
			END;
1841
			SetPos(text, selBeg.X, selBeg.Y + step);
1842
			setSelect(text);
1843
			text.select.X := selEnd.X;
1844
			text.select.Y := selEnd.Y + step
9413 akron1 1845
		ELSE
9560 akron1 1846
			first := getLine(text, selBeg.Y);
1847
			Lines.modify(first);
1848
			IF down THEN
1849
				last := first.next(tLine)
1850
			ELSE
1851
				last := first.prev.prev(tLine)
1852
			END;
1853
			List._delete(text, first);
1854
			List._insert(text, last, first);
1855
			INC(text.cursor.Y, step);
1856
			INC(text.select.Y, step);
1857
			SetPos(text, text.cursor.X, text.cursor.Y)
1858
		END
9413 akron1 1859
	END
1860
END MoveLines;
1861
 
1862
 
9010 leency 1863
PROCEDURE isWordChar (c: WCHAR): BOOLEAN;
1864
    RETURN U.isLetter(c) OR U.isDigit(c) OR (c = "_")
1865
END isWordChar;
1866
 
1867
 
9197 akron1 1868
PROCEDURE getSelectedText* (text: tText; VAR s: ARRAY OF WCHAR);
1869
VAR
1870
    n: INTEGER;
1871
    selBeg, selEnd: tPoint;
1872
BEGIN
1873
	s[0] := 0X;
1874
    IF selected(text) & (text.cursor.Y = text.select.Y) THEN
1875
        getSelect(text, selBeg, selEnd);
1876
        n := getString(text.curLine, selBeg.X, selEnd.X - selBeg.X, s)
1877
    END
1878
END getSelectedText;
1879
 
1880
 
9010 leency 1881
PROCEDURE wordSel* (text: tText);
1882
VAR
1883
    n, i, x1, x2: INTEGER;
1884
    selBeg, selEnd: tPoint;
1885
    str: tString;
1886
    curLine: tLine;
1887
BEGIN
1888
    curLine := text.curLine;
1889
    IF selected(text) & (text.cursor.Y = text.select.Y) THEN
1890
        getSelect(text, selBeg, selEnd);
1891
        x1 := selBeg.X;
1892
        x2 := selEnd.X;
1893
        n := getString(curLine, x1, x2 - x1, str);
1894
    ELSE
1895
        str := ""
1896
    END;
1897
    IF str # "" THEN
1898
        i := 0;
1899
        WHILE (i < n) & isWordChar(str[i]) DO
1900
            INC(i)
1901
        END;
1902
        IF (i # n) OR
9659 akron1 1903
            ((x1 > 0) & isWordChar(Lines.getChar(curLine, x1 - 1))) OR
1904
            ((x2 < curLine.length) & isWordChar(Lines.getChar(curLine, x2))) THEN
9010 leency 1905
            str := ""
1906
        END
1907
    END;
9050 leency 1908
    IF search(text, str, Lang.isCS(text.lang), TRUE) THEN END
9010 leency 1909
END wordSel;
1910
 
1911
 
9336 akron1 1912
PROCEDURE getWordPos (line: tLine; pos: INTEGER): INTEGER;
1913
VAR
1914
	c: WCHAR;
1915
BEGIN
9659 akron1 1916
	c := Lines.getChar(line, pos);
9336 akron1 1917
	IF isWordChar(c) THEN
9659 akron1 1918
		WHILE (pos < line.length) & isWordChar(Lines.getChar(line, pos)) DO
9336 akron1 1919
			INC(pos)
1920
		END
1921
	ELSIF Lines.isSpace(c) THEN
9659 akron1 1922
		WHILE (pos < line.length) & Lines.isSpace(Lines.getChar(line, pos)) DO
9336 akron1 1923
			INC(pos)
1924
		END
1925
	ELSE
9659 akron1 1926
		WHILE (pos < line.length) & ~Lines.isSpace(Lines.getChar(line, pos)) & ~isWordChar(Lines.getChar(line, pos)) DO
9336 akron1 1927
			INC(pos)
1928
		END
1929
	END
1930
	RETURN pos
1931
END getWordPos;
1932
 
1933
 
9073 leency 1934
PROCEDURE key* (text: tText; code: INTEGER; shift, ctrl: BOOLEAN);
9174 akron1 1935
VAR
9336 akron1 1936
	n, wPos: INTEGER;
8728 leency 1937
BEGIN
9073 leency 1938
    IF shift THEN
8728 leency 1939
        setSelect(text)
1940
    ELSE
1941
        IF (33 <= code) & (code <= 40) THEN
9413 akron1 1942
        	IF ~(((code = 38) OR (code = 40)) & ctrl) THEN
1943
	            resetSelect(text)
1944
            END
8728 leency 1945
        END
1946
    END;
1947
 
1948
    CASE code OF
1949
    |33:
9073 leency 1950
        IF ctrl THEN
8728 leency 1951
            UpDown(text, text.scroll.Y - text.cursor.Y)
1952
        ELSE
1953
            text.scroll.Y := MAX(text.scroll.Y - textsize.Y, 0);
1954
            UpDown(text, -textsize.Y)
1955
        END
1956
    |34:
9073 leency 1957
        IF ctrl THEN
8728 leency 1958
            UpDown(text, MIN(text.scroll.Y + textsize.Y - 1, text.count - 1) - text.cursor.Y)
1959
        ELSE
1960
            text.scroll.Y := MIN(text.scroll.Y + textsize.Y, text.count - 1);
1961
            UpDown(text, textsize.Y)
1962
        END
1963
    |35:
9073 leency 1964
        IF ctrl THEN
8728 leency 1965
            SetPos(text, text.last(tLine).length, text.count - 1)
1966
        ELSE
1967
            SetPos(text, text.curLine.length, text.cursor.Y)
1968
        END
1969
    |36:
9073 leency 1970
        IF ctrl THEN
8728 leency 1971
            SetPos(text, 0, 0)
1972
        ELSE
9174 akron1 1973
        	n := leadingSpaces(text.curLine);
9659 akron1 1974
        	IF text.cursor.X <= n THEN
1975
	            n := 0
1976
        	END;
1977
        	SetPos(text, n, text.cursor.Y)
8728 leency 1978
        END
1979
    |37:
1980
        IF (text.cursor.X = 0) & (text.curLine.prev # NIL) THEN
1981
            SetPos(text, text.curLine.prev(tLine).length, text.cursor.Y - 1)
1982
        ELSE
9336 akron1 1983
        	IF ctrl THEN
1984
        		wPos := 0;
1985
        		REPEAT
1986
        			n := wPos;
1987
        			wPos := getWordPos(text.curLine, wPos)
1988
        		UNTIL wPos >= text.cursor.X;
1989
				move(text, n - text.cursor.X)
1990
        	ELSE
1991
            	move(text, -1)
1992
            END
8728 leency 1993
        END
1994
    |38:
9073 leency 1995
        IF ctrl THEN
9413 akron1 1996
            MoveLines(text, FALSE)
9010 leency 1997
        ELSE
1998
            UpDown(text, -1)
1999
        END
8728 leency 2000
    |39:
2001
        IF (text.cursor.X = text.curLine.length) & (text.curLine.next # NIL) THEN
2002
            SetPos(text, 0, text.cursor.Y + 1)
2003
        ELSE
9336 akron1 2004
        	IF ctrl THEN
2005
				move(text, getWordPos(text.curLine, text.cursor.X) - text.cursor.X)
2006
        	ELSE
2007
            	move(text, 1)
2008
        	END
8728 leency 2009
        END
2010
    |40:
9073 leency 2011
        IF ctrl THEN
9413 akron1 2012
            MoveLines(text, TRUE)
9010 leency 2013
        ELSE
2014
            UpDown(text, 1)
2015
        END
2016
    |46:
9073 leency 2017
        IF ctrl THEN
9010 leency 2018
            delLine(text)
2019
        ELSE
9174 akron1 2020
            delete(text);
2021
            ShowCursor
9010 leency 2022
        END
9659 akron1 2023
    |ORD("C"), ORD("X"):
9073 leency 2024
        IF ctrl THEN
8728 leency 2025
            IF selected(text) THEN
2026
                copy(text);
9659 akron1 2027
                IF code = ORD("X") THEN
2028
                	delSelect(text)
2029
                END
8728 leency 2030
            END
2031
        END
2032
    |ORD("V"):
9073 leency 2033
        IF ctrl THEN
8728 leency 2034
            IF CB.available() THEN
2035
                paste(text)
2036
            END
2037
        END
2038
    |ORD("A"):
9073 leency 2039
        IF ctrl THEN
8728 leency 2040
            text.select2.X := 0;
2041
            text.select2.Y := 0;
2042
            text.select := text.select2;
2043
            SetPos(text, text.last(tLine).length, text.count - 1)
2044
        END
2045
    |ORD("L"), ORD("U"):
9073 leency 2046
        IF ctrl THEN
9174 akron1 2047
        	IF selected(text) THEN
2048
            	chCase(text, code = ORD("U"))
2049
            ELSE
2050
            	changeCase(text, code = ORD("U"))
2051
            END;
2052
            ShowCursor
8728 leency 2053
        END
9010 leency 2054
    |ORD("D"):
9073 leency 2055
        IF ctrl THEN
9010 leency 2056
            dupLine(text)
2057
        END
8728 leency 2058
    ELSE
2059
    END
2060
END key;
2061
 
2062
 
2063
PROCEDURE mouse* (text: tText; x, y: INTEGER);
2064
VAR
2065
    cursorX: INTEGER;
2066
BEGIN
2067
    DEC(x, padding.left);
2068
    DEC(y, padding.top);
2069
    cursorX := (x*2) DIV charWidth;
2070
    SetPos(text, cursorX DIV 2 + cursorX MOD 2 + text.scroll.X, y DIV charHeight + text.scroll.Y)
2071
END mouse;
2072
 
2073
 
2074
PROCEDURE selectWord* (text: tText);
2075
VAR
2076
    cursorX, x1, x2: INTEGER;
2077
    line: tLine;
2078
BEGIN
2079
    resetSelect(text);
2080
    cursorX := text.cursor.X;
2081
    line := text.curLine;
2082
    x1 := cursorX - 1;
9659 akron1 2083
    IF (cursorX < line.length) & isWordChar(Lines.getChar(line, cursorX)) THEN
8728 leency 2084
        x2 := cursorX;
9659 akron1 2085
        WHILE (x2 < line.length) & isWordChar(Lines.getChar(line, x2)) DO
8728 leency 2086
            INC(x2)
2087
        END
2088
    ELSE
9659 akron1 2089
        WHILE (x1 >= 0) & ~isWordChar(Lines.getChar(line, x1)) DO
8728 leency 2090
            DEC(x1)
2091
        END;
2092
        x2 := x1 + 1
2093
    END;
9659 akron1 2094
    WHILE (x1 >= 0) & isWordChar(Lines.getChar(line, x1)) DO
8728 leency 2095
        DEC(x1)
2096
    END;
2097
    INC(x1);
2098
    IF x1 < x2 THEN
2099
        SetPos(text, x1, text.cursor.Y);
2100
        setSelect(text);
2101
        SetPos(text, x2, text.cursor.Y)
2102
    END
2103
END selectWord;
2104
 
2105
 
2106
PROCEDURE cursor (text: tText);
2107
VAR
9295 akron1 2108
    x, y1, y2, scrollX, scrollY: INTEGER;
8728 leency 2109
    cursor: pPoint;
2110
BEGIN
2111
    cursor := text.cursor;
9295 akron1 2112
    scrollX := text.scroll.X;
2113
    scrollY := text.scroll.Y;
2114
    IF ~((scrollY > cursor.Y) OR (scrollY + textsize.Y <= cursor.Y) OR
2115
       (scrollX > cursor.X) OR (scrollX + textsize.X <= cursor.X)) THEN
2116
        x := (cursor.X - scrollX)*charWidth + padding.left;
2117
        y1 := (cursor.Y - scrollY)*charHeight + padding.top + (inter DIV 2 + 1);
2118
        y2 := y1 + charHeight - (inter + 2);
2119
        G.notVLine(canvas, x, y1, y2);
2120
        G.notVLine(canvas, x - 1, y1, y2)
8728 leency 2121
    END
2122
END cursor;
2123
 
2124
 
2125
PROCEDURE drawSelect (text: tText; line: tLine; selBeg, selEnd, y: INTEGER);
2126
VAR
2127
    Len, pos, x, firstCharIdx: INTEGER;
2128
BEGIN
2129
    firstCharIdx := MAX(text.scroll.X, selBeg);
2130
    Len := MAX(MIN(line.length - firstCharIdx, selEnd - firstCharIdx), 0);
2131
    Len := MIN(Len, textsize.X - pos + 1);
2132
    SetColor(colors.seltext, colors.selback);
2133
    pos := MAX((selBeg - text.scroll.X), 0);
2134
    x := pos*charWidth + padding.left;
2135
    G.SetColor(canvas, colors.selback);
2136
    G.FillRect(canvas, x - 2, y - inter DIV 2, x + 1 + Len*charWidth, y - inter DIV 2 + charHeight);
9193 akron1 2137
    G.TextOut(canvas, pos*charWidth + padding.left, y, Lines.getPChar(line, firstCharIdx), Len, colors.seltext)
8728 leency 2138
END drawSelect;
2139
 
2140
 
2141
PROCEDURE mark (line: tLine; y: INTEGER);
2142
VAR
2143
    color, i: INTEGER;
2144
BEGIN
2145
    IF line.modified THEN
2146
        color := colors.modified
2147
    ELSIF line.saved THEN
2148
        color := colors.saved
2149
    ELSE
2150
        color := colors.back
2151
    END;
2152
    G.SetColor(canvas, color);
2153
 
2154
    FOR i := 3 TO mark_width + 2 DO
2155
        G.VLine(canvas, padding.left - i, y, y + charHeight)
2156
    END
2157
END mark;
2158
 
2159
 
2160
PROCEDURE setPadding (left, top: INTEGER);
2161
BEGIN
2162
    padding.left := left;
2163
    padding.top := top;
2164
    textsize.X := (size.X - padding.left) DIV charWidth;
2165
    textsize.Y := (size.Y - padding.top) DIV charHeight;
2166
END setPadding;
2167
 
2168
 
2169
PROCEDURE draw* (text: tText);
2170
VAR
2171
    y, n, Len, cnt, i, x: INTEGER;
2172
    line, firstLine, lastLine: tLine;
2173
    selBeg, selEnd: tPoint;
2174
    s: ARRAY 12 OF WCHAR;
2175
    backColor, numWidth, xNum, wNum: INTEGER;
2176
    p: Search.tPos;
2177
    guard: tGuard;
2178
BEGIN
2179
    IF text.search & search(text, text.searchText, text.cs, text.whole) THEN END;
9190 akron1 2180
    IF (text.lang # Lang.langText) & text.comments THEN
8728 leency 2181
        Comments(text)
2182
    END;
2183
    IF text.guard THEN
2184
        NEW(guard);
9050 leency 2185
        List.append(ChangeLog.CL.Log, guard);
9073 leency 2186
        guard.saved := ChangeLog.isFirstGuard(guard);
8728 leency 2187
        text.edition := guard;
9073 leency 2188
        text.guard := FALSE
8728 leency 2189
    ELSE
2190
        guard := text.edition
2191
    END;
2192
 
2193
    guard.cursor := text.cursor^;
2194
    guard.select2 := text.select2^;
2195
    guard.scroll := text.scroll;
2196
    guard.CurX := text.CurX;
2197
    guard.selected := text.select = text.select2;
2198
 
2199
    G.SetColor(canvas, colors.back);
2200
    G.clear(canvas);
9060 leency 2201
    wNum := charWidth;
8728 leency 2202
    IF text.numbers THEN
2203
        numWidth := U.lg10(text.count) + 2;
2204
        xNum := numWidth*wNum - wNum DIV 2;
2205
        setPadding(numWidth*wNum + pad_left, padding.top);
2206
    ELSE
9060 leency 2207
        setPadding(pad_left + wNum*2, padding.top)
8728 leency 2208
    END;
2209
    getSelect(text, selBeg, selEnd);
2210
    y := padding.top + inter DIV 2;
2211
    n := text.scroll.Y;
2212
    line := getLine(text, n);
2213
    firstLine := line;
2214
    cnt := 0;
9210 akron1 2215
    WHILE (line # NIL) & (cnt < textsize.Y) DO
8728 leency 2216
        backColor := colors.back;
2217
        IF (line = text.curLine) & ~selected(text) THEN
2218
            G.SetColor(canvas, colors.curline);
2219
            G.FillRect(canvas, padding.left - 2, y - inter DIV 2, size.X - 1, y - inter DIV 2 + charHeight);
2220
            backColor := colors.curline
2221
        END;
2222
        SetColor(colors.text, backColor);
2223
        Len := MAX(line.length - text.scroll.X, 0);
9193 akron1 2224
        G.TextOut(canvas, padding.left, y, Lines.getPChar(line, text.scroll.X), MIN(Len, textsize.X + 1), colors.delim);
9190 akron1 2225
        IF text.lang # Lang.langText THEN
8728 leency 2226
            parse(text, line, y, backColor, text.lang)
2227
        END;
2228
        mark(line, y - inter DIV 2);
2229
        IF (selBeg.Y < n) & (n < selEnd.Y) THEN
2230
            drawSelect(text, line, 0, line.length, y)
2231
        ELSIF (selBeg.Y = n) & (selEnd.Y = n) & (selBeg.X # selEnd.X) THEN
2232
            drawSelect(text, line, selBeg.X, selEnd.X, y)
2233
        ELSIF (selBeg.Y = n) & (selEnd.Y # n) THEN
2234
            drawSelect(text, line, selBeg.X, line.length, y)
2235
        ELSIF (selBeg.Y # n) & (selEnd.Y = n) THEN
2236
            drawSelect(text, line, 0, selEnd.X, y)
2237
        END;
2238
        NextLine(line);
2239
        INC(y, charHeight);
2240
        INC(n);
2241
        INC(cnt)
2242
    END;
9060 leency 2243
    G.SetColor(canvas, colors.numback);
2244
    G.FillRect(canvas, 0, 0, padding.left - pad_left (*+ 1*), size.Y - 1);
2245
    line := firstLine;
2246
    SetColor(colors.numtext, colors.numback);
2247
    y := padding.top + inter DIV 2;
9210 akron1 2248
    n := MIN(text.scroll.Y + textsize.Y, text.count);
9060 leency 2249
    FOR i := text.scroll.Y + 1 TO n DO
2250
        IF text.numbers THEN
2251
            IF (i MOD 10 = 0) OR (i - 1 = text.cursor.Y) OR line.label THEN
8728 leency 2252
                U.int2str(i, s);
9060 leency 2253
                G.TextOut2(canvas, (numWidth - U.lg10(i) - 1)*wNum - wNum DIV 2, y, s, LENGTH(s))
8728 leency 2254
            ELSE
2255
                G.SetColor(canvas, colors.numtext);
9208 akron1 2256
                G.HLine(canvas, y - inter DIV 2 + charHeight DIV 2, xNum - wNum DIV (1 + ORD(i MOD 5 # 0)), xNum)
9060 leency 2257
            END
2258
        END;
2259
        IF line.label THEN
2260
            FOR x := wNum DIV 2 TO (padding.left - pad_left) - wNum DIV 2 DO
2261
                G.notVLine(canvas, x, y, y + charHeight - inter);
2262
                G.xorVLine(canvas, x, y, y + charHeight - inter)
2263
            END
2264
        END;
2265
        NextLine(line);
2266
        INC(y, charHeight)
8728 leency 2267
    END;
2268
 
2269
    IF text.searchText # "" THEN
2270
        cnt := 0;
2271
        line := firstLine;
2272
        lastLine := line;
9210 akron1 2273
        WHILE (line # NIL) & (cnt < textsize.Y) DO
8728 leency 2274
            lastLine := line;
2275
            NextLine(line);
2276
            INC(cnt)
2277
        END;
2278
        p := text.foundList.first(Search.tPos);
2279
        WHILE p # NIL DO
2280
            y := padding.top + inter DIV 2;
2281
            IF (firstLine.pos <= p.pos) & (p.pos <= lastLine.pos + lastLine.length) THEN
2282
                line := firstLine;
2283
                WHILE (line.pos <= p.pos) & (line # lastLine) DO
2284
                    NextLine(line);
2285
                    INC(y, charHeight)
2286
                END;
2287
                IF (line # lastLine) & (line # firstLine) OR (line = lastLine) & (line.pos > p.pos) THEN
2288
                    PrevLine(line);
2289
                    DEC(y, charHeight)
2290
                END;
2291
                x := (p.pos - line.pos - text.scroll.X)*charWidth + padding.left;
2292
                n := LENGTH(text.searchText)*charWidth;
2293
                WHILE n > 0 DO
2294
                    IF x >= padding.left THEN
2295
                        G.notVLine(canvas, x, y, y + charHeight - inter)
2296
                    END;
2297
                    INC(x);
2298
                    DEC(n)
2299
                END;
2300
            END;
2301
            p := p.next(Search.tPos)
2302
        END
2303
    END;
2304
 
2305
    IF text.foundSel > 0 THEN
2306
        x := (text.cursor.X - text.scroll.X)*charWidth + padding.left;
2307
        y := (text.cursor.Y - text.scroll.Y)*charHeight + padding.top + inter DIV 2;
2308
        n := text.foundSel*charWidth;
2309
        WHILE n > 0 DO
2310
            IF x >= padding.left THEN
2311
                G.xorVLine(canvas, x, y, y + charHeight - inter)
2312
            END;
2313
            INC(x);
2314
            DEC(n)
2315
        END
2316
    END;
2317
 
2318
    IF drawCursor THEN
2319
        cursor(text)
9599 akron1 2320
    END
8728 leency 2321
END draw;
2322
 
2323
 
9050 leency 2324
PROCEDURE switch* (text: tText);
2325
BEGIN
2326
    ChangeLog.set(text.chLog);
9194 akron1 2327
    Lines.setMaxLength(text.maxLength);
2328
    Lang.setCurLang(text.lang)
9050 leency 2329
END switch;
2330
 
2331
 
8728 leency 2332
PROCEDURE create (fileName: RW.tFileName): tText;
2333
VAR
2334
    text: tText;
2335
BEGIN
2336
    NEW(text);
9050 leency 2337
    text.maxLength := 64;
2338
    text.chLog := ChangeLog.create(text.maxLength);
8728 leency 2339
    NEW(text.cursor);
2340
    NEW(text.select2);
2341
    text.cursor.X := 0;
2342
    text.cursor.Y := 0;
2343
    resetSelect(text);
2344
    text.scroll.X := 0;
2345
    text.scroll.Y := 0;
2346
    setPadding(padding.left, padding.top);
2347
    text.curLine := NIL;
2348
    text.modified := FALSE;
2349
    text.comments := TRUE;
2350
    text.search := TRUE;
2351
    text.cs := FALSE;
2352
    text.whole := FALSE;
2353
    text.numbers := TRUE;
2354
    text.guard := TRUE;
2355
    text.edition := NIL;
2356
    text.foundList := List.create(NIL);
2357
    text.searchText := "";
2358
    text.foundSel := 0;
2359
    text.CurX := -1;
9193 akron1 2360
    text.lang := Lang.langText;
2361
    Lang.setCurLang(Lang.langText);
8728 leency 2362
    setName(text, fileName);
2363
    ASSERT(text = List.create(text))
2364
    RETURN text
2365
END create;
2366
 
2367
 
2368
PROCEDURE setColors* (text, back, seltext, selback, modified, saved, curline, numtext, numback,
9413 akron1 2369
                        comment, string, escape, num, delim, key1, key2, key3: INTEGER);
8728 leency 2370
BEGIN
2371
    colors.text := text;
2372
    colors.back := back;
2373
    colors.seltext := seltext;
2374
    colors.selback := selback;
2375
    colors.modified := modified;
2376
    colors.saved := saved;
2377
    colors.curline := curline;
2378
    colors.numtext := numtext;
2379
    colors.numback := numback;
2380
    colors.comment := comment;
2381
    colors.string  := string;
9413 akron1 2382
    colors.escape  := escape;
8728 leency 2383
    colors.num := num;
2384
    colors.delim := delim;
2385
    colors.key1 := key1;
2386
    colors.key2 := key2;
2387
    colors.key3 := key3;
2388
END setColors;
2389
 
2390
 
9659 akron1 2391
PROCEDURE setCanvas* (_canvas: G.tCanvas);
8728 leency 2392
BEGIN
9659 akron1 2393
    canvas := _canvas;
2394
    charWidth := _canvas.font.width;
2395
    charHeight := _canvas.font.height + inter
8728 leency 2396
END setCanvas;
2397
 
2398
 
2399
PROCEDURE resize* (width, height: INTEGER);
2400
BEGIN
2401
    size.X := width;
2402
    size.Y := height;
2403
    setPadding(padding.left, padding.top)
2404
END resize;
2405
 
2406
 
2407
PROCEDURE destroy* (VAR text: tText);
2408
BEGIN
2409
    IF search(text, "", FALSE, FALSE) THEN END;
9448 akron1 2410
    ChangeLog.destroy(text.chLog);
8728 leency 2411
    DISPOSE(text.foundList);
2412
    DISPOSE(text.cursor);
2413
    DISPOSE(text.select2);
2414
    DISPOSE(text)
2415
END destroy;
2416
 
2417
 
2418
PROCEDURE open* (name: RW.tFileName; VAR errno: INTEGER): tText;
2419
VAR
2420
    text: tText;
2421
    file: RW.tInput;
9180 akron1 2422
    n, enc, eol: INTEGER;
2423
    _eol: BOOLEAN;
8728 leency 2424
    line: tLine;
2425
BEGIN
2426
    errno := 0;
9522 akron1 2427
    text := create(name);
2428
    IF text # NIL THEN
2429
    	file := RW.load(name, enc, eol);
2430
    	IF file = NIL THEN
2431
    		destroy(text)
2432
    	END
2433
    ELSE
2434
    	file := NIL
2435
    END;
8728 leency 2436
    IF file # NIL THEN
9336 akron1 2437
        ChangeLog.changeInt(text.enc, enc);
2438
        ChangeLog.changeInt(text.eol, eol);
8728 leency 2439
        text.enc := enc;
9180 akron1 2440
        text.eol := eol;
2441
        line := Lines.create(FALSE);
2442
        List._append(text, line);
8728 leency 2443
        REPEAT
9180 akron1 2444
            n := RW.getString(file, line, Lines.tabs, _eol);
2445
            IF _eol THEN
2446
            	line := Lines.create(FALSE);
2447
            	List._append(text, line)
8728 leency 2448
            END
9180 akron1 2449
        UNTIL ~_eol;
8728 leency 2450
        RW.destroy(file);
9180 akron1 2451
        text.curLine := text.first(tLine);
2452
        SetPos(text, 0, 0);
2453
        resetSelect(text)
8728 leency 2454
    ELSE
2455
        errno := 1
2456
    END;
9190 akron1 2457
    IF (text # NIL) & (text.lang # Lang.langText) THEN
8728 leency 2458
        Comments(text)
2459
    END
2460
    RETURN text
2461
END open;
2462
 
2463
 
2464
PROCEDURE findNext* (text: tText; prev: BOOLEAN): BOOLEAN;
2465
VAR
2466
    cursorPos, x, y, X, Y, Len: INTEGER;
2467
    p: Search.tPos;
2468
    line: tLine;
2469
    res: BOOLEAN;
2470
BEGIN
2471
    X := text.cursor.X;
2472
    Y := text.cursor.Y;
2473
    text.cursor.X := MIN(text.cursor.X, text.curLine.length);
2474
    cursorPos := text.curLine.pos + text.cursor.X - ORD(prev) - ORD(~prev & (text.foundSel = 0));
2475
    p := text.foundList.first(Search.tPos);
2476
    WHILE (p # NIL) & (p.pos <= cursorPos) DO
2477
        p := p.next(Search.tPos)
2478
    END;
2479
    IF prev THEN
2480
        IF p = NIL THEN
2481
            p := text.foundList.last(Search.tPos)
2482
        ELSE
2483
            p := p.prev(Search.tPos)
2484
        END
2485
    END;
2486
    res := p # NIL;
2487
    IF res THEN
2488
        y := 0;
2489
        line := text.first(tLine);
2490
        WHILE (line.pos <= p.pos) & (line.next # NIL) DO
2491
            NextLine(line);
2492
            INC(y)
2493
        END;
2494
        IF (line.next # NIL) OR (line.pos > p.pos) THEN
2495
            PrevLine(line);
2496
            DEC(y)
2497
        END;
2498
        resetSelect(text);
2499
        searchScroll(text, y);
2500
        x := p.pos - line.pos;
2501
        Len := LENGTH(text.searchText);
2502
        IF x + Len > text.scroll.X + textsize.X THEN
2503
            text.scroll.X := MAX(x + Len - textsize.X + 3, 0)
2504
        ELSIF x < text.scroll.X THEN
2505
            text.scroll.X := MAX(x - 3, 0)
2506
        END;
2507
        SetPos(text, x, y);
2508
        text.foundSel := Len
2509
    ELSE
2510
        SetPos(text, X, Y)
2511
    END
2512
    RETURN res
2513
END findNext;
2514
 
2515
 
2516
PROCEDURE replace* (text: tText; s: ARRAY OF WCHAR; n: INTEGER);
2517
VAR
2518
    line: tLine;
2519
    sLen, i: INTEGER;
2520
BEGIN
2521
    IF text.foundSel > 0 THEN
2522
        line := text.curLine;
2523
        sLen := LENGTH(s);
2524
        i := text.cursor.X;
2525
        IF sLen > n THEN
2526
            Lines.insert3(line, i, sLen - n)
9560 akron1 2527
        ELSIF n > sLen THEN
2528
            Lines.delCharN(line, i, n - sLen)
2529
        ELSE (* n = sLen *)
2530
        	Lines.copy(line)
8728 leency 2531
        END;
2532
        SetPos(text, i + sLen, text.cursor.Y);
9560 akron1 2533
	    WHILE sLen > 0 DO
2534
	        DEC(sLen);
2535
	        Lines.setChar(line, i + sLen, s[sLen])
2536
	    END;
8728 leency 2537
        resetSelect(text);
2538
        Lines.modify(line);
2539
        modify(text)
2540
    END
2541
END replace;
2542
 
2543
 
2544
PROCEDURE replaceAll* (text: tText; s: ARRAY OF WCHAR; n: INTEGER): INTEGER;
2545
VAR
2546
    p: Search.tPos;
2547
    line: tLine;
2548
    y, k, d, pos, y0: INTEGER;
2549
BEGIN
2550
    resetSelect(text);
2551
    SetPos(text, 0, 0);
2552
    line := text.first(tLine);
2553
    y := 0;
2554
    y0 := -1;
2555
    k := 0;
2556
    d := LENGTH(s) - n;
2557
    p := text.foundList.first(Search.tPos);
2558
    WHILE p # NIL DO
2559
        pos := p.pos;
2560
        WHILE (line.pos <= pos) & (line.next # NIL) DO
2561
            NextLine(line);
2562
            INC(y)
2563
        END;
2564
        IF (line.next # NIL) OR (line.pos > pos) THEN
2565
            PrevLine(line);
2566
            DEC(y)
2567
        END;
2568
        IF y = y0 THEN
2569
            INC(k, d)
2570
        ELSE
2571
            k := 0;
2572
            y0 := y
2573
        END;
2574
        SetPos(text, pos - line.pos + k, y);
2575
        text.foundSel := n;
2576
        replace(text, s, n);
2577
        p := p.next(Search.tPos)
2578
    END
2579
    RETURN text.foundList.count
2580
END replaceAll;
2581
 
2582
 
2583
PROCEDURE New* (): tText;
2584
VAR
2585
    text: tText;
2586
BEGIN
2587
    text := create("");
2588
    List._append(text, Lines.create(FALSE));
2589
    text.curLine := text.first(tLine);
9336 akron1 2590
    ChangeLog.changeInt(text.enc, E.CP866);
9659 akron1 2591
    ChangeLog.changeInt(text.eol, E.EOL_CRLF);
8728 leency 2592
    text.enc := E.CP866;
9659 akron1 2593
    text.eol := E.EOL_CRLF;
8728 leency 2594
    SetPos(text, 0, 0);
2595
    resetSelect(text)
2596
    RETURN text
2597
END New;
2598
 
2599
 
2600
PROCEDURE init* (pShowCursor: tProcedure);
2601
BEGIN
9174 akron1 2602
    ShowCursor := pShowCursor;
8728 leency 2603
    pdelete := delete;
2604
    drawCursor := TRUE;
2605
    padding.left := pad_left;
2606
    padding.top := pad_top;
2607
END init;
2608
 
2609
 
2610
END Text.