home *** CD-ROM | disk | FTP | other *** search
/ Jason Aller Floppy Collection / 270.img / FORUM25C.ZIP / ANSIEDIT.PAS < prev    next >
Pascal/Delphi Source File  |  1989-02-06  |  21KB  |  1,089 lines

  1. {$R-,S-,I-,F-,V-,B-,L+ }
  2. {$M 65500,0,0 }
  3.  
  4. {$ifdef testansieditor}
  5. {*}
  6. {*} {*} indicates test code
  7. {*}
  8. {*}uses crt,modem;
  9. {*}
  10. {*}const maxmessagesize=100;
  11. {*}      hungupon=false;
  12. {*}
  13. {*}type anystr=string[255];
  14. {*}     lstr=string[80];
  15. {*}     mstr=string[30];
  16. {*}     sstr=string[15];
  17. {*}
  18. {*}     message=record
  19. {*}       text:array [1..maxmessagesize] of lstr;
  20. {*}       title:mstr;
  21. {*}       anon:boolean;
  22. {*}       numlines:integer
  23. {*}     end;
  24. {*}
  25. {*}     regs=record
  26. {*}       case byte of
  27. {*}         0:(ax,bx,cx,dx,bp,si,di,ds,es,flags:integer);
  28. {*}         1:(al,ah,bl,bh,cl,ch,dl,dh:byte)
  29. {*}     end;
  30. {*}
  31. {*}type configtype=(moreprompts,eightycols,ansigraphics);
  32. {*}
  33. {*}var input:anystr;
  34. {*}    nobreak:boolean;
  35. {*}    urec:record
  36. {*}      displaylen:integer;
  37. {*}      config:set of configtype
  38. {*}    end;
  39. {*}    winds:array [0..0] of record y2:integer end;
  40. {*}
  41. {*}
  42. {*}function strr (n:integer):mstr;
  43. {*}var q:mstr;
  44. {*}begin
  45. {*}  str (n,q);
  46. {*}  strr:=q
  47. {*}end;
  48. {*}
  49. {*}function waitforchar:char;
  50. {*}var k:char;
  51. {*}begin
  52. {*}  repeat until keypressed or (numchars>0);
  53. {*}  read (kbd,k);
  54. {*}  waitforchar:=k
  55. {*}end;
  56. {*}
  57. {*}procedure clearbreak;
  58. {*}begin
  59. {*}end;
  60. {*}
  61. {*}function yes:boolean;
  62. {*}begin
  63. {*}  yes:=false;
  64. {*}  if length(input)>0
  65. {*}    then if upcase(input[1])='Y'
  66. {*}      then yes:=true
  67. {*}end;
  68. {*}
  69. {*}function readchar:char;
  70. {*}var r:regs;
  71. {*}begin
  72. {*}  if keypressed then begin
  73. {*}    r.ah:=0;
  74. {*}    intr ($16,r);
  75. {*}    readchar:=chr(r.al);
  76. {*}    if r.al=29 then halt;
  77. {*}    if r.al=0 then case r.ah of
  78. {*}      72:readchar:=^E;
  79. {*}      75:readchar:=^S;
  80. {*}      77:readchar:=^D;
  81. {*}      80:readchar:=^X;
  82. {*}      115:readchar:=^A;
  83. {*}      116:readchar:=^F;
  84. {*}      73:readchar:=^R;
  85. {*}      81:readchar:=^C;
  86. {*}      71:readchar:=^Q;
  87. {*}      79:readchar:=^W;
  88. {*}      83:readchar:=^G;
  89. {*}      82:readchar:=^V;
  90. {*}      117:readchar:=^P;
  91. {*}    end;
  92. {*}    exit
  93. {*}  end;
  94. {*}  if (numchars>0) and carrier
  95. {*}    then readchar:=getchar
  96. {*}    else readchar:=#0
  97. {*}end;
  98. {*}
  99. {*}procedure writeturbo (k:char);
  100. {*}begin
  101. {*}  inline ($8A/$86/k/$50/$ff/$16/usroutptr)
  102. {*}end;
  103. {*}
  104. {*}procedure writechar (k:char);
  105. {*}var r:regs;
  106. {*}begin
  107. {*}  if k=^J then writeturbo (k) else begin
  108. {*}    r.dl:=ord(k);
  109. {*}    r.ah:=2;
  110. {*}    intr ($21,r)
  111. {*}  end;
  112. {*}  if carrier then sendchar (k)
  113. {*}end;
  114. {*}
  115. {*}procedure getstr;
  116. {*}begin
  117. {*}  readln (input)
  118. {*}end;
  119. {*}
  120. {*}procedure printfile (l:lstr);
  121. {*}begin
  122. {*}end;
  123. {*}
  124. {*}procedure wholescreen;
  125. {*}begin
  126. {*}  window (1,1,80,winds[0].y2)
  127. {*}end;
  128. {*}
  129. {*}procedure bottom;
  130. {*}begin
  131. {*}end;
  132. {*}
  133. {*}procedure bottomline;
  134. {*}begin
  135. {*}end;
  136. {*}
  137. {*}procedure unsplit;
  138. {*}begin
  139. {*}end;
  140. {*}
  141. {*}function ansireedit (var m:message; gettitle:boolean):boolean;
  142. {*}
  143. {$else}
  144.  
  145. unit ansiedit;
  146.  
  147. interface
  148.  
  149. uses crt,
  150.      gentypes,modem,configrt,windows,gensubs,subs1,subs2;
  151.  
  152.  
  153. function ansireedit (var m:message; gettitle:boolean):boolean;
  154.  
  155. implementation
  156.  
  157. function ansireedit (var m:message; gettitle:boolean):boolean;
  158.  
  159. {$endif}
  160.  
  161. var topline,curline,cx,cy,cols,scrnsize,lines,
  162.     rightmargin,savedx,savedy,topscrn:integer;
  163.     insertmode,msgdone,ansimode,helptoggle:boolean;
  164.  
  165. function curx:integer;
  166. begin
  167.   curx:=wherex
  168. end;
  169.  
  170. function cury:integer;
  171. begin
  172.   cury:=wherey-topscrn+1
  173. end;
  174.  
  175. procedure writevt52 (q:lstr);
  176. var cnt:integer;
  177. begin
  178.   if not carrier then exit;
  179.   for cnt:=1 to length(q) do sendchar (q[cnt])
  180. end;
  181.  
  182. procedure moveto (x,y:integer);
  183. begin
  184.   y:=y+topscrn-1;
  185.   if ansimode then begin
  186.     write (direct,#27'[');
  187.     if y<>1 then write (direct,strr(y));
  188.     if x<>1 then write (direct,';',strr(x));
  189.     write ('H')
  190.   end else begin
  191.     gotoxy (x,y);
  192.     writevt52 (#27'Y'+chr(y+31)+chr(x+31))
  193.   end
  194. end;
  195.  
  196. procedure clearscr;
  197. begin
  198.   if ansimode
  199.     then write (direct,#27'[2J')
  200.     else begin
  201.       writevt52 (#27'H'#27'J');
  202.       clrscr
  203.     end
  204. end;
  205.  
  206. procedure cleareol;
  207. begin
  208.   if ansimode
  209.     then write (direct,#27'[K')
  210.     else begin
  211.       writevt52 (#27'K');
  212.       clreol
  213.     end
  214. end;
  215.  
  216. procedure savecsr;
  217. begin
  218.   if ansimode
  219.     then write (direct,#27'[s')
  220.     else begin
  221.       savedx:=curx;
  222.       savedy:=cury
  223.     end
  224. end;
  225.  
  226. procedure restorecsr;
  227. begin
  228.   if ansimode
  229.     then write (direct,#27'[u')
  230.     else moveto (savedx,savedy)
  231. end;
  232.  
  233. procedure cmove (k:char; n,dx,dy:integer);
  234. var cnt:integer;
  235. begin
  236.   if n<1 then exit;
  237.   if ansimode then begin
  238.     write (direct,#27'[');
  239.     if n<>1 then write (direct,strr(n));
  240.     write (direct,k)
  241.   end else
  242.     for cnt:=1 to n do begin
  243.       writevt52 (#27+k);
  244.       gotoxy (wherex+dx,wherey+dy)
  245.     end
  246. end;
  247.  
  248. procedure cup (n:integer);
  249. begin
  250.   cmove ('A',n,0,-1)
  251. end;
  252.  
  253. procedure cdn (n:integer);
  254. begin
  255.   cmove ('B',n,0,1)
  256. end;
  257.  
  258. procedure clf (n:integer);
  259. var cnt:integer;
  260. begin
  261.   cmove ('D',n,-1,0)
  262. end;
  263.  
  264. procedure crg (n:integer);
  265. begin
  266.   cmove ('C',n,1,0)
  267. end;
  268.  
  269. procedure checkspaces;
  270. var q:^lstr;
  271. begin
  272.   q:=addr(m.text[curline]);
  273.   while q^[length(q^)]=' ' do q^[0]:=pred(q^[0])
  274. end;
  275.  
  276. procedure checkcx;
  277. var n:integer;
  278. begin
  279.   n:=length(m.text[curline])+1;
  280.   if cx>n then cx:=n
  281. end;
  282.  
  283. procedure computecy;
  284. begin
  285.   cy:=curline-topline+1
  286. end;
  287.  
  288. procedure updatecpos;
  289. begin
  290.   computecy;
  291.   moveto (cx,cy)
  292. end;
  293.  
  294. procedure insertabove;
  295. var cnt:integer;
  296. begin
  297.   if m.numlines=maxmessagesize then exit;
  298.   for cnt:=m.numlines downto curline do m.text[cnt+1]:=m.text[cnt];
  299.   m.text[curline]:='';
  300.   m.numlines:=m.numlines+1
  301. end;
  302.  
  303. procedure deletethis;
  304. var cnt:integer;
  305. begin
  306.   if m.numlines=1 then begin
  307.     m.text[1]:='';
  308.     exit
  309.   end;
  310.   for cnt:=curline+1 to m.numlines do m.text[cnt-1]:=m.text[cnt];
  311.   m.text[m.numlines]:='';
  312.   m.numlines:=m.numlines-1;
  313.   checkcx
  314. end;
  315.  
  316. procedure fullrefresh;
  317. var cnt,n:integer;
  318. begin
  319.   clearscr;
  320.   if topline<1 then topline:=1;
  321.   computecy;
  322.   if helptoggle then begin
  323.      if ansimode then printfile (textfiledir+'Edithelp.ANS')
  324.        else printfile (textfiledir+'EDITHELP.ASC');
  325.      end
  326.   else if ansimode then printfile (textfiledir+'Ruler.ANS')
  327.    else writeln ('----!----1----!----2----!----3----!----4----!----5----!----6----!----7----!----8');
  328.   moveto (1,1);
  329.   for cnt:=1 to lines do begin
  330.     n:=cnt+topline-1;
  331.     if n<=m.numlines then begin
  332.       write (m.text[n]);
  333.       if cnt<>lines then writeln
  334.     end
  335.   end;
  336.   updatecpos
  337. end;
  338.  
  339. procedure repos (dorefresh:boolean);
  340. var cl,tl:integer;
  341. begin
  342.   checkspaces;
  343.   cl:=curline;
  344.   tl:=topline;
  345.   if curline<1 then curline:=1;
  346.   if curline>m.numlines then curline:=m.numlines;
  347.   if topline>curline then topline:=curline;
  348.   if topline+lines<curline then topline:=curline-lines;
  349.   if topline<1 then topline:=1;
  350.   checkcx;
  351.   computecy;
  352.   if (cl=curline) and (tl=topline) and (not dorefresh)
  353.     then updatecpos
  354.     else fullrefresh
  355. end;
  356.  
  357. procedure partrefresh;  { Refreshes from CY }
  358. var cnt,n:integer;
  359. begin
  360.   if topline<1 then repos(true) else begin
  361.     moveto (1,cy);
  362.     for cnt:=cy to lines do begin
  363.       n:=cnt+topline-1;
  364.       if n<=m.numlines then write (m.text[n]);
  365.       cleareol;
  366.       if cnt<>lines then writeln
  367.     end;
  368.     updatecpos
  369.   end
  370. end;
  371.  
  372. procedure pageup;
  373. begin
  374.   checkspaces;
  375.   if curline=1 then exit;
  376.   curline:=curline-lines+4;
  377.   topline:=topline-lines+4;
  378.   repos (true)
  379. end;
  380.  
  381. procedure pagedn;
  382. begin
  383.   checkspaces;
  384.   if curline=m.numlines then exit;
  385.   curline:=curline+lines-4;
  386.   topline:=topline+lines-4;
  387.   repos (true)
  388. end;
  389.  
  390. procedure toggleins;
  391. begin
  392.   insertmode:=not insertmode
  393. end;
  394.  
  395. procedure scrolldown;
  396. begin
  397.   topline:=curline-lines+2;
  398.   repos (true)
  399. end;
  400.  
  401. procedure scrollup;
  402. begin
  403.   if topline<1 then begin
  404.     topline:=topline+1;
  405.     moveto (1,lines);
  406.     computecy;
  407.     writeln
  408.   end else begin
  409.     topline:=curline-1;
  410.     repos (true)
  411.   end
  412. end;
  413.  
  414. procedure topofmsg;
  415. begin
  416.   checkspaces;
  417.   cx:=1;
  418.   cy:=1;
  419.   curline:=1;
  420.   if topline=1
  421.     then updatecpos
  422.     else
  423.       begin
  424.         topline:=1;
  425.         fullrefresh
  426.       end
  427. end;
  428.  
  429. procedure updatetoeol;
  430. var cnt:integer;
  431. begin
  432.   savecsr;
  433.   write (copy(m.text[curline],cx,255));
  434.   cleareol;
  435.   restorecsr
  436. end;
  437.  
  438. procedure letterkey (k:char);
  439. var l:^lstr;
  440.     w:lstr;
  441.     n,ox:integer;
  442.     q:char;
  443.     inserted,refr:boolean;
  444.  
  445.   procedure scrollwwrap;
  446.   begin
  447.     if topline>0 then begin
  448.       scrollup;
  449.       exit
  450.     end;
  451.     cy:=cy-1;
  452.     moveto (length(m.text[curline-1])+1,cy);
  453.     cleareol;
  454.     writeln;
  455.     write (m.text[curline]);
  456.     topline:=topline+1;
  457.     cx:=curx
  458.   end;
  459.  
  460. begin
  461.   l:=addr(m.text[curline]);
  462.   if length(l^)>=rightmargin then begin
  463.     if curline=maxmessagesize then exit;
  464.     if cx<=length(l^) then exit;
  465.     l^:=l^+k;
  466.     w:='';
  467.     cx:=length(l^);
  468.     repeat
  469.       q:=l^[cx];
  470.       if q<>' ' then insert (q,w,1);
  471.       cx:=cx-1
  472.     until (q=' ') or (cx<1);
  473.     if cx<1 then begin
  474.       cx:=length(l^)-1;
  475.       w:=k
  476.     end;
  477.     l^[0]:=chr(cx);
  478.     checkspaces;
  479.     curline:=curline+1;
  480.     if curline>m.numlines then m.numlines:=curline;
  481.     inserted:=m.text[curline]<>'';
  482.     if inserted then insertabove;
  483.     m.text[curline]:=w;
  484.     cy:=cy+1;
  485.     ox:=cx;
  486.     cx:=length(w)+1;
  487.     refr:=cy>lines;
  488.     if refr
  489.       then scrollwwrap
  490.       else begin
  491.         if length(w)>0 then begin
  492.           moveto (ox+1,cy-1);
  493.           for n:=1 to length(w) do write (' ')
  494.         end;
  495.         if inserted and (m.numlines>curline)
  496.           then partrefresh
  497.           else begin
  498.             moveto (1,cy);
  499.             write (m.text[curline]);
  500.           end
  501.       end;
  502.     exit
  503.   end;
  504.   if insertmode
  505.     then insert (k,l^,cx)
  506.     else begin
  507.       while length(l^)<cx do l^:=l^+' ';
  508.       l^[cx]:=k
  509.     end;
  510.   write (k);
  511.   cx:=cx+1;
  512.   if insertmode and (cx<=length(l^)) then updatetoeol
  513. end;
  514.  
  515. procedure back;
  516. begin
  517.   if cx=1 then begin
  518.     if curline=1 then exit;
  519.     checkspaces;
  520.     curline:=curline-1;
  521.     cy:=cy-1;
  522.     cx:=length(m.text[curline])+1;
  523.     if cy<1 then scrolldown else updatecpos;
  524.   end else begin
  525.     cx:=cx-1;
  526.     clf (1)
  527.   end
  528. end;
  529.  
  530. procedure fowrd;
  531. begin
  532.   if cx>length(m.text[curline]) then begin
  533.     if curline=maxmessagesize then exit;
  534.     checkspaces;
  535.     curline:=curline+1;
  536.     if curline>m.numlines then m.numlines:=curline;
  537.     cy:=cy+1;
  538.     cx:=1;
  539.     if cy>lines then scrollup else updatecpos
  540.   end else begin
  541.     cx:=cx+1;
  542.     crg (1)
  543.   end
  544. end;
  545.  
  546. procedure del;
  547. begin
  548.   if length(m.text[curline])=0 then begin
  549.     deletethis;
  550.     partrefresh;
  551.     exit
  552.   end;
  553.   delete (m.text[curline],cx,1);
  554.   if cx>length(m.text[curline])
  555.     then write (' '^H)
  556.     else updatetoeol
  557. end;
  558.  
  559. procedure bkspace;
  560. begin
  561.   if length(m.text[curline])=0 then begin
  562.     if curline=1 then exit;
  563.     deletethis;
  564.     checkspaces;
  565.     curline:=curline-1;
  566.     cy:=cy-1;
  567.     cx:=length(m.text[curline])+1;
  568.     if cy<1
  569.       then scrolldown
  570.       else partrefresh;
  571.     exit
  572.   end;
  573.   if cx=1 then exit;
  574.   cx:=cx-1;
  575.   write (^H);
  576.   del
  577. end;
  578.  
  579. procedure beginline;
  580. begin
  581.   if cx=1 then exit;
  582.   cx:=1;
  583.   updatecpos
  584. end;
  585.  
  586. procedure endline;
  587. var dx:integer;
  588. begin
  589.   dx:=length(m.text[curline])+1;
  590.   if cx=dx then exit;
  591.   cx:=dx;
  592.   updatecpos
  593. end;
  594.  
  595. procedure upline;
  596. var chx:boolean;
  597.     l:integer;
  598. begin
  599.   checkspaces;
  600.   if curline=1 then exit;
  601.   curline:=curline-1;
  602.   l:=length(m.text[curline]);
  603.   chx:=cx>l;
  604.   if chx then cx:=l+1;
  605.   cy:=cy-1;
  606.   if cy>0
  607.     then if chx
  608.       then updatecpos
  609.       else cup (1)
  610.     else scrolldown
  611. end;
  612.  
  613. procedure downline;
  614. var chx:boolean;
  615.     l:integer;
  616. begin
  617.   checkspaces;
  618.   if curline=maxmessagesize then exit;
  619.   curline:=curline+1;
  620.   if curline>m.numlines then m.numlines:=curline;
  621.   l:=length(m.text[curline]);
  622.   chx:=cx>l;
  623.   if chx then cx:=l+1;
  624.   cy:=cy+1;
  625.   if cy<=lines
  626.     then if chx
  627.       then updatecpos
  628.       else cdn (1)
  629.     else scrollup
  630. end;
  631.  
  632. procedure crlf;
  633. var k:char;
  634. begin
  635.   if (length(m.text[curline])=2) and (m.text[curline][1]='/') then begin
  636.     k:=upcase(m.text[curline][2]);
  637.     case k of
  638.       'S':begin
  639.         deletethis;
  640.         msgdone:=true;
  641.         ansireedit:=true;
  642.         exit
  643.       end
  644.     end
  645.   end;
  646.   beginline;
  647.   downline
  648. end;
  649.  
  650. function conword:boolean;
  651. var l:^lstr;
  652. begin
  653.   l:=addr(m.text[curline]);
  654.   conword:=false;
  655.   if (cx>length(l^)) or (cx=0) then exit;
  656.   conword:=true;
  657.   if cx=1 then exit;
  658.   if (l^[cx-1]=' ') and (l^[cx]<>' ') then exit;
  659.   conword:=false
  660. end;
  661.  
  662. procedure wordleft;
  663. begin
  664.   repeat
  665.     cx:=cx-1;
  666.     if cx<1 then begin
  667.       if curline=1 then begin
  668.         cx:=1;
  669.         repos (false);
  670.         exit
  671.       end;
  672.       checkspaces;
  673.       curline:=curline-1;
  674.       cy:=cy-1;
  675.       cx:=length(m.text[curline])
  676.     end;
  677.   until conword;
  678.   if cx=0 then cx:=1;
  679.   if cy<1
  680.     then repos (true)
  681.     else updatecpos
  682. end;
  683.  
  684. procedure wordright;
  685. begin
  686.   repeat
  687.     cx:=cx+1;
  688.     if cx>length(m.text[curline]) then begin
  689.       if curline=m.numlines then begin
  690.         repos (false);
  691.         exit
  692.       end;
  693.       checkspaces;
  694.       curline:=curline+1;
  695.       cy:=cy+1;
  696.       cx:=1
  697.     end;
  698.   until conword;
  699.   if cy>lines
  700.     then repos (true)
  701.     else updatecpos
  702. end;
  703.  
  704. procedure worddel;
  705. var l:^lstr;
  706.     b:byte;
  707.     s,n:integer;
  708. begin
  709.   l:=addr(m.text[curline]);
  710.   b:=length(l^);
  711.   if cx>b then exit;
  712.   s:=cx;
  713.   repeat
  714.     cx:=cx+1
  715.   until conword or (cx>b);
  716.   n:=cx-s;
  717.   delete (l^,s,n);
  718.   cx:=s;
  719.   updatetoeol
  720. end;
  721.  
  722. procedure deleteline;
  723. begin
  724.   deletethis;
  725.   partrefresh
  726. end;
  727.  
  728. procedure insertline;
  729. begin
  730.   if m.numlines>=maxmessagesize then exit;
  731.   insertabove;
  732.   checkcx;
  733.   partrefresh
  734. end;
  735.  
  736. procedure help;
  737. var k:char;
  738. begin
  739.   clearscr;
  740.   if ansimode then printfile (textfiledir+'Edithelp.ANS')
  741.   else begin
  742.      clearscr;
  743.      printfile (textfiledir+'edithelp.asc');
  744.      end;
  745.   write (^B^M'Press any key...');
  746.   k:=waitforchar;
  747.  fullrefresh
  748. end;
  749.  
  750. procedure breakline;
  751. begin
  752.   if (m.numlines>=maxmessagesize) or (cy=lines) or
  753.     (cx=1) or (cx>length(m.text[curline])) then exit;
  754.   insertabove;
  755.   m.text[curline]:=copy(m.text[curline+1],1,cx-1);
  756.   delete (m.text[curline+1],1,cx-1);
  757.   partrefresh
  758. end;
  759.  
  760. procedure joinlines;
  761. var n:integer;
  762. begin
  763.   if curline=m.numlines then exit;
  764.   if length(m.text[curline])+length(m.text[curline+1])>rightmargin then exit;
  765.   m.text[curline]:=m.text[curline]+m.text[curline+1];
  766.   n:=cx;
  767.   curline:=curline+1;
  768.   deletethis;
  769.   curline:=curline-1;
  770.   cx:=n;
  771.   partrefresh
  772. end;
  773.  
  774. procedure userescape;
  775. var k:char;
  776. begin
  777.   repeat
  778.   k:=waitforchar;
  779.     case k of
  780.       'A':upline;
  781.       'B':downline;
  782.       'C':fowrd;
  783.       'D':back
  784.     end
  785.   until (k<>'[') or hungupon
  786. end;
  787.  
  788. procedure deleteeol;
  789. begin
  790.   cleareol;
  791.   m.text[curline][0]:=chr(cx-1)
  792. end;
  793.  
  794. procedure tab;
  795. var nx,n,cnt:integer;
  796. begin
  797.   nx:=((cx+8) and 248)+1;
  798.   n:=nx-cx;
  799.   if (n+length(m.text[curline])>=cols) or (nx>=cols) then exit;
  800.   for cnt:=1 to n do insert (' ',m.text[curline],cx);
  801.   updatetoeol;
  802.   cx:=cx+n;
  803.   updatecpos
  804. end;
  805.  
  806. procedure signature;
  807. var nx,n:integer;
  808. begin
  809.   nx:=((cx+length(unam)) and 248)+1;
  810.   n:=nx-cx;
  811.   if (n+length(m.text[curline])>=cols) or (nx>=cols) then exit;
  812.   insert (unam,m.text[curline],cx);
  813.   updatetoeol;
  814.   cx:=cx+length(unam);
  815.   updatecpos
  816. end;
  817.  
  818.  
  819.  
  820. procedure commands;
  821.  
  822.   function youaresure:boolean;
  823.   var q:string[1];
  824.   begin
  825.     youaresure:=false;
  826.     moveto (1,0);
  827.     write ('Are you sure? ');
  828.     buflen:=1;
  829.     getstr;
  830.     cup (1);
  831.     write ('               ');
  832.     youaresure:=yes;
  833.     clearbreak;
  834.     nobreak:=true
  835.   end;
  836.  
  837.   procedure savemes;
  838.   begin
  839.     msgdone:=true;
  840.     ansireedit:=true
  841.   end;
  842.  
  843.   procedure abortmes;
  844.   begin
  845.     if youaresure then begin
  846.       m.numlines:=0;
  847.       msgdone:=true
  848.     end
  849.   end;
  850.  
  851.   procedure formattext;
  852.   var ol,il,c:integer;
  853.       oln,wd,iln:lstr;
  854.       k:char;
  855.  
  856.     procedure putword;
  857.     var cnt:integer;
  858.         b:boolean;
  859.     begin
  860.       b:=true;
  861.       for cnt:=1 to length(wd) do if wd[cnt]<>' ' then b:=false;
  862.       if b then exit;
  863.       while wd[length(wd)]=' ' do wd[0]:=pred(wd[0]);
  864.       if length(wd)=0 then exit;
  865.       if length(wd)+length(oln)>rightmargin then begin
  866.         m.text[ol]:=oln;
  867.         ol:=ol+1;
  868.         while (wd[1]=' ') and (length(wd)>0) do delete (wd,1,1);
  869.         oln:=wd
  870.       end else oln:=oln+wd;
  871.       if wd[length(wd)] in ['.','?','!']
  872.         then wd:='  '
  873.         else wd:=' '
  874.     end;
  875.  
  876.   begin
  877.     il:=curline;
  878.     ol:=il;
  879.     c:=1;
  880.     oln:='';
  881.     wd:='';
  882.     iln:=m.text[il];
  883.     repeat
  884.       if length(iln)=0 then begin
  885.         putword;
  886.         m.text[ol]:=oln;
  887.         partrefresh;
  888.         checkcx;
  889.         updatecpos;
  890.         exit
  891.       end;
  892.       if c>length(iln) then begin
  893.         il:=il+1;
  894.         if il>m.numlines
  895.           then iln:=''
  896.           else begin
  897.             iln:=m.text[il];
  898.             m.text[il]:=''
  899.           end;
  900.         c:=0;
  901.         k:=' '
  902.       end else k:=iln[c];
  903.       c:=c+1;
  904.       if k=' '
  905.         then putword
  906.         else wd:=wd+k
  907.     until 0=1
  908.   end;
  909.  
  910. var cmd:string[1];
  911.     k:char;
  912. begin
  913.   clearbreak;
  914.   nobreak:=true;
  915.   if ansimode then moveto (0,0)
  916.   else moveto (1,0);
  917.   write ('Cmd: ');
  918.   buflen:=1;
  919.   getstr;
  920.   clearbreak;
  921.   nobreak:=true;
  922.   cup (1);
  923.   write ('      ');
  924.   if length(input)=0 then begin
  925.     updatecpos;
  926.     exit
  927.   end;
  928.   k:=upcase(input[1]);
  929.   case k of
  930.     'S':savemes;
  931.     'A':abortmes;
  932.     'F':formattext;
  933.     'H':begin
  934.          if helptoggle then begin
  935.           clearscr;
  936.           gotoxy (1,1);
  937.           lines:=urec.displaylen-2;
  938.           topscrn:=scrnsize-lines+1;
  939.           topline:=2-lines;
  940.           helptoggle:=false;
  941.           fullrefresh;
  942.          end
  943.        else begin
  944.          helptoggle:=true;
  945.          lines:=urec.displaylen-9;
  946.          topscrn:=scrnsize-lines+1;
  947.          topline:=2-lines;
  948.          helptoggle:=true;
  949.          fullrefresh;
  950.        end;
  951.       end;
  952.     '?':help
  953.   end;
  954.   updatecpos
  955. end;
  956.  
  957.  
  958.  
  959.  
  960. procedure processkey;
  961. var k:char;
  962. begin
  963.   clearbreak;
  964.   nobreak:=true;
  965.   k:=waitforchar;
  966.   case k of
  967.     ' '..'~':letterkey (k);
  968.     ^S:back;
  969.     ^D:fowrd;
  970.     ^H:bkspace;
  971.     ^M:crlf;
  972.     ^V:toggleins;
  973.     ^E:upline;
  974.     ^X:downline;
  975.     ^U:help;
  976.     ^K:commands;
  977.     ^R:pageup;
  978.     ^C:pagedn;
  979.     ^G:del;
  980.     ^A:wordleft;
  981.     ^F:wordright;
  982.     ^T:worddel;
  983.     ^Q:beginline;
  984.     ^W:endline;
  985.     ^L:fullrefresh;
  986.     ^Y:deleteline;
  987.     ^N:insertline;
  988.     ^I:tab;
  989.     ^B:breakline;
  990.     ^P:deleteeol;
  991.     ^J:joinlines;
  992.     ^Z:signature;
  993.     #27:userescape
  994.   end
  995. end;
  996.  
  997. var cnt:integer;
  998.     mp:boolean;
  999.  
  1000. begin
  1001.   clearbreak;
  1002.   nobreak:=true;
  1003.   ansireedit:=false;
  1004.   for cnt:=m.numlines+1 to maxmessagesize do m.text[cnt]:='';
  1005.   scrnsize:=urec.displaylen;
  1006.   winds[0].y2:=scrnsize;
  1007.   unsplit;
  1008.   wholescreen;
  1009.   gotoxy (1,25);
  1010.   clreol;
  1011.   if eightycols in urec.config
  1012.     then cols:=80
  1013.     else cols:=40;
  1014.   ansimode:=ansigraphics in urec.config;
  1015.   mp:=moreprompts in urec.config;
  1016.   if mp then urec.config:=urec.config-[moreprompts];
  1017.   lines:=urec.displaylen-9;
  1018.   topscrn:=scrnsize-lines+1;
  1019.   insertmode:=false;
  1020.   rightmargin:=cols-1;
  1021.   msgdone:=false;
  1022.   cx:=1;
  1023.   curline:=1;
  1024.   topline:=2-lines;
  1025.   computecy;
  1026.   helptoggle:=true;
  1027.   updatecpos;
  1028.   if m.numlines>0
  1029.     then fullrefresh
  1030.     else
  1031.       begin
  1032.         clearscr;
  1033.         fullrefresh;
  1034.         m.numlines:=1
  1035.       end;
  1036.   repeat
  1037.     processkey
  1038.   until msgdone or hungupon;
  1039.   moveto (1,lines);
  1040.   cleareol;
  1041.   writeln (^M^M^M^M);
  1042.   if mp then urec.config:=urec.config+[moreprompts];
  1043.   winds[0].y2:= 25;
  1044.   bottom;
  1045.   bottomline
  1046. end;
  1047.  
  1048.  
  1049. {$ifdef testansieditor}
  1050. {*}
  1051. {*}procedure termmode;
  1052. {*}var k:char;
  1053. {*}begin
  1054. {*}  setparam (1,1200,false);
  1055. {*}  writeln ('Press ^D when connected.');
  1056. {*}  repeat
  1057. {*}    if keypressed then begin
  1058. {*}      read (kbd,k);
  1059. {*}      if k=#4 then exit;
  1060. {*}      if k=#3 then halt;
  1061. {*}      sendchar (k)
  1062. {*}    end;
  1063. {*}    while numchars>0 do write (getchar)
  1064. {*}  until 0=1
  1065. {*}end;
  1066. {*}
  1067. {*}var m:message;
  1068. {*}    cnt:integer;
  1069. {*}begin
  1070. {*}  checkbreak:=false;
  1071. {*}  urec.displaylen:=22;
  1072. {*}  urec.config:=[eightycols]; { ,ansigraphics]; }
  1073. {*}  if not driverpresent then begin
  1074. {*}    writeln ('You fool.');
  1075. {*}    halt
  1076. {*}  end;
  1077. {*}  termmode;
  1078. {*}  coninptr:=ofs(readchar);
  1079. {*}  conoutptr:=ofs(writechar);
  1080. {*}  m.numlines:=0;
  1081. {*}  for cnt:=1 to 100 do m.text[cnt]:='Hello line '+chr(cnt+64);
  1082. {*}  writeln (ansireedit(m,false))
  1083. {*}
  1084. {$endif}
  1085.  
  1086. end.
  1087.  
  1088.  
  1089.