Subversion Repositories Kolibri OS

Rev

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

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