Subversion Repositories Kolibri OS

Rev

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