editor.mod 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. MODULE editor;
  2. (* based on the kilo editor building course*)
  3. (* Step 26 *)
  4. (******************** INCLUDES ******************)
  5. IMPORT FIO, SYSTEM, termios, STextIO, NumberIO;
  6. IMPORT CharClass, STextIO, libc, ASCII;
  7. IMPORT Strings, errno;
  8. (******************** DATA ******************)
  9. VAR
  10. c : CHAR;
  11. p : POINTER TO CHAR;
  12. result : INTEGER;
  13. number : CARDINAL;
  14. editorConfig : RECORD
  15. theThermios : termios.TERMIOS;
  16. raw : termios.TERMIOS;
  17. END;
  18. (* testing *)
  19. test : BOOLEAN;
  20. clearScreen : ARRAY[0..6] OF CHAR;
  21. cursorHome : ARRAY[0..2] OF CHAR;
  22. (******************** TERMINAL ******************)
  23. PROCEDURE CtrlKey(c: CHAR) : CARDINAL;
  24. VAR
  25. n : BITSET;
  26. BEGIN
  27. n := BITSET(ORD(c));
  28. n := n * BITSET(1FH);
  29. RETURN CARDINAL(n)
  30. END CtrlKey;
  31. PROCEDURE die (s : ARRAY OF CHAR);
  32. BEGIN
  33. libc.perror(s);
  34. STextIO.WriteString(clearScreen);
  35. HALT
  36. END die;
  37. PROCEDURE disablerawMode(): INTEGER;
  38. VAR
  39. TCSAFLUSH : INTEGER;
  40. result : INTEGER;
  41. BEGIN
  42. TCSAFLUSH := termios.tcsflush ();
  43. IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, editorConfig.theThermios) = -1 THEN
  44. die("tcsetattr")
  45. END;
  46. RETURN result;
  47. END disablerawMode;
  48. PROCEDURE enablerawMode;
  49. VAR
  50. TCSAFLUSH : INTEGER;
  51. result : INTEGER;
  52. bresult : BOOLEAN;
  53. BEGIN
  54. TCSAFLUSH := termios.tcsflush ();
  55. libc.atexit(disablerawMode);
  56. bresult := termios.SetFlag(editorConfig.raw,termios.icrnl, FALSE);
  57. bresult := termios.SetFlag(editorConfig.raw,termios.ixon, FALSE);
  58. bresult := termios.SetFlag(editorConfig.raw,termios.lecho, FALSE);
  59. bresult := termios.SetFlag(editorConfig.raw,termios.opost, FALSE);
  60. bresult := termios.SetFlag(editorConfig.raw,termios.licanon, FALSE);
  61. bresult := termios.SetFlag(editorConfig.raw,termios.liexten, FALSE);
  62. bresult := termios.SetFlag(editorConfig.raw,termios.lisig, FALSE);
  63. bresult := termios.SetFlag(editorConfig.raw,termios.ibrkint, FALSE);
  64. bresult := termios.SetFlag(editorConfig.raw,termios.inpck, FALSE);
  65. bresult := termios.SetFlag(editorConfig.raw,termios.istrip, FALSE);
  66. bresult := termios.SetFlag(editorConfig.raw,termios.cs8, TRUE);
  67. IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, editorConfig.raw) = -1 THEN
  68. die("tcsetattr")
  69. END;
  70. (* PROCEDURE SetChar (t: TERMIOS; c: ControlChar; ch: CHAR) : BOOLEAN ; *)
  71. (* termios.vmin := 0;
  72. termios.vtime := 1; *)
  73. bresult := termios.SetChar(editorConfig.raw,termios.vmin,CHR(0));
  74. bresult := termios.SetChar(editorConfig.raw,termios.vtime,CHR(1));
  75. END enablerawMode;
  76. PROCEDURE editorReadKey() : CHAR;
  77. VAR
  78. c : CHAR;
  79. nread : INTEGER;
  80. BEGIN
  81. p := SYSTEM.ADR(c);
  82. WHILE FIO.ReadNBytes(FIO.StdIn,1,p) <> 1 DO
  83. ;
  84. END;
  85. RETURN c
  86. END editorReadKey;
  87. (******************** output ******************)
  88. PROCEDURE editorDrawRows;
  89. VAR
  90. y : CARDINAL;
  91. BEGIN
  92. FOR y := 1 TO 24 DO
  93. STextIO.WriteChar("~");
  94. STextIO.WriteLn;
  95. STextIO.WriteChar(CHR(13))
  96. END;
  97. END editorDrawRows;
  98. PROCEDURE editorRefreshScreen;
  99. BEGIN
  100. STextIO.WriteString(clearScreen);
  101. editorDrawRows;
  102. STextIO.WriteString(cursorHome);
  103. END editorRefreshScreen;
  104. (******************** input ******************)
  105. PROCEDURE editorProcessKeypress;
  106. VAR
  107. c : CHAR;
  108. b : BOOLEAN;
  109. BEGIN
  110. c := editorReadKey();
  111. CASE ORD(c) OF
  112. 17 : HALT;
  113. END
  114. END editorProcessKeypress;
  115. (******************** INIT ******************)
  116. PROCEDURE InitScreenEscapes;
  117. BEGIN
  118. clearScreen := "";
  119. Strings.Concat(clearScreen,ASCII.esc,clearScreen);
  120. Strings.Concat(clearScreen,"[2J",clearScreen);
  121. Strings.Concat(clearScreen,ASCII.esc,clearScreen);
  122. Strings.Concat(clearScreen,"[H",clearScreen);
  123. cursorHome := "";
  124. Strings.Concat(cursorHome,ASCII.esc,cursorHome);
  125. Strings.Concat(cursorHome,"[H",cursorHome);
  126. END InitScreenEscapes;
  127. BEGIN
  128. InitScreenEscapes;
  129. editorConfig.theThermios := termios.InitTermios();
  130. editorConfig.raw := termios.InitTermios();
  131. IF termios.tcgetattr(FIO.StdIn, editorConfig.theThermios) = -1 THEN
  132. die("tcgetattr")
  133. END;
  134. IF termios.tcgetattr(FIO.StdIn, editorConfig.raw) = -1 THEN
  135. die("tcgetattr")
  136. END;
  137. enablerawMode;
  138. LOOP
  139. editorRefreshScreen;
  140. editorProcessKeypress;
  141. editorRefreshScreen;
  142. END;
  143. END editor.