editor.mod 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. MODULE editor;
  2. (* based on the kilo editor building course*)
  3. (* Step 23 *)
  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. (******************** TERMINAL ******************)
  20. PROCEDURE CtrlKey(c: CHAR) : CARDINAL;
  21. VAR
  22. n : BITSET;
  23. BEGIN
  24. n := BITSET(ORD(c));
  25. n := n * BITSET(1FH);
  26. RETURN CARDINAL(n)
  27. END CtrlKey;
  28. PROCEDURE die (s : ARRAY OF CHAR);
  29. BEGIN
  30. libc.perror(s);
  31. (* STextIO.WriteString(clearScreen); *)
  32. HALT
  33. END die;
  34. PROCEDURE disableRawMode(): INTEGER;
  35. VAR
  36. TCSAFLUSH : INTEGER;
  37. result : INTEGER;
  38. BEGIN
  39. TCSAFLUSH := termios.tcsflush ();
  40. IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, thetermios) = -1 THEN
  41. die("tcsetattr")
  42. END;
  43. RETURN result;
  44. END disableRawMode;
  45. PROCEDURE enableRawMode;
  46. VAR
  47. TCSAFLUSH : INTEGER;
  48. result : INTEGER;
  49. bresult : BOOLEAN;
  50. BEGIN
  51. TCSAFLUSH := termios.tcsflush ();
  52. libc.atexit(disableRawMode);
  53. bresult := termios.SetFlag(raw,termios.icrnl, FALSE);
  54. bresult := termios.SetFlag(raw,termios.ixon, FALSE);
  55. bresult := termios.SetFlag(raw,termios.lecho, FALSE);
  56. bresult := termios.SetFlag(raw,termios.opost, FALSE);
  57. bresult := termios.SetFlag(raw,termios.licanon, FALSE);
  58. bresult := termios.SetFlag(raw,termios.liexten, FALSE);
  59. bresult := termios.SetFlag(raw,termios.lisig, FALSE);
  60. bresult := termios.SetFlag(raw,termios.ibrkint, FALSE);
  61. bresult := termios.SetFlag(raw,termios.inpck, FALSE);
  62. bresult := termios.SetFlag(raw,termios.istrip, FALSE);
  63. bresult := termios.SetFlag(raw,termios.cs8, TRUE);
  64. IF termios.tcsetattr(FIO.StdIn, TCSAFLUSH, raw) = -1 THEN
  65. die("tcsetattr")
  66. END;
  67. (* PROCEDURE SetChar (t: TERMIOS; c: ControlChar; ch: CHAR) : BOOLEAN ; *)
  68. (* termios.vmin := 0;
  69. termios.vtime := 1; *)
  70. bresult := termios.SetChar(raw,termios.vmin,CHR(0));
  71. bresult := termios.SetChar(raw,termios.vtime,CHR(1));
  72. END enableRawMode;
  73. PROCEDURE editorReadKey() : CHAR;
  74. VAR
  75. c : CHAR;
  76. nread : INTEGER;
  77. BEGIN
  78. p := SYSTEM.ADR(c);
  79. WHILE FIO.ReadNBytes(FIO.StdIn,1,p) <> 1 DO
  80. ;
  81. END;
  82. RETURN c
  83. END editorReadKey;
  84. (******************** output ******************)
  85. PROCEDURE editorRefreshScreen;
  86. BEGIN
  87. STextIO.WriteString(clearScreen)
  88. END editorRefreshScreen;
  89. (******************** input ******************)
  90. PROCEDURE editorProcessKeypress;
  91. VAR
  92. c : CHAR;
  93. b : BOOLEAN;
  94. BEGIN
  95. c := editorReadKey();
  96. CASE ORD(c) OF
  97. 17 : HALT;
  98. END
  99. END editorProcessKeypress;
  100. (******************** INIT ******************)
  101. PROCEDURE InitClearScreen;
  102. BEGIN
  103. clearScreen := "";
  104. Strings.Concat(clearScreen,ASCII.esc,clearScreen);
  105. Strings.Concat(clearScreen,"[2J",clearScreen);
  106. Strings.Concat(clearScreen,ASCII.esc,clearScreen);
  107. Strings.Concat(clearScreen,"[H",clearScreen);
  108. END InitClearScreen;
  109. BEGIN
  110. InitClearScreen;
  111. thetermios := termios.InitTermios();
  112. raw := termios.InitTermios();
  113. IF termios.tcgetattr(FIO.StdIn, thetermios) = -1 THEN
  114. die("tcgetattr")
  115. END;
  116. IF termios.tcgetattr(FIO.StdIn, raw) = -1 THEN
  117. die("tcgetattr")
  118. END;
  119. enableRawMode;
  120. LOOP
  121. editorRefreshScreen;
  122. editorProcessKeypress;
  123. editorRefreshScreen;
  124. END;
  125. END editor.