Syntax10.Scn.Fnt Syntax10i.Scn.Fnt StampElems Alloc 2 May 95 Syntax10b.Scn.Fnt Syntax12b.Scn.Fnt PopupElems Alloc Macro Syntax10.Scn.Fnt Macro.Record 0 Macro.Play 0 Macro.Play 0 2 Macro.Play 0 3 Macro.Play 0 4 Macro.Play 0 8 Macro.Play 0 ^ _______________________________________ Macro.Record 1 Macro.Play 1 Macro.Play 1 2 Macro.Play 1 3 Macro.Play 1 4 Macro.Play 1 8 Macro.Play 1 ^ MODULE Macro; (** SHML 21 Jul 92, IMPORT Input, Texts, TF := TextFrames, Oberon; CONST (* understood by XE editor *) CtrlB = 2X; CtrlD = 4X; CtrlE = 5X; CtrlF = 6X; BS = 8X; TAB = 9X; LF = 0AX; CtrlK = 0BX; CR = 0DX; CtrlN = 0EX; CtrlP = 10X; CtrlT = 14X; CtrlW = 17X; CtrlX = 18X; CtrlZ = 1AX; Legal = {ORD(CtrlB), ORD(CtrlD), ORD(CtrlE), ORD(CtrlF), ORD(BS), ORD(TAB), ORD(LF), ORD(CtrlK), ORD(CR), ORD(CtrlN), ORD(CtrlP), ORD(CtrlT), ORD(CtrlW), ORD(CtrlX), ORD(CtrlZ)}; CtrlS = 13X; CtrlC = 3X; CtrlV = 16X; CtrlQ = 11X; (* start/cut selection, copy, paste, end macro *) VAR macro: ARRAY 8, 256 OF CHAR; PROCEDURE Interpret(f: TF.Frame; msg: Oberon.InputMsg; ch: CHAR; VAR start: LONGINT; buf: Texts.Buffer); VAR end: LONGINT; buf1: Texts.Buffer; BEGIN IF (ch >= " ") OR (ORD(ch) IN Legal) THEN msg.ch := ch; f.handle(f, msg) ELSIF (ch = CtrlS) & (start < 0) THEN start := f.carloc.pos ELSIF (ch = CtrlS) OR (ch = CtrlC) THEN IF start >= 0 THEN end := f.carloc.pos; IF end < start THEN end := start; start := f.carloc.pos END; Texts.Save(f.text, start, end, buf); IF ch = CtrlS THEN Texts.Delete(f.text, start, end); TF.SetCaret(f, start) END; start := -1 END ELSIF ch = CtrlV THEN end := f.carloc.pos+buf.len; NEW(buf1); Texts.OpenBuf(buf1); Texts.Copy(buf, buf1); Texts.Insert(f.text, f.carloc.pos, buf1); TF.SetCaret(f, end) END END Interpret; PROCEDURE Record*; (** n Start recording of keyboard macro n **) VAR s: Texts.Scanner; buf: Texts.Buffer; f: TF.Frame; msg: Oberon.InputMsg; n, i: INTEGER; start: LONGINT; ch: CHAR; BEGIN Texts.OpenScanner(s, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(s); IF (s.class = Texts.Int) & (s.i < LEN(macro, 0)) & (Oberon.FocusViewer.dsc.next IS TF.Frame) & Oberon.FocusViewer.dsc.next(TF.Frame).hasCar THEN f := Oberon.FocusViewer.dsc.next(TF.Frame); n := SHORT(s.i); NEW(buf); Texts.OpenBuf(buf); start := -1; msg.id := Oberon.consume; msg.fnt := Oberon.CurFnt; msg.col := Oberon.CurCol; msg.voff := Oberon.CurOff; Oberon.FadeCursor(Oberon.Mouse); i := 0; REPEAT REPEAT UNTIL Input.Available() > 0; Input.Read(ch); Interpret(f, msg, ch, start, buf); macro[n, i] := ch; INC(i) UNTIL (ch = CtrlQ) OR (i = LEN(macro, 1)-1); Oberon.DrawCursor(Oberon.Mouse, Oberon.Mouse.marker, Oberon.Mouse.X, Oberon.Mouse.Y); macro[n, i-1] := 0X; macro[n, i] := 0X END END Record; PROCEDURE Play*; (** n [rep] Playback keyboard macro n rep times **) VAR s: Texts.Scanner; sel: Texts.Text; beg, end, time: LONGINT; buf: Texts.Buffer; f: TF.Frame; msg: Oberon.InputMsg; n, rep, i: INTEGER; start: LONGINT; BEGIN Texts.OpenScanner(s, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(s); IF (s.class = Texts.Int) & (s.i < LEN(macro, 0)) & (Oberon.FocusViewer.dsc.next IS TF.Frame) & Oberon.FocusViewer.dsc.next(TF.Frame).hasCar THEN f := Oberon.FocusViewer.dsc.next(TF.Frame); n := SHORT(s.i); Texts.Scan(s); IF (s.class = Texts.Char) & (s.line = 0) & (s.c = "^") THEN Oberon.GetSelection(sel, beg, end, time); IF time >= 0 THEN Texts.OpenScanner(s, sel, beg); Texts.Scan(s) END END; IF (s.line = 0) & (s.class = Texts.Int) & (s.i > 0) THEN rep := SHORT(s.i) ELSE rep := 1 END; Oberon.FadeCursor(Oberon.Mouse); REPEAT NEW(buf); Texts.OpenBuf(buf); start := -1; msg.id := Oberon.consume; msg.fnt := Oberon.CurFnt; msg.col := Oberon.CurCol; msg.voff := Oberon.CurOff; Oberon.FadeCursor(Oberon.Mouse); i := 0; WHILE macro[n, i] # 0X DO Interpret(f, msg, macro[n, i], start, buf); INC(i) END; DEC(rep) UNTIL rep = 0; Oberon.DrawCursor(Oberon.Mouse, Oberon.Mouse.marker, Oberon.Mouse.X, Oberon.Mouse.Y) END END Play; END Macro.