MODULE editor; (* based on the kilo editor building course*) (* Step 24 *) (******************** INCLUDES ******************) IMPORT FIO, SYSTEM, termios, STextIO, NumberIO; IMPORT CharClass, STextIO, libc, ASCII; IMPORT Strings, errno; (******************** DATA ******************) VAR c : CHAR; p : POINTER TO CHAR; thetermios : termios.TERMIOS; raw : termios.TERMIOS; result : INTEGER; number : CARDINAL; (* testing *) test : BOOLEAN; clearScreen : ARRAY[0..6] OF CHAR; (******************** 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); STextIO.WriteString(clearScreen); HALT END die; PROCEDURE disableRawMode(): INTEGER; VAR TCSAFLUSH : INTEGER; result : INTEGER; BEGIN TCSAFLUSH := termios.tcsflush (); IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios) = -1 THEN die("tcsetattr") END; RETURN result; END disableRawMode; PROCEDURE enableRawMode; VAR TCSAFLUSH : INTEGER; result : INTEGER; bresult : BOOLEAN; BEGIN TCSAFLUSH := termios.tcsflush (); libc.atexit(disableRawMode); bresult := termios.SetFlag(raw,termios.icrnl, FALSE); bresult := termios.SetFlag(raw,termios.ixon, FALSE); bresult := termios.SetFlag(raw,termios.lecho, FALSE); bresult := termios.SetFlag(raw,termios.opost, FALSE); bresult := termios.SetFlag(raw,termios.licanon, FALSE); bresult := termios.SetFlag(raw,termios.liexten, FALSE); bresult := termios.SetFlag(raw,termios.lisig, FALSE); bresult := termios.SetFlag(raw,termios.ibrkint, FALSE); bresult := termios.SetFlag(raw,termios.inpck, FALSE); bresult := termios.SetFlag(raw,termios.istrip, FALSE); bresult := termios.SetFlag(raw,termios.cs8, TRUE); IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, raw) = -1 THEN die("tcsetattr") END; (* PROCEDURE SetChar (t: TERMIOS; c: ControlChar; ch: CHAR) : BOOLEAN ; *) (* termios.vmin := 0; termios.vtime := 1; *) bresult := termios.SetChar(raw,termios.vmin,CHR(0)); bresult := termios.SetChar(raw,termios.vtime,CHR(1)); END enableRawMode; PROCEDURE editorReadKey() : CHAR; VAR c : CHAR; nread : INTEGER; BEGIN p := SYSTEM.ADR(c); WHILE FIO.ReadNBytes(FIO.StdIn,1,p) <> 1 DO ; END; RETURN c END editorReadKey; (******************** output ******************) PROCEDURE editorRefreshScreen; BEGIN STextIO.WriteString(clearScreen) END editorRefreshScreen; (******************** input ******************) PROCEDURE editorProcessKeypress; VAR c : CHAR; b : BOOLEAN; BEGIN c := editorReadKey(); CASE ORD(c) OF 17 : HALT; END END editorProcessKeypress; (******************** INIT ******************) PROCEDURE InitClearScreen; BEGIN clearScreen := ""; Strings.Concat(clearScreen,ASCII.esc,clearScreen); Strings.Concat(clearScreen,"[2J",clearScreen); Strings.Concat(clearScreen,ASCII.esc,clearScreen); Strings.Concat(clearScreen,"[H",clearScreen); END InitClearScreen; BEGIN InitClearScreen; thetermios := termios.InitTermios(); raw := termios.InitTermios(); IF termios.tcgetattr(FIO.StdIn, thetermios) = -1 THEN die("tcgetattr") END; IF termios.tcgetattr(FIO.StdIn, raw) = -1 THEN die("tcgetattr") END; enableRawMode; LOOP editorRefreshScreen; editorProcessKeypress; editorRefreshScreen; END; END editor.