editor.mod 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. MODULE editor;
  2. (* based on the kilo editor building course*)
  3. (* Step 22 *)
  4. (*** IMPORTS ***)
  5. IMPORT IO, termios, FIO, libc, CharClass, NumberIO, ASCII ;
  6. IMPORT STextIO, Strings, SYSTEM;
  7. (*** data ***)
  8. CONST
  9. clearScreenStrLen = 4;
  10. cursorHomeStrLen = 3;
  11. VAR
  12. c : CHAR;
  13. theTermios : termios.TERMIOS;
  14. TCSAFLUSH : INTEGER;
  15. i : CARDINAL;
  16. (* escape sequences *)
  17. clearScreenStr : ARRAY[0..3] OF CHAR;
  18. cursorHomeStr : ARRAY[0..2] OF CHAR;
  19. (* escape sequences length *)
  20. (*** Terminal ***)
  21. PROCEDURE CtrlKey(c: CHAR) : CARDINAL;
  22. VAR
  23. n : BITSET;
  24. BEGIN
  25. n := BITSET(ORD(c));
  26. n := n * BITSET(1FH);
  27. RETURN CARDINAL(n)
  28. END CtrlKey;
  29. PROCEDURE die (s : ARRAY OF CHAR);
  30. BEGIN
  31. libc.perror(s);
  32. FOR i := 0 TO Strings.Length(s) DO
  33. IO.Write(s[i])
  34. END;
  35. HALT
  36. END die;
  37. PROCEDURE disablerawMode() : INTEGER;
  38. VAR
  39. result : INTEGER;
  40. BEGIN
  41. IO.BufferedMode(0,TRUE);
  42. IO.BufferedMode(1,TRUE);
  43. result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, theTermios);
  44. IF result = -1 THEN
  45. theTermios := termios.KillTermios(theTermios);
  46. die("tcsetattr")
  47. ELSE
  48. RETURN result
  49. END;
  50. END disablerawMode;
  51. PROCEDURE enablerawMode;
  52. BEGIN
  53. libc.atexit(disablerawMode);
  54. theTermios := termios.InitTermios();
  55. IF termios.tcgetattr(FIO.StdIn, theTermios) = -1 THEN
  56. die("tcgetattr")
  57. END;
  58. IO.UnBufferedMode(0,TRUE);
  59. IO.UnBufferedMode(1,TRUE);
  60. END enablerawMode;
  61. PROCEDURE editorReadKey() : CHAR;
  62. VAR
  63. c : CHAR;
  64. BEGIN
  65. IO.Read(c);
  66. RETURN c
  67. END editorReadKey;
  68. PROCEDURE editorProcessKeypress;
  69. VAR
  70. c : CHAR;
  71. BEGIN
  72. c := editorReadKey();
  73. CASE ORD(c) OF
  74. 17 : HALT;
  75. END
  76. END editorProcessKeypress;
  77. (*** Output ***)
  78. PROCEDURE editorRefreshScreen;
  79. BEGIN
  80. (* libc.write(FIO.StdOut,SYSTEM.ADR(cursorHomeStr), cursorHomeStrLen); *)
  81. libc.write(FIO.StdOut,SYSTEM.ADR(clearScreenStr), clearScreenStrLen);
  82. END editorRefreshScreen;
  83. (*** Input ***)
  84. (*** Init ***)
  85. PROCEDURE InitScreenEscapes;
  86. VAR temp : ARRAY[0..10] OF CHAR;
  87. BEGIN
  88. cursorHomeStr := "";
  89. Strings.Concat(cursorHomeStr,ASCII.esc,cursorHomeStr);
  90. Strings.Concat(cursorHomeStr,"[H",cursorHomeStr);
  91. clearScreenStr := "";
  92. Strings.Concat(clearScreenStr,ASCII.esc,clearScreenStr);
  93. Strings.Concat(clearScreenStr,"[2J",clearScreenStr);
  94. END InitScreenEscapes;
  95. BEGIN
  96. InitScreenEscapes;
  97. TCSAFLUSH := termios.tcsflush ();
  98. enablerawMode;
  99. editorRefreshScreen;
  100. LOOP
  101. editorProcessKeypress;
  102. editorRefreshScreen;
  103. END;
  104. END editor.