editor.mod 4.5 KB

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