Subversion Repositories Kolibri OS

Rev

Rev 9599 | Rev 9668 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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