home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / SYSPC22.ZIP / ANSIEDIT.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1987-12-13  |  18.1 KB  |  1,012 lines

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