editor.mod 3.5 KB

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