Subversion Repositories Kolibri OS

Rev

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

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