MODULE editor; (* based on the kilo editor building course*) (* Step 21 *) (*** IMPORTS ***) IMPORT IO, termios, FIO, libc, CharClass, NumberIO, ASCII ; IMPORT STextIO, Strings; (*** data ***) VAR c : CHAR; theTermios : termios.TERMIOS; TCSAFLUSH : INTEGER; i : CARDINAL; (*** Terminal ***) PROCEDURE CtrlKey(c: CHAR) : CARDINAL; VAR n : BITSET; BEGIN n := BITSET(ORD(c)); n := n * BITSET(1FH); RETURN CARDINAL(n) END CtrlKey; PROCEDURE die (s : ARRAY OF CHAR); BEGIN libc.perror(s); FOR i := 0 TO Strings.Length(s) DO IO.Write(s[i]) END; HALT END die; PROCEDURE disablerawMode() : INTEGER; VAR result : INTEGER; BEGIN IO.BufferedMode(0,TRUE); IO.BufferedMode(1,TRUE); result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, theTermios); IF result = -1 THEN theTermios := termios.KillTermios(theTermios); die("tcsetattr") ELSE RETURN result END; END disablerawMode; PROCEDURE enablerawMode; BEGIN libc.atexit(disablerawMode); theTermios := termios.InitTermios(); IF termios.tcgetattr(FIO.StdIn, theTermios) = -1 THEN die("tcgetattr") END; IO.UnBufferedMode(0,TRUE); IO.UnBufferedMode(1,TRUE); END enablerawMode; PROCEDURE editorReadKey() : CHAR; VAR c : CHAR; BEGIN IO.Read(c); RETURN c END editorReadKey; (*** Input ***) PROCEDURE editorProcessKeypress; VAR c : CHAR; BEGIN c := editorReadKey(); CASE ORD(c) OF 17 : HALT; END END editorProcessKeypress; (*** Init ***) BEGIN TCSAFLUSH := termios.tcsflush (); enablerawMode; LOOP editorProcessKeypress; END; END editor.