Browse Source

Show line and column; file modified indicator; new error display

Arthur Yefimov 3 years ago
parent
commit
22464d80c8
9 changed files with 128 additions and 109 deletions
  1. 41 7
      src/Editor.Mod
  2. 7 9
      src/EditorText.Mod
  3. 11 1
      src/FoStrings.Mod
  4. 10 38
      src/FreeOberon.Mod
  5. 6 2
      src/Int.Mod
  6. 5 15
      src/OV.Mod
  7. 11 0
      src/Strings.Mod
  8. 2 2
      src/TermBox.Mod
  9. 35 35
      src/make.sh

+ 41 - 7
src/Editor.Mod

@@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License
 along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 *)
 IMPORT OV, T := TermBox, Text := EditorText,
-  Strings, StrList, Dir, Out;
+  Int, Strings, StrList, Dir, Out;
 CONST
   stdPath* = 'Programs/';
   dotChar = 0B7X; (* To higlight spaces *)
@@ -62,7 +62,9 @@ TYPE
   Editor* = POINTER TO EditorDesc;
   EditorDesc* = RECORD(OV.WindowDesc)
     text*: Text.Text;
-    fname*: ARRAY 1000 OF CHAR
+    fname*: ARRAY 1000 OF CHAR;
+    msgShown*: INTEGER; (* 0 - hidden, 1 - top, 2 - bottom *)
+    msg*: ARRAY 256 OF CHAR
   END;
 
 VAR
@@ -872,7 +874,8 @@ END HandleEnter;
 PROCEDURE InitEditor*(c: Editor);
 BEGIN OV.InitWindow(c); c.closeOnEsc := FALSE;
   c.fname[0] := 0X; c.bg := 1; c.resizable := TRUE; c.caption := 'NONAME';
-  c.text := Text.NewText(); c.do := editorMethod
+  c.text := Text.NewText(); c.msgShown := 0; c.msg[0] := 0X;
+  c.do := editorMethod
 END InitEditor;
 
 PROCEDURE NewEditor*(): Editor;
@@ -880,6 +883,17 @@ VAR w: Editor;
 BEGIN NEW(w); InitEditor(w) ;
 RETURN w END NewEditor;
 
+PROCEDURE SetMsg*(c: OV.Control; IN s: ARRAY OF CHAR);
+VAR e: Editor; n: INTEGER;
+BEGIN e := c(Editor);
+  IF e.text.scrFirst = e.text.cur THEN n := 2 ELSE n := 1 END;
+  e.msgShown := n; Strings.Copy(s, e.msg)
+END SetMsg;
+
+PROCEDURE HideMsg*(c: OV.Control);
+BEGIN c(Editor).msgShown := 0
+END HideMsg;
+
 (* Standard Menu Hanlders *)
 
 PROCEDURE EditCut*(c: OV.Control);
@@ -939,14 +953,34 @@ END EditUnselect;
 
 (* EditorMethod *)
 
+PROCEDURE PrintMsg(c: Editor);
+VAR y: INTEGER;
+BEGIN
+  IF c.msgShown = 1 THEN y := c.y + 1 ELSE y := c.y + c.h - 2 END;
+  T.Fill(c.x + 1, y, c.w - 2, 1, ' ', 14, 4);
+  T.Print(c.x + 2, y, c.w - 3, c.msg, 14, 4)
+END PrintMsg;
+
+PROCEDURE DrawEditorMarks(c: Editor);
+VAR x, y: INTEGER;
+  s: ARRAY 30 OF CHAR;
+BEGIN y := c.y + c.h - 1;
+  IF c.text.changed THEN T.SetChar(c.x + 2, y, 0FX) END;
+  Int.Str(c.text.y + 1, s); x := 5 + Strings.Length(s);
+  Strings.Append(':', s); Int.Append(c.text.x + 1, s);
+  Strings.Insert(' ', 0, s); Strings.Append(' ', s);
+  T.Print(c.x + x, y, c.w - x, s, 15, 1)
+END DrawEditorMarks;
+
 PROCEDURE EditorDraw*(c: OV.Control; x, y: INTEGER);
-BEGIN OV.WindowDraw(c, x, y);
-  PrintText(c(Editor))
+BEGIN OV.WindowDraw(c, x, y); DrawEditorMarks(c(Editor));
+  PrintText(c(Editor));
+  IF c(Editor).msgShown # 0 THEN PrintMsg(c(Editor)) END
 END EditorDraw;
 
 PROCEDURE EditorMouseDown*(c: OV.Control; x, y, button: INTEGER);
 VAR t: Text.Text; L: Text.Line; i: INTEGER;
