| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- MODULE editor;
- (* based on the kilo editor building course*)
- (* Step 26 *)
- (*** IMPORTS ***)
- IMPORT IO, termios, FIO, libc, CharClass, NumberIO, ASCII ;
- IMPORT STextIO, Strings, SYSTEM;
- (*** data ***)
- CONST
- clearScreenStrLen = 4;
- cursorHomeStrLen = 3;
- tildeStrLen = 3;
- VAR
- editorConfig : RECORD
- theTermios : termios.TERMIOS;
- END;
- c : CHAR;
- TCSAFLUSH : INTEGER;
- i : CARDINAL;
- (* escape sequences *)
- clearScreenStr : ARRAY[0..3] OF CHAR;
- cursorHomeStr : ARRAY[0..2] OF CHAR;
- tildeStr : ARRAY[0..2] OF CHAR;
- (* escape sequences length *)
- (*** 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.write(FIO.StdOut,SYSTEM.ADR(cursorHomeStr), cursorHomeStrLen);
- libc.write(FIO.StdOut,SYSTEM.ADR(clearScreenStr), clearScreenStrLen);
- 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, editorConfig.theTermios);
- IF result = -1 THEN
- editorConfig.theTermios := termios.KillTermios(editorConfig.theTermios);
- die("tcsetattr")
- ELSE
- RETURN result
- END;
- END disablerawMode;
- PROCEDURE enablerawMode;
- BEGIN
- libc.atexit(disablerawMode);
- editorConfig.theTermios := termios.InitTermios();
- IF termios.tcgetattr(FIO.StdIn, editorConfig.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;
-
- PROCEDURE editorProcessKeypress;
- VAR
- c : CHAR;
- BEGIN
- c := editorReadKey();
- CASE ORD(c) OF
- 17 : libc.write(FIO.StdOut,SYSTEM.ADR(cursorHomeStr), cursorHomeStrLen);
- libc.write(FIO.StdOut,SYSTEM.ADR(clearScreenStr), clearScreenStrLen);
- HALT;
- END
- END editorProcessKeypress;
- (*** Output ***)
-
- PROCEDURE editorDrawRows;
- VAR
- y : CARDINAL;
-
- BEGIN
- FOR y := 1 TO 24 DO
- libc.write(FIO.StdOut,SYSTEM.ADR(tildeStr), tildeStrLen);
- END;
- END editorDrawRows;
- PROCEDURE editorRefreshScreen;
- BEGIN
- libc.write(FIO.StdOut,SYSTEM.ADR(cursorHomeStr), cursorHomeStrLen);
- libc.write(FIO.StdOut,SYSTEM.ADR(clearScreenStr), clearScreenStrLen);
- editorDrawRows;
- libc.write(FIO.StdOut,SYSTEM.ADR(cursorHomeStr), cursorHomeStrLen);
- END editorRefreshScreen;
- (*** Input ***)
- (*** Init ***)
- PROCEDURE InitScreenEscapes;
- VAR temp : ARRAY[0..10] OF CHAR;
- BEGIN
- cursorHomeStr := "";
- Strings.Concat(cursorHomeStr,ASCII.esc,cursorHomeStr);
- Strings.Concat(cursorHomeStr,"[H",cursorHomeStr);
- clearScreenStr := "";
- Strings.Concat(clearScreenStr,ASCII.esc,clearScreenStr);
- Strings.Concat(clearScreenStr,"[2J",clearScreenStr);
- tildeStr[0] := "~";
- tildeStr[1] := CHR(13);
- tildeStr[2] := CHR(10);
- END InitScreenEscapes;
- BEGIN
- InitScreenEscapes;
- TCSAFLUSH := termios.tcsflush ();
- enablerawMode;
- editorRefreshScreen;
- LOOP
- editorProcessKeypress;
- editorRefreshScreen;
- END;
- END editor.
|