|
|
@@ -0,0 +1,177 @@
|
|
|
+MODULE editor;
|
|
|
+
|
|
|
+(* based on the kilo editor building course*)
|
|
|
+
|
|
|
+(* Step 25 *)
|
|
|
+
|
|
|
+(******************** 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;
|
|
|
+ cursorHome : ARRAY[0..2] 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 editorDrawRows;
|
|
|
+
|
|
|
+ VAR
|
|
|
+ y : CARDINAL;
|
|
|
+
|
|
|
+ BEGIN
|
|
|
+ FOR y := 1 TO 24 DO
|
|
|
+ STextIO.WriteChar("~");
|
|
|
+ STextIO.WriteLn;
|
|
|
+ STextIO.WriteChar(CHR(13))
|
|
|
+ END;
|
|
|
+ END editorDrawRows;
|
|
|
+
|
|
|
+ PROCEDURE editorRefreshScreen;
|
|
|
+
|
|
|
+ BEGIN
|
|
|
+ STextIO.WriteString(clearScreen);
|
|
|
+ editorDrawRows;
|
|
|
+ STextIO.WriteString(cursorHome);
|
|
|
+ END editorRefreshScreen;
|
|
|
+
|
|
|
+(******************** input ******************)
|
|
|
+
|
|
|
+ PROCEDURE editorProcessKeypress;
|
|
|
+ VAR
|
|
|
+ c : CHAR;
|
|
|
+ b : BOOLEAN;
|
|
|
+ BEGIN
|
|
|
+ c := editorReadKey();
|
|
|
+ CASE ORD(c) OF
|
|
|
+ 17 : HALT;
|
|
|
+ END
|
|
|
+ END editorProcessKeypress;
|
|
|
+
|
|
|
+(******************** INIT ******************)
|
|
|
+
|
|
|
+PROCEDURE InitScreenEscapes;
|
|
|
+
|
|
|
+BEGIN
|
|
|
+ clearScreen := "";
|
|
|
+ Strings.Concat(clearScreen,ASCII.esc,clearScreen);
|
|
|
+ Strings.Concat(clearScreen,"[2J",clearScreen);
|
|
|
+ Strings.Concat(clearScreen,ASCII.esc,clearScreen);
|
|
|
+ Strings.Concat(clearScreen,"[H",clearScreen);
|
|
|
+ cursorHome := "";
|
|
|
+ Strings.Concat(cursorHome,ASCII.esc,cursorHome);
|
|
|
+ Strings.Concat(cursorHome,"[H",cursorHome);
|
|
|
+END InitScreenEscapes;
|
|
|
+
|
|
|
+BEGIN
|
|
|
+ InitScreenEscapes;
|
|
|
+
|
|
|
+ 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.
|