Переглянути джерело

Autoremove autoindentation; restore Tab key

Arthur Yefimov 3 роки тому
батько
коміт
8d09be4d73
4 змінених файлів з 63 додано та 44 видалено
  1. 10 14
      src/Editor.Mod
  2. 26 8
      src/EditorText.Mod
  3. 15 11
      src/OV.Mod
  4. 12 11
      src/Strings.Mod

+ 10 - 14
src/Editor.Mod

@@ -708,8 +708,7 @@ END MoveScreen;
 (* Moves input cursor up and down *)
 PROCEDURE MoveByLine(c: Editor; down, viaHoriz: BOOLEAN);
 VAR moved: BOOLEAN;
-BEGIN
-  moved := FALSE;
+BEGIN c.text.MaybeRemoveIndent; moved := FALSE;
   IF down THEN
     IF c.text.cur.next # NIL THEN
       HandleSelection(c, dirDown, viaHoriz);
@@ -735,7 +734,7 @@ END MoveByLine;
 (* Moves input cursor up and down by page *)
 PROCEDURE MoveByPage(c: Editor; down: BOOLEAN);
 VAR i: INTEGER; moved: BOOLEAN;
-BEGIN i := c.h - 3;
+BEGIN c.text.MaybeRemoveIndent; i := c.h - 3;
   IF down THEN
     moved := c.text.cur.next # NIL;
     WHILE (i > 0) & (c.text.cur.next # NIL) DO
@@ -746,7 +745,9 @@ BEGIN i := c.h - 3;
   ELSE (* Up *)
     moved := c.text.cur.prev # NIL;
     WHILE (i > 0) & (c.text.cur.prev # NIL) DO
-      IF c.text.scrY > 0 THEN c.text.scrFirst := c.text.scrFirst.prev; DEC(c.text.scrY) END;
+      IF c.text.scrY > 0 THEN
+        c.text.scrFirst := c.text.scrFirst.prev; DEC(c.text.scrY)
+      END;
       MoveByLine(c, FALSE, FALSE);
       DEC(i)
     END
@@ -758,14 +759,14 @@ END MoveByPage;
 (* Moves input cursor left and right by one char *)
 PROCEDURE MoveInLine(c: Editor; right: BOOLEAN);
 BEGIN
-  IF right THEN
+  IF right THEN c.text.MaybeRemoveIndent;
     IF c.text.x < c.text.cur.len THEN
       HandleSelection(c, dirRight, FALSE); INC(c.text.x)
     ELSIF c.text.cur.next # NIL THEN
       MoveByLine(c, TRUE, TRUE);
       c.text.x := 0;
     END
-  ELSE (* Left *)
+  ELSE (* Left *) c.text.newLineCreated := FALSE;
     IF c.text.x > 0 THEN
       HandleSelection(c, dirLeft, FALSE); DEC(c.text.x)
     ELSIF c.text.cur.prev # NIL THEN
@@ -839,10 +840,7 @@ END HandleDelete;
 PROCEDURE HandleTab(e: Editor; shift: BOOLEAN);
 BEGIN
   IF shift THEN e.text.RemoveIndent
-  ELSIF e.text.WholeLineSelected() THEN
-    IF shift THEN e.text.RemoveIndent
-    ELSE e.text.AddIndent
-    END
+  ELSIF e.text.WholeLineSelected() THEN e.text.AddIndent
   ELSE
     IF e.text.selected THEN e.text.DeleteSelection END;
     e.text.InsertChar(' ');
@@ -952,13 +950,11 @@ BEGIN OV.WindowMouseDown(c, x, y, button);
 END EditorMouseDown;
 
 PROCEDURE EditorMouseUp*(c: OV.Control; x, y, button: INTEGER);
-BEGIN
-  OV.WindowMouseUp(c, x, y, button)
+BEGIN OV.WindowMouseUp(c, x, y, button)
 END EditorMouseUp;
 
 PROCEDURE EditorMouseMove*(c: OV.Control; x, y: INTEGER; buttons: SET);
-BEGIN
-  OV.WindowMouseMove(c, x, y, buttons)
+BEGIN OV.WindowMouseMove(c, x, y, buttons)
 END EditorMouseMove;
 
 PROCEDURE EditorTextInput(c: OV.Control; ch: CHAR);

+ 26 - 8
src/EditorText.Mod

@@ -248,17 +248,34 @@ BEGIN
   END
 END HandleDelete;
 
+PROCEDURE (t: Text) MaybeRemoveIndent*, NEW;
+VAR i: INTEGER;
+  L: Line;
+BEGIN
+  IF t.newLineCreated & (t.x = t.cur.len) THEN
+    L := t.cur; i := 0;
+    WHILE (L.s[i] # 0X) & (L.s[i] = ' ') DO INC(i) END;
+    IF L.s[i] = 0X THEN
+      t.x := 0; L.len := 0; L.s[0] := 0X;
+      t.changed := TRUE
+    END;
+    t.newLineCreated := FALSE
+  END
+END MaybeRemoveIndent;
+
 PROCEDURE (t: Text) HandleEnter*(autoIndent: BOOLEAN), NEW;
-VAR L: Line; i, spaces: INTEGER;
-BEGIN t.MaybeRemoveIndent; L := NewLine(); spaces := 0;
+VAR L: Line; x, i, spaces: INTEGER;
+BEGIN x := t.x; IF autoIndent THEN t.MaybeRemoveIndent END;
+  L := NewLine(); spaces := 0;
   IF t.winLineEndings THEN L.lineEndLen := 2 ELSE L.lineEndLen := 1 END;
-  IF t.x = 0 THEN (* Начало строки *)
+  IF (t.x = 0) & (t.cur.len # 0) THEN (* Начало непустой строки *)
     IF t.cur.prev # NIL THEN t.cur.prev.next := L END;
     L.next := t.cur; L.prev := t.cur.prev;
     t.cur.prev := L;
     IF t.first = t.cur THEN t.first := L END;
     IF t.scrFirst = t.cur THEN t.scrFirst := L END
   ELSE (* Середина или конец строки *)
+    IF t.x = 0 THEN spaces := x END;
     IF autoIndent THEN
       WHILE (spaces < t.cur.len) & (t.cur.s[spaces] = ' ') DO INC(spaces) END;
       FOR i := 0 TO spaces - 1 DO L.s[i] := ' ' END
@@ -268,8 +285,7 @@ BEGIN t.MaybeRemoveIndent; L := NewLine(); spaces := 0;
         L.s[i + spaces] := t.cur.s[i + t.x]
       END
     END;
-    L.len := t.cur.len + spaces - t.x;
-    t.cur.s[t.x] := 0X; t.cur.len := t.x;
+    L.len := t.cur.len + spaces - t.x; t.cur.s[t.x] := 0X; t.cur.len := t.x;
     IF t.cur.next # NIL THEN t.cur.next.prev := L END;
     L.next := t.cur.next; L.prev := t.cur; t.cur.next := L;
     IF t.last = t.cur THEN t.last := L END;
@@ -279,12 +295,13 @@ BEGIN t.MaybeRemoveIndent; L := NewLine(); spaces := 0;
 END HandleEnter;
 
 PROCEDURE (t: Text) InsertChar*(ch: CHAR), NEW;
-BEGIN t.cur.InsertChar(ch, t.x); INC(t.x); t.changed := TRUE
+BEGIN t.newLineCreated := FALSE;
+  t.cur.InsertChar(ch, t.x); INC(t.x); t.changed := TRUE
 END InsertChar;
 
 PROCEDURE (t: Text) Insert*(s: ARRAY OF CHAR; autoIndent: BOOLEAN), NEW;
 VAR i: INTEGER;
-BEGIN
+BEGIN t.newLineCreated := FALSE;
   i := 0;
   WHILE (i < LEN(s)) & (s[i] # 0X) DO
     IF s[i] = 0AX THEN (* Line Feed *)
@@ -301,7 +318,8 @@ BEGIN t.cur := NewLine(); t.first := t.cur;
   t.last := t.cur; t.scrFirst := t.cur;
   t.x := 0; t.y := 0;
   t.selected := FALSE;
-  t.changed := TRUE
+  t.changed := TRUE;
+  t.newLineCreated := FALSE
 END Clear;
 
 PROCEDURE (t: Text) CopySelection*(VAR buf: ARRAY OF CHAR), NEW;

+ 15 - 11
src/OV.Mod

@@ -2377,13 +2377,17 @@ BEGIN t := p.tabIndex; next := NIL;
   END ;
 RETURN next END FindNextTabControl;
 
-PROCEDURE OnTabPress(app: App; back: BOOLEAN);
+PROCEDURE OnTabPress(app: App; back: BOOLEAN): BOOLEAN;
 VAR p: Control;
-BEGIN p := app.cur;
+  worked: BOOLEAN;
+BEGIN worked := FALSE; p := app.cur;
   IF p # NIL THEN p := FindNextTabControl(p, back);
-    IF p # NIL THEN SetAppFocus(app, p) END
-  END
-END OnTabPress;
+    IF (p # NIL) & (p # app.cur) THEN
+      SetAppFocus(app, p);
+      worked := TRUE
+    END
+  END ;
+RETURN worked END OnTabPress;
 
 PROCEDURE OnKeyDown(app: App; key: G.Key);
 VAR handled: BOOLEAN; p: Control;
@@ -2399,13 +2403,13 @@ BEGIN handled := FALSE; p := app.cur;
   IF ~handled THEN
     IF (key.code = G.kEnter) & (key.mod * G.mAlt # {}) THEN
       T.ToggleFullscreen
-    ELSIF (p # NIL) & (key.code = G.kTab) THEN
-      OnTabPress(app, key.mod * G.mShift # {})
     ELSIF p # NIL THEN
-      IF p.do.keyDown # NIL THEN p.do.keyDown(p, key) END;
-      IF (p.parent # NIL) & (p.parent IS Window) &
-         (p.parent.do.keyDown # NIL) THEN
-        p.parent.do.keyDown(p.parent, key)
+      IF (key.code # G.kTab) OR ~OnTabPress(app, key.mod * G.mShift # {}) THEN
+        IF p.do.keyDown # NIL THEN p.do.keyDown(p, key) END;
+        IF (p.parent # NIL) & (p.parent IS Window) &
+           (p.parent.do.keyDown # NIL) THEN
+          p.parent.do.keyDown(p.parent, key)
+        END
       END
     END
   END

+ 12 - 11
src/Strings.Mod

@@ -89,18 +89,19 @@ BEGIN
   Insert(source, pos, dest)
 END Replace;
 
-PROCEDURE Extract*(IN source: ARRAY OF CHAR; pos, n: INTEGER; VAR dest: ARRAY OF CHAR);
+PROCEDURE Extract*(IN source: ARRAY OF CHAR; pos, n: INTEGER;
+    VAR dest: ARRAY OF CHAR);
 VAR len, destLen, i: INTEGER;
-BEGIN
-  len := Length(source); destLen := LEN(dest) - 1;
-  IF pos < 0 THEN pos := 0 END;
-  IF pos >= len THEN dest[0] := 0X; RETURN END;
-  i := 0;
-  WHILE (pos + i <= LEN(source)) & (source[pos + i] # 0X) & (i < n) DO
-    IF i < destLen THEN dest[i] := source[pos + i] END;
-    INC(i)
-  END;
-  dest[i] := 0X
+BEGIN len := Length(source);
+  IF pos < 0 THEN pos := 0 ELSIF pos >= len THEN dest[0] := 0X
+  ELSE i := 0; destLen := LEN(dest) - 1;
+    IF n >= destLen THEN n := destLen - 1 END;
+    WHILE (pos + i <= len) & (source[pos + i] # 0X) & (i < n) DO
+      IF i < destLen THEN dest[i] := source[pos + i] END;
+      INC(i)
+    END;
+    dest[i] := 0X
+  END
 END Extract;
 
 PROCEDURE Pos*(IN pattern, s: ARRAY OF CHAR; pos: INTEGER): INTEGER;