cedit.red 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. COMMENT REDUCE INPUT STRING EDITOR;
  2. GLOBAL '(CRBUF!* CRBUF1!* CRBUFLIS!* ESC!* STATCOUNTER RPRIFN!* RTERFN!*
  3. !$EOL!$ !*EAGAIN !*FULL);
  4. !*EAGAIN := NIL;
  5. %ESC!* := INTERN ASCII 125; %this is system dependent and defines
  6. %a terminator for strings;
  7. SYMBOLIC PROCEDURE RPLACW(U,V);
  8. IF ATOM U OR ATOM V THEN ERRACH LIST('RPLACW,U,V)
  9. ELSE RPLACD(RPLACA(U,CAR V),CDR V);
  10. SYMBOLIC PROCEDURE CEDIT N;
  11. BEGIN SCALAR X,OCHAN;
  12. OCHAN := WRS NIL;
  13. IF N EQ 'FN THEN X := REVERSIP CRBUF!*
  14. ELSE IF NULL N
  15. THEN IF NULL CRBUFLIS!*
  16. THEN <<STATCOUNTER := STATCOUNTER-1;
  17. REDERR "No previous entry">>
  18. ELSE X := CDAR CRBUFLIS!*
  19. ELSE IF (X := ASSOC(CAR N,CRBUFLIS!*)) THEN X := CDR X
  20. ELSE <<STATCOUNTER := STATCOUNTER-1;
  21. REDERR LIST("Entry",CAR N,"not found")>>;
  22. CRBUF!* := NIL;
  23. X := FOR EACH J IN X COLLECT J; %to make a copy;
  24. TERPRI();
  25. EDITP X;
  26. TERPRI();
  27. X := CEDIT1 X;
  28. WRS OCHAN;
  29. IF X EQ 'FAILED THEN NIL ELSE CRBUF1!* := X
  30. END;
  31. GLOBAL '(!*BLANKNOTOK!*);
  32. SYMBOLIC PROCEDURE CEDIT1 U;
  33. BEGIN SCALAR X,Y,Z;
  34. Z := SETPCHAR '!>;
  35. IF NOT !*EAGAIN
  36. THEN <<PRIN2T "For help, type ?"; !*EAGAIN := T>>;
  37. WHILE U AND (CAR U EQ !$EOL!$) DO U := CDR U;
  38. U := APPEND(U,LIST '! ); %to avoid 'last char' problem;
  39. IF !*FULL THEN EDITP U;
  40. TOP:
  41. X := U; %current pointer position;
  42. A:
  43. Y := READCH(); %current command;
  44. IF Y EQ 'P OR Y EQ 'p THEN EDITP X
  45. ELSE IF Y EQ 'I OR Y EQ 'i THEN EDITI X
  46. ELSE IF Y EQ 'C OR Y EQ 'c THEN EDITC X
  47. ELSE IF Y EQ 'D OR Y EQ 'd THEN EDITD X
  48. ELSE IF Y EQ 'F OR Y EQ 'f THEN X := EDITF(X,NIL)
  49. ELSE IF Y EQ 'E OR Y EQ 'e
  50. THEN <<TERPRI(); EDITP1 U; SETPCHAR Z; RETURN U>>
  51. ELSE IF Y EQ 'Q OR Y EQ 'q THEN <<SETPCHAR Z; RETURN 'FAILED>>
  52. ELSE IF Y EQ '!? THEN EDITH X
  53. ELSE IF Y EQ 'B OR Y EQ 'b THEN GO TO TOP
  54. ELSE IF Y EQ 'K OR Y EQ 'k THEN EDITF(X,T)
  55. ELSE IF Y EQ 'S OR Y EQ 's THEN X := EDITS X
  56. ELSE IF Y EQ '! AND NOT !*BLANKNOTOK!* OR Y EQ 'X OR Y EQ 'x
  57. THEN X := EDITN X
  58. ELSE IF Y EQ '! AND !*BLANKNOTOK!* THEN GO TO A
  59. ELSE IF Y EQ !$EOL!$ THEN GO TO A
  60. ELSE LPRIM!* LIST(Y,"Invalid editor character");
  61. GO TO A
  62. END;
  63. SYMBOLIC PROCEDURE EDITC X;
  64. IF NULL CDR X THEN LPRIM!* "No more characters"
  65. ELSE RPLACA(X,READCH());
  66. SYMBOLIC PROCEDURE EDITD X;
  67. IF NULL CDR X THEN LPRIM!* "No more characters"
  68. ELSE RPLACW(X,CADR X . CDDR X);
  69. SYMBOLIC PROCEDURE EDITF(X,BOOL);
  70. BEGIN SCALAR Y,Z;
  71. Y := CDR X;
  72. Z := READCH();
  73. IF NULL Y THEN RETURN <<LPRIM!* LIST(Z,"Not found"); X>>;
  74. WHILE CDR Y AND NOT Z EQ CAR Y DO Y := CDR Y;
  75. RETURN IF NULL CDR Y THEN <<LPRIM!* LIST(Z,"Not found"); X>>
  76. ELSE IF BOOL THEN RPLACW(X,CAR Y . CDR Y)
  77. ELSE Y
  78. END;
  79. SYMBOLIC PROCEDURE EDITH X;
  80. <<PRIN2T "THE FOLLOWING COMMANDS ARE SUPPORTED:";
  81. PRIN2T " B move pointer to beginning";
  82. PRIN2T " C<character> replace next character by <character>";
  83. PRIN2T " D delete next character";
  84. PRIN2T " E end editing and reread text";
  85. PRIN2T
  86. " F<character> move pointer to next occurrence of <character>";
  87. PRIN2T
  88. " I<string><escape> insert <string> in front of pointer";
  89. PRIN2T " K<character> delete all chars until <character>";
  90. PRIN2T " P print string from current pointer";
  91. PRIN2T " Q give up with error exit";
  92. PRIN2T
  93. " S<string><escape> search for first occurrence of <string>";
  94. PRIN2T " positioning pointer just before it";
  95. PRIN2T " <space> or X move pointer right one character";
  96. TERPRI();
  97. PRIN2T
  98. "ALL COMMAND SEQUENCES SHOULD BE FOLLOWED BY A CARRIAGE RETURN";
  99. PRIN2T " TO BECOME EFFECTIVE">>;
  100. SYMBOLIC PROCEDURE EDITI X;
  101. BEGIN SCALAR Y,Z;
  102. WHILE (Y := READCH()) NEQ ESC!* DO Z := Y . Z;
  103. RPLACW(X,NCONC(REVERSIP Z,CAR X . CDR X))
  104. END;
  105. SYMBOLIC PROCEDURE EDITN X;
  106. IF NULL CDR X THEN LPRIM!* "NO MORE CHARACTERS"
  107. ELSE CDR X;
  108. SYMBOLIC PROCEDURE EDITP U;
  109. <<EDITP1 U; TERPRI()>>;
  110. SYMBOLIC PROCEDURE EDITP1 U;
  111. FOR EACH X IN U DO IF X EQ !$EOL!$ THEN TERPRI() ELSE PRIN2 X;
  112. SYMBOLIC PROCEDURE EDITS U;
  113. BEGIN SCALAR X,Y,Z;
  114. X := U;
  115. WHILE (Y := READCH()) NEQ ESC!* DO Z := Y . Z;
  116. Z := REVERSIP Z;
  117. A: IF NULL X THEN RETURN <<LPRIM!* "not found"; U>>
  118. ELSE IF EDMATCH(Z,X) THEN RETURN X;
  119. X := CDR X;
  120. GO TO A
  121. END;
  122. SYMBOLIC PROCEDURE EDMATCH(U,V);
  123. %matches list of characters U against V. Returns rest of V if
  124. %match occurs or NIL otherwise;
  125. IF NULL U THEN V
  126. ELSE IF NULL V THEN NIL
  127. ELSE IF CAR U=CAR V THEN EDMATCH(CDR U,CDR V)
  128. ELSE NIL;
  129. SYMBOLIC PROCEDURE LPRIM!* U; <<LPRIM U; TERPRI()>>;
  130. COMMENT Editing Function Definitions;
  131. REMPROP('EDITDEF,'STAT);
  132. SYMBOLIC PROCEDURE EDITDEF U; EDITDEF1 CAR U;
  133. SYMBOLIC PROCEDURE EDITDEF1 U;
  134. BEGIN SCALAR TYPE,X;
  135. IF NULL(X := GETD U) THEN RETURN LPRIM LIST(U,"not defined")
  136. ELSE IF CODEP CDR X OR NOT EQCAR(CDR X,'LAMBDA)
  137. THEN RETURN LPRIM LIST(U,"cannot be edited");
  138. TYPE := CAR X;
  139. X := CDR X;
  140. IF TYPE EQ 'EXPR THEN X := 'DE . U . CDR X
  141. ELSE IF TYPE EQ 'FEXPR THEN X := 'DF . U . CDR X
  142. ELSE IF TYPE EQ 'MACRO THEN X := 'DM . U . CDR X
  143. ELSE REDERR LIST("strange function type",TYPE);
  144. RPRIFN!* := 'ADD2BUF;
  145. RTERFN!* := 'ADDTER2BUF;
  146. CRBUF!* := NIL;
  147. X := ERRORSET(LIST('RPRINT,MKQUOTE X),T,NIL);
  148. RPRIFN!* := NIL;
  149. RTERFN!* := NIL;
  150. IF ERRORP X THEN RETURN (CRBUF!* := NIL);
  151. CRBUF!* := CEDIT 'FN;
  152. RETURN NIL
  153. END;
  154. SYMBOLIC PROCEDURE ADD2BUF U; CRBUF!* := U . CRBUF!*;
  155. SYMBOLIC PROCEDURE ADDTER2BUF; CRBUF!* := !$EOL!$ . CRBUF!*;
  156. PUT('EDITDEF,'STAT,'RLIS);
  157. COMMENT Displaying past input expressions;
  158. PUT('DISPLAY,'STAT,'RLIS);
  159. SYMBOLIC PROCEDURE DISPLAY U;
  160. BEGIN SCALAR X;
  161. U := CAR U;
  162. X := CRBUFLIS!*;
  163. TERPRI();
  164. IF NOT NUMBERP U THEN U := LENGTH X;
  165. WHILE U>0 AND X DO
  166. <<PRIN2 CAAR X; PRIN2 ": "; EDITP CDAR X; TERPRI();
  167. X := CDR X; U := U-1>>;
  168. END;
  169. END;