home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 10
/
Fresh_Fish_10_2352.bin
/
new
/
dev
/
obero
/
oberon
/
system
/
xe.mod
(
.txt
)
< prev
next >
Wrap
Oberon Text
|
1995-05-17
|
51KB
|
1,090 lines
Syntax10.Scn.Fnt
Syntax10i.Scn.Fnt
StampElems
Alloc
17 May 95
Syntax12i.Scn.Fnt
FoldElems
LineElems
Alloc
Syntax10b.Scn.Fnt
Syntax10i.Scn.Fnt
(* code for all Oberons without the object model (all except HP, DEC, SGI) *)
MODULE XE; (** SHML (ludwig@inf.ethz.ch) 10 Dec 90;
(* eXtended Edit: Supports various enhancements over usual TextFrames.Handle for programmer's purposes *)
(* Declarations *)
IMPORT Modules, Display, Input, Files, Fonts, Texts, Viewers, Oberon, TextFrames, MenuViewers, FoldElems;
CONST
GetHandlerKey* = -210566; (** secret number to get XE.Handle **)
DefErrFile = "OberonErrors.Text"; ErrFont = "Syntax8.Scn.Fnt";
ML = 2; MM = 1; MR = 0;
WordBoundary = 0; NameBoundary = 1; FileNameBoundary = 2; (* type for WordBounds checking *)
CtrlB = 2X; CtrlD = 4X; CtrlE = 5X; CtrlF = 6X; BS = 08X; LF = 0AX; CtrlK = 0BX; CR = 0DX; CtrlN = 0EX;
CtrlP = 10X; CtrlT = 14X; CtrlW = 17X; CtrlX = 18X; CtrlZ = 1AX;
UpArrow = 0C1X; DnArrow = 0C2X;
MaxPat = 32;
OptionChar1 = "/"; OptionChar2 = "\"; (* character used by host Oberon System for introducing options *)
Version = "XE (SHML 23 Mar 95)";
XEMenu = "XE.Menu.Text"; EditMenu = "Edit.Menu.Text"; SystemMenu = "System.Menu.Text";
ConfigurationName = "XE.Configuration.Text";
KeyHandler = "EditKeys.GetKeyHandler";
DefComp = "Compiler.Compile"; (* default compiler command *)
DefOpenCmd = "Doc.Open"; DefOpenCmd1 = "XE.Open"; (* commands used by OpenCall *)
Empty0 = "Empty.Mod"; Empty1 = "Empty.Tool"; Empty3 = "Empty.c"; (* default empty files for Defaults *)
Ext00 = "Mod"; Ext01 = "Text"; Ext1 = "Tool"; Ext30 = "c"; Ext31 = "h"; (* default file extensions for Defaults *)
AsciiFont = "Courier10.Scn.Fnt"; (* used by OpenAscii for displaying ascii texts *)
TYPE
LongName = ARRAY 128 OF CHAR;
Name = ARRAY 32 OF CHAR;
Elem = POINTER TO ElemDesc;
ElemDesc = RECORD (Texts.ElemDesc)
err: INTEGER;
pos: LONGINT;
wide: BOOLEAN;
num: ARRAY 8 OF CHAR;
msg: LongName
END;
Element = POINTER TO ElementDesc;
ElementDesc = RECORD
compiler, ext: Name; errFile: LongName;
next: Element
END;
wr: Texts.Writer;
errT: Texts.Text; errFnt: Fonts.Font;
keyHandle: Display.Handler;
compiler, defComp, openCmd: Name;
empty: ARRAY 4 OF Name;
ext: ARRAY 4, 2 OF Name;
first: BOOLEAN; delay: LONGINT;
root: Element;
find: RECORD
len: SHORTINT;
buf: ARRAY MaxPat OF CHAR;
shiftTab: ARRAY 256 OF SHORTINT
END;
(* Support *)
PROCEDURE Str(s: ARRAY OF CHAR); BEGIN Texts.WriteString(wr, s) END Str;
PROCEDURE Ch(ch: CHAR); BEGIN Texts.Write(wr, ch) END Ch;
PROCEDURE Ln; BEGIN Texts.WriteLn(wr); Texts.Append(Oberon.Log, wr.buf) END Ln;
PROCEDURE Extension(name: ARRAY OF CHAR; VAR ext: ARRAY OF CHAR); (* get extension of name *)
VAR i, j: INTEGER;
BEGIN
i := -1;
REPEAT INC(i) UNTIL name[i] = 0X;
REPEAT DEC(i) UNTIL (name[i] = ".") OR (i = 0);
IF i = 0 THEN ext[0] := 0X
ELSE
j := -1;
REPEAT INC(i); INC(j); ext[j] := name[i] UNTIL name[i] = 0X
END
END Extension;
PROCEDURE Append(src: ARRAY OF CHAR; VAR dest: ARRAY OF CHAR); (* append src to dest if no "." in src *)
VAR i, off: INTEGER;
BEGIN
off := -1;
REPEAT INC(off) UNTIL (dest[off] = 0X) OR (dest[off] = ".");
IF dest[off] # "." THEN
i := -1;
REPEAT INC(i); dest[i+off] := src[i] UNTIL src[i] = 0X END
END Append;
PROCEDURE SearchPair(ext: ARRAY OF CHAR; VAR prev: Element): Element;
VAR l: Element;
BEGIN
l := root; prev := NIL;
WHILE (l # NIL) & (l.ext # ext) DO prev := l; l := l.next END;
RETURN l
END SearchPair;
PROCEDURE ScanFirst(VAR s: Texts.Scanner); (* Scan first parameter *)
VAR sel: Texts.Text; beg, end, time: LONGINT;
BEGIN
Texts.OpenScanner(s, Oberon.Par.text, Oberon.Par.pos); 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
END ScanFirst;
PROCEDURE InstallKeyHandler;
VAR save, par: Oberon.ParList; res: INTEGER;
BEGIN
save := Oberon.Par;
NEW(par); NEW(par.frame); par.frame.X := 0; par.frame.Y := 0; par.pos := -42; (* magic *)
Oberon.Call(KeyHandler, par, FALSE, res);
IF res = 0 THEN keyHandle := Oberon.Par.frame.handle
ELSE keyHandle := NIL
END;
Oberon.Par := save; Modules.res := 0 (* bug in Modules? *)
END InstallKeyHandler;
PROCEDURE OpenText(VAR t: Texts.Text; VAR name: ARRAY OF CHAR;
s: Texts.Scanner; default, ext1, ext2: ARRAY OF CHAR);
VAR extName: LongName; i, len: INTEGER;
PROCEDURE Extend(VAR str: ARRAY OF CHAR; with: ARRAY OF CHAR); (* extend str with with *)
VAR ls, le: INTEGER;
BEGIN
ls := -1;
REPEAT INC(ls) UNTIL str[ls] = 0X;
le := -1;
REPEAT INC(le) UNTIL with[le] = 0X;
IF ls <= LEN(str)-(le+1) THEN
INC(ls, le+1);
REPEAT str[ls] := with[le]; DEC(ls); DEC(le) UNTIL le = -1;
str[ls] := "."
END
END Extend;
PROCEDURE Try(): BOOLEAN; (* try opening name with ext1 or ext2 appended to it *)
BEGIN
COPY(name, extName); Extend(extName, ext1); t := TextFrames.Text(extName);
IF t.len = 0 THEN COPY(name, extName); Extend(extName, ext2); t := TextFrames.Text(extName) END;
RETURN t.len > 0
END Try;
BEGIN
IF first THEN first := FALSE; Str(Version); Ln; InstallKeyHandler END; (* write a startup message to the Log (once) *)
find.len := 0;
IF s.class = Texts.String THEN
t := TextFrames.Text(s.s);
name[0] := '"'; i := 0;
REPEAT INC(i); name[i] := s.s[i-1] UNTIL name[i] = 0X;
name[i] := '"'; name[i+1] := 0X
ELSIF s.class # Texts.Name THEN t := TextFrames.Text(default); COPY(default, name)
ELSE
COPY(s.s, name); t := TextFrames.Text(name); (* use original name *)
IF t.len = 0 THEN (* name doesn't exist *)
IF Try() THEN COPY(extName, name) (* use extended name *)
ELSE
len := s.len;
REPEAT DEC(len) UNTIL (name[len] = ".") OR (len = 0);
IF len # 0 THEN (* name[len] = "." *)
i := -1; (* copy appended name to pattern for Edit.Show *)
REPEAT INC(i); find.buf[i] := name[i+len+1] UNTIL find.buf[i] = 0X;
find.len := SHORT(i);
name[len] := 0X; (* delete extension, try with trimmed name *)
IF Try() THEN COPY(extName, name) (* use extended name *)
ELSE COPY(s.s, name) (* use original name with empty text *)
END
END
END
END
END
END OpenText;
PROCEDURE Show(f: TextFrames.Frame; pos: LONGINT);
VAR end, delta: LONGINT;
BEGIN
delta := 200; end := TextFrames.Pos(f, f.X+f.W, f.Y);
WHILE ((f.org > pos) OR (pos >= end)) & (f.org # end) DO
TextFrames.Show(f, pos-delta); DEC(delta, 20);
end := TextFrames.Pos(f, f.X+f.W, f.Y)
END
END Show;
PROCEDURE GetOptions(VAR s: Texts.Scanner; VAR options: ARRAY OF CHAR);
VAR pos: LONGINT; i: INTEGER; ch: CHAR; r: Texts.Reader;
BEGIN
IF (s.class # Texts.Char) OR (s.c # OptionChar1) & (s.c # OptionChar2) THEN options[0] := 0X
ELSE
pos := Texts.Pos(s);
options[0] := s.c; ch := s.nextCh; i := 1; r := s;
WHILE ((ch >= "0") & (ch <= "9") OR (ch >= "a") & (ch <= "z")) & (i < LEN(options)-1) DO
options[i] := ch; INC(i); Texts.Read(r, ch)
END;
options[i] := 0X; pos := pos+(i-1);
WHILE Texts.Pos(s) < pos DO Texts.Scan(s) END; Texts.Scan(s)
END
END GetOptions;
PROCEDURE MenuFrame(name, menu: ARRAY OF CHAR; line: INTEGER): TextFrames.Frame;
(* open XEMenu/EditMenu/SystemMenu and if existant get lineth textline (counting starts with 0) as menuline; (line >= 0, 100) *)
VAR
mf: TextFrames.Frame; buf: Texts.Buffer; t: Texts.Text;
r: Texts.Reader; start, end: LONGINT; ch: CHAR; menuFile: LongName;
BEGIN
ASSERT(line >= 0, 100);
IF Files.Old(XEMenu) # NIL THEN menuFile := XEMenu
ELSIF (line = 1) & (Files.Old(SystemMenu) # NIL) THEN menuFile := SystemMenu
ELSIF Files.Old(EditMenu) # NIL THEN menuFile := EditMenu
ELSE RETURN TextFrames.NewMenu(name, menu)
END;
NEW(t); Texts.Open(t, menuFile);
Texts.OpenReader(r, t, 0);
REPEAT (* skip line lines *)
start := Texts.Pos(r);
REPEAT Texts.Read(r, ch) UNTIL r.eot OR (ch = 0DX);
DEC(line)
UNTIL line = -1;
IF r.eot THEN end := t.len ELSE end := Texts.Pos(r)-1