editor.mod 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. MODULE editor;
  2. (* based on the kilo editor building course*)
  3. (* Step 24 *)
  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.write(FIO.StdOut,SYSTEM.ADR(cursorHomeStr), cursorHomeStrLen);
  32. libc.write(FIO.StdOut,SYSTEM.ADR(clearScreenStr), clearScreenStrLen);
  33. libc.perror(s);
  34. FOR i := 0 TO Strings.Length(s) DO
  35. IO.Write(s[i])
  36. END;
  37. HALT
  38. END die;
  39. PROCEDURE disablerawMode() : INTEGER;
  40. VAR
  41. result : INTEGER;
  42. BEGIN
  43. IO.BufferedMode(0,TRUE);
  44. IO.BufferedMode(1,TRUE);
  45. result := termios.tcsetattr(FIO.StdIn, TCSAFLUSH, theTermios);
  46. IF result = -1 THEN
  47. theTermios := termios.KillTermios(theTermios);
  48. die("tcsetattr")
  49. ELSE
  50. RETURN result
  51. END;
  52. END disablerawMode;
  53. PROCEDURE enablerawMode;
  54. BEGIN
  55. libc.atexit(disablerawMode);
  56. theTermios := termios.InitTermios();
  57. IF termios.tcgetattr(FIO.StdIn, theTermios) = -1 THEN
  58. die("tcgetattr")
  59. END;
  60. IO.UnBufferedMode(0,TRUE);
  61. IO.UnBufferedMode(1,TRUE);
  62. END enablerawMode;
  63. PROCEDURE editorReadKey() : CHAR;
  64. VAR
  65. c : CHAR;
  66. BEGIN
  67. IO.Read(c);
  68. RETURN c
  69. END editorReadKey;
  70. PROCEDURE editorProcessKeypress;
  71. VAR
  72. c : CHAR;
  73. BEGIN
  74. c := editorReadKey();
  75. CASE ORD(c) OF
  76. 17 : libc.write(FIO.StdOut,SYSTEM.ADR(cursorHomeStr), cursorHomeStrLen);
  77. libc.write(FIO.StdOut,SYSTEM.ADR(clearScreenStr), clearScreenStrLen);
  78. HALT;
  79. END
  80. END editorProcessKeypress;
  81. (*** Output ***)
  82. PROCEDURE editorRefreshScreen;
  83. BEGIN
  84. libc.write(FIO.StdOut,SYSTEM.ADR(cursorHomeStr), cursorHomeStrLen);
  85. libc.write(FIO.StdOut,SYSTEM.ADR(clearScreenStr), clearScreenStrLen);
  86. END editorRefreshScreen;
  87. (*** Input ***)
  88. (*** Init ***)
  89. PROCEDURE InitScreenEscapes;
  90. VAR temp : ARRAY[0..10] OF CHAR;
  91. BEGIN
  92. cursorHomeStr := "";
  93. Strings.Concat(cursorHomeStr,ASCII.esc,cursorHomeStr);
  94. Strings.Concat(cursorHomeStr,"[H",cursorHomeStr);
  95. clearScreenStr := "";
  96. Strings.Concat(clearScreenStr,ASCII.esc,clearScreenStr);
  97. Strings.Concat(clearScreenStr,"[2J",clearScreenStr);
  98. END InitScreenEscapes;
  99. BEGIN
  100. InitScreenEscapes;
  101. TCSAFLUSH := termios.tcsflush ();
  102. enablerawMode;
  103. editorRefreshScreen;
  104. LOOP
  105. editorProcessKeypress;
  106. editorRefreshScreen;
  107. END;
  108. END editor.