Subversion Repositories Kolibri OS

Rev

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

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