-BEGIN OV.WindowMouseDown(c, x, y, button);
+BEGIN OV.WindowMouseDown(c, x, y, button); HideMsg(c);
   IF (x > 0) & (x < c.w - 1) & (y > 0) & (y < c.h - 1) THEN
     DEC(x); DEC(y); t := c(Editor).text;
     t.selected := FALSE; L := t.scrFirst; i := y;
@@ -985,7 +1019,7 @@ END EditorClose;
 
 PROCEDURE EditorKeyDown*(c: OV.Control; VAR E: T.Event);
 VAR shiftPressed: BOOLEAN;
-BEGIN OV.WindowKeyDown(c, E);
+BEGIN OV.WindowKeyDown(c, E); HideMsg(c);
   shiftPressed := E.mod * T.mShift # {};
   CASE E.key OF
     T.kLeft:

+ 7 - 9
src/EditorText.Mod

@@ -436,15 +436,13 @@ RETURN success END LoadFromFile;
 PROCEDURE (t: Text) MoveToLineCol*(line, col, winH: INTEGER), NEW;
 VAR i, centerY, tx, ty: INTEGER; L: Line;
 BEGIN L := t.first; tx := 0; ty := 0; DEC(line); DEC(col);
-  WHILE (L # NIL) & (ty # line) DO L := L.next; INC(ty) END;
-  IF L # NIL THEN
-    WHILE (L.s[tx] # 0X) & (col > 0) DO DEC(col); INC(tx) END;
-    t.x := tx; t.y := ty; t.cur := L;
-    IF (ty > t.scrY + winH - 4) OR (ty < t.scrY + 1) THEN 
-      i := 5; IF i > winH DIV 2 THEN i := winH DIV 2 END;
-      WHILE (L.prev # NIL) & (i # 0) DO L := L.prev; DEC(i); DEC(ty) END;
-      t.scrFirst := L; t.scrY := ty
-    END
+  WHILE (L.next # NIL) & (ty # line) DO L := L.next; INC(ty) END;
+  WHILE (L.s[tx] # 0X) & (col > 0) DO DEC(col); INC(tx) END;
+  t.x := tx; t.y := ty; t.cur := L;
+  IF (ty >= t.scrY + winH) OR (ty < t.scrY) THEN 
+    i := winH DIV 2;
+    WHILE (L.prev # NIL) & (i # 0) DO L := L.prev; DEC(i); DEC(ty) END;
+    t.scrFirst := L; t.scrY := ty
   END
 END MoveToLineCol;
 

+ 11 - 1
src/FoStrings.Mod

@@ -3,7 +3,7 @@ IMPORT Strings, Int;
 
 PROCEDURE GetErrorStr*(err: INTEGER; VAR s: ARRAY OF CHAR);
 BEGIN
-  IF err = 41 THEN s := 'Ожидается точка с запятой'
+  IF err = 41 THEN s := 'Пропущена точка с запятой.'
   ELSE
     s := 'Ошибка ';
     Int.Append(err, s);
@@ -11,4 +11,14 @@ BEGIN
   END
 END GetErrorStr;
 
+PROCEDURE MakeErrorStr*(err: INTEGER; VAR s: ARRAY OF CHAR);
+VAR z: ARRAY 256 OF CHAR;
+BEGIN
+  GetErrorStr(err, z);
+  s := 'Ошибка #';
+  Int.Append(err, s);
+  Strings.Append(': ', s);
+  Strings.Append(z, s)
+END MakeErrorStr;
+
 END FoStrings.

+ 10 - 38
src/FreeOberon.Mod

@@ -89,40 +89,12 @@ RETURN lines END CountLines;
 
 PROCEDURE ShowErrors(s: ARRAY OF CHAR);
 VAR lines, width, x0, x, y, i: INTEGER;
+  e: Editor.Editor;
 BEGIN
-  ;;;;;;Out.String('ERRORS:'); Out.Ln;;;;;;
+  (*;;;;;;Out.String('ERROR STRING: ['); Out.String(s); Out.String('] END.'); Out.Ln;;;;;;*)
+  e := app.windows(Editor.Editor);
+  Editor.SetMsg(e, s);
   OV.SetStatusText(app, s);
-  (*T.Print(0, 1, s, 14, 12);
-  T.Flush;*)
-  ;;;;;;Out.String(s); Out.Ln;;;;;;
-  ;;;;;;Out.String('END ERRORS.'); Out.Ln;;;;;;
-(*
-  width := T.charsX - 2;
-  lines := CountLines(s, width);
-  IF lines > 10 THEN lines := 10 END;
-  i := 0; x0 := 1; x := x0;
-  y := T.charsY - 2 - lines;
-  WHILE (s[i] # 0X) & (y < T.charsY - 2) DO
-    IF s[i] = 0AX THEN
-      WHILE x < x0 + width DO (* Till end of line *)
-        T.PutChar(x, y, ' ', 0, 3); INC(x)
-      END;
-      x := x0; INC(y)
-    ELSIF s[i] # 0DX THEN
-      T.PutChar(x, y, s[i], 0, 3);
-      IF x = x0 + width - 1 THEN INC(y); x := x0
-      ELSE INC(x)
-      END
-    END;
-    INC(i)
-  END;
-  IF x > x0 THEN
-    WHILE x < x0 + width DO
-      T.PutChar(x, y, ' ', 0, 3); INC(x)
-    END
-  END;
-  IF T.Draw() THEN G.Flip; G.Pause END (*!FIXME*)
-  *)
 END ShowErrors;
 
 (* !TODO move out, rewrite *)
@@ -312,7 +284,7 @@ BEGIN fname[0] := 0X; line := 1; col := 1;
         INC(i, 4); ReadInt(s, i, error)
       ELSE error := 0
       END;
-      FoStrings.GetErrorStr(error, s);
+      FoStrings.MakeErrorStr(error, s);
       ;;;;;Out.String('error = ');Out.Int(error, 0);Out.Ln;;;;;;
     END
   END
@@ -516,7 +488,7 @@ BEGIN
       Strings.Append('" /C Data\bin\', cmd);
       Strings.Append(command, cmd);
       Strings.Append('.bat ', cmd)
-    ELSE T.Print(0, tH - 1, 'Could not find cmd.exe', 15, 4)
+    ELSE T.Print(0, tH - 1, -1, 'Could not find cmd.exe', 15, 4)
     END
   ELSE (* Linux *)
     cmd := 'Data/bin/'; Strings.Append(command, cmd);
@@ -553,12 +525,12 @@ BEGIN
       END;
       Utf8.Decode(buf, z);
       ParseErrors(z, fname, line, col, error);
-      Out.Int(line, 10);Out.Int(col, 10);Out.Ln;;;;;;;
+      ;;;;;;;;Out.String('Место ошибки: '); Out.Int(line, 0);Out.Char(':');Out.Int(col, 0);Out.Ln;;;;;;;
       FocusOrOpenFile(fname);
       e := app.windows(Editor.Editor);
-      e.text.MoveToLineCol(line, col, e.h - 2);
-      IF (col = 1) & (line # 1) & (TRUE) THEN
+      IF (col = 1) & (line # 1) THEN
         e.text.MoveToLineCol(line - 1, 256, e.h - 2)
+      ELSE e.text.MoveToLineCol(line, col, e.h - 2)
       END;
       Editor.PrintText(app.windows(Editor.Editor))
     ELSIF link THEN z := 'Linking failed.'
@@ -644,7 +616,7 @@ BEGIN dir := prg$;
   Utf8.Encode(dir, d);
   IF ~Term.StartProcessIn(s, d) THEN
     ;;;;;;;;;;Out.String('EXECUTION FAILED');Out.Ln;;;;;;;;;
-    T.Print(0, tH - 1, ' Program execution failed ', 15, 4);
+    T.Print(0, tH - 1, -1, ' Program execution failed ', 15, 4);
     T.Flush
     (* ; T.Pause !FIXME*)
   ELSE

+ 6 - 2
src/Int.Mod

@@ -36,10 +36,14 @@ BEGIN n := 0; c := s[0];
   IF neg THEN n := -n END ;
 RETURN n END Val;
 
+PROCEDURE Insert*(n: INTEGER; pos: INTEGER; VAR s: ARRAY OF CHAR);
+VAR sn: ARRAY 30 OF CHAR;
+BEGIN Str(n, sn); Strings.Insert(sn, pos, s)
+END Insert;
+
 PROCEDURE Append*(n: INTEGER; VAR s: ARRAY OF CHAR);
 VAR sn: ARRAY 30 OF CHAR;
-BEGIN
-  Str(n, sn); Strings.Append(sn, s)
+BEGIN Str(n, sn); Strings.Append(sn, s)
 END Append;
 
 END Int.

+ 5 - 15
src/OV.Mod

@@ -726,7 +726,7 @@ BEGIN T.Size(tW, tH); x := 0;
   END;
   IF app.statusText[0] # 0X THEN
     T.SetCell(x, tH - 1, T.lineVert, 0, 7);
-    T.Print(x + 2, tH - 1, app.statusText, 0, 7)
+    T.Print(x + 2, tH - 1, -1, app.statusText, 0, 7)
   END
 END DrawAppStatusbar;
 
@@ -833,16 +833,6 @@ PROCEDURE SetCharColor(x, y, fg, bg: INTEGER);
 BEGIN T.SetFg(x, y, fg); T.SetBg(x, y, bg)
 END SetCharColor;
 
-PROCEDURE PrintLimited(x, y: INTEGER; s: ARRAY OF CHAR;
-  fg, bg, limit: INTEGER);
-VAR i: INTEGER;
-BEGIN
-  i := 0;
-  WHILE (s[i] # 0X) & (x <= limit) DO
-    T.SetCell(x, y, s[i], fg, bg);
-    INC(i); INC(x)
-  END;
-END PrintLimited;
 
 PROCEDURE DrawWindowBorder*(x, y, w, h, fg, bg: INTEGER;
   title: ARRAY OF CHAR; resizable, moving, inactive: BOOLEAN);
@@ -912,7 +902,7 @@ BEGIN single := moving OR inactive;
     IF i + len > x2 - 4 THEN len := x2 - i - 4 END;
     IF i # x + 5 THEN T.SetCell(i - 1, y, ' ', fg, bg) END;
     IF i + len # x2 - 4 THEN T.SetCell(i + len, y, ' ', fg, bg) END;
-    PrintLimited(i, y, title, fg, bg, i + len - 1)
+    T.Print(i, y, i + len - 1, title, fg, bg)
   END
 END DrawWindowBorder;
 
@@ -1123,7 +1113,7 @@ BEGIN
     END;
     IF m.status = disabled THEN fg := 8 ELSE fg := 0 END;
     IF m(Menu).hint[0] # 0X THEN
-      T.Print(x - m(Menu).hintW - 1, y, m(Menu).hint, fg, bg)
+      T.Print(x - m(Menu).hintW - 1, y, -1, m(Menu).hint, fg, bg)
     ELSIF (m.children # NIL) & (m.y # 0) THEN
       T.SetCell(x - 2, y, T.triangleRight, fg, bg)
     END
@@ -1435,7 +1425,7 @@ BEGIN L := c(Label); INC(x, c.x); INC(y, c.y); X := x;
   IF L.align = right THEN INC(X, c.w - L.len)
   ELSIF L.align = center THEN INC(X, (c.w - L.len) DIV 2)
   END;
-  PrintLimited(X, y, c.caption, 0, 7, x + c.w - 1)
+  T.Print(X, y, x + c.w - 1, c.caption, 0, 7)
 END LabelDraw;
 
 (* LabelMethod *)
@@ -1863,7 +1853,7 @@ BEGIN C := c(ColumnList); INC(x, C.x); INC(y, C.y);
       ELSE fg := 14
       END
     END;
-    PrintLimited(x2, y2, s, fg, bg, x2 + colw - 1);
+    T.Print(x2, y2, x2 + colw - 1, s, fg, bg);
     IF y2 < y + C.h - 2 THEN INC(y2) ELSE y2 := y; INC(x2, colw + 1) END;
     StrList.Next(C.items, s); INC(i)
   END;

+ 11 - 0
src/Strings.Mod

@@ -21,6 +21,8 @@ Strings.Extract(src, pos, n, dst)
   If n > Length(src) - pos, dst is only the part of src from pos to Length(src) - 1. If the size of
   dst is not large enough to hold the result of the operation, the result is truncated so that
   dst is always terminated with a 0X.
+Strings.Copy(src, dst)
+  has the same effect as Extract(src, 0, LEN(dst), dst)
 Strings.Pos(pat, s, pos)
   returns the position of the first occurrence of pat in s after position pos (inclusive).
   If pat is not found, -1 is returned.
@@ -104,6 +106,15 @@ BEGIN len := Length(source);
   END
 END Extract;
 
+PROCEDURE Copy*(IN source: ARRAY OF CHAR; VAR dest: ARRAY OF CHAR);
+VAR i, len: INTEGER;
+BEGIN len := LEN(dest) - 1;
+  IF LEN(source) < LEN(dest) THEN len := LEN(source) - 1 END;
+  i := 0;
+  WHILE (i # len) & (source[i] # 0X) DO dest[i] := source[i]; INC(i) END;
+  dest[i] := 0X
+END Copy;
+
 PROCEDURE Pos*(IN pattern, s: ARRAY OF CHAR; pos: INTEGER): INTEGER;
 VAR n1, n2, i, j: INTEGER;
 BEGIN

+ 2 - 2
src/TermBox.Mod

@@ -689,10 +689,10 @@ BEGIN
   END
 END Fill;
 
-PROCEDURE Print*(x, y: INTEGER; s: ARRAY OF CHAR; fg, bg: INTEGER);
+PROCEDURE Print*(x, y, limit: INTEGER; s: ARRAY OF CHAR; fg, bg: INTEGER);
 VAR i, w, h: INTEGER;
 BEGIN i := 0;
-  WHILE (s[i] # 0X) & (x < buffer.w) DO
+  WHILE (s[i] # 0X) & (i # limit) & (x < buffer.w) DO
     SetCell(x, y, s[i], fg, bg); INC(i); INC(x)
   END
 END Print;

+ 35 - 35
src/make.sh

@@ -12,67 +12,67 @@ AR="ar"
 CCFULL="$CC -g3 -O0 -fno-exceptions -I $OFRDIR/../../Mod/Lib -I $OFRDIR/Lib/Obj"
 
 
-$OFR -Cw Config_linux.Mod
+$OFR -Cw Config_linux.Mod &&
 
-$OFR -Cw Utf8.Mod
+$OFR -Cw Utf8.Mod &&
 
-$OFR -Cw Strings.Mod
+$OFR -Cw Strings.Mod &&
 
-$OFR -Cw Reals.Mod
+$OFR -Cw Reals.Mod &&
 
-$OFR -Cw Int.Mod
+$OFR -Cw Int.Mod &&
 
-$OFR -Cw In.Mod
+$OFR -Cw In.Mod &&
 
-$OFR -Cw Out.Mod
+$OFR -Cw Out.Mod &&
 
-$OFR -Cw Files.Mod
+$OFR -Cw Files.Mod &&
 
-$OFR -7w Texts.Mod
+$OFR -7w Texts.Mod &&
 
-$OFR -7w Random.Mod
+$OFR -7w Random.Mod &&
 
-$OFR -7w StrList.Mod
+$OFR -7w StrList.Mod &&
 
-$OFR -7w Dir.Mod
+$OFR -7w Dir.Mod &&
 
-$OFR -7w Allegro5.Mod
+$OFR -7w Allegro5.Mod &&
 
-$OFR -7w Graph2.Mod
+$OFR -7w Graph2.Mod &&
 
-$OFR -7w TermBox.Mod
+$OFR -7w TermBox.Mod &&
 
-$OFR -Cw Term.Mod
+$OFR -Cw Term.Mod &&
 
-$OFR -7w OV.Mod
+$OFR -7w OV.Mod &&
 
-$OFR -7w FoStrings.Mod
+$OFR -7w FoStrings.Mod &&
 
-$OFR -Cw EditorText.Mod
+$OFR -Cw EditorText.Mod &&
 
-$OFR -Cw Editor.Mod
+$OFR -Cw Editor.Mod &&
 
-$OFR -Cwm FreeOberon.Mod
+$OFR -Cwm FreeOberon.Mod &&
 
 
 
-$CCFULL -c Utf8.c
-$CCFULL -c Strings.c
-$CCFULL -c Reals.c
-$CCFULL -c Int.c
-$CCFULL -c In.c
-$CCFULL -c Out.c
-$CCFULL -c Files.c
-$CCFULL -c Texts.c
-$CCFULL -c Random.c
-$CCFULL -c StrList.c
-$CCFULL -c Dir.c
-$CCFULL -c Graph2.c
-$CCFULL -c TermBox.c
+$CCFULL -c Utf8.c &&
+$CCFULL -c Strings.c &&
+$CCFULL -c Reals.c &&
+$CCFULL -c Int.c &&
+$CCFULL -c In.c &&
+$CCFULL -c Out.c &&
+$CCFULL -c Files.c &&
+$CCFULL -c Texts.c &&
+$CCFULL -c Random.c &&
+$CCFULL -c StrList.c &&
+$CCFULL -c Dir.c &&
+$CCFULL -c Graph2.c &&
+$CCFULL -c TermBox.c &&
 
 $AR -crs ../Data/bin/libFreeOberon.a \
   Utf8.o Strings.o Reals.o Int.o In.o Out.o Files.o Texts.o Random.o \
-  StrList.o Dir.o Graph2.o TermBox.o
+  StrList.o Dir.o Graph2.o TermBox.o &&
 
 $CCFULL -o ../$PROG \
   Graph2.c TermBox.c \