Subversion Repositories Kolibri OS

Rev

Rev 8762 | Rev 9050 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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