home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / applications / wp / yadme11.lha / YADME11 / src / cmd1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-02  |  39.5 KB  |  1,732 lines

  1.  
  2. /*
  3.  * CMD1.C   (was TEXT1.C)
  4.  *
  5.  *      (C)Copyright 1987 by Matthew Dillon,    All Rights Reserved
  6.  */
  7.  
  8. #include "defs.h"
  9. #include "cb.h"
  10. #include <ctype.h>
  11. #include <reqtools/reqtools.h>
  12.  
  13. #include "replace.h"
  14.  
  15. typedef struct Process PROC;
  16.  
  17. int confirm_replace(void);
  18. int ConfirmReplace = 0;
  19.  
  20. #define nomemory()  { memoryfail = 1; }
  21.  
  22. char RecallBuf[256];
  23.  
  24.  
  25. /*
  26. void setpen(int line)
  27. {
  28.     ED *ep = Ep;
  29.     RP *rp = ep->Win->RPort;
  30.     short bpen;
  31.  
  32.     short pen = (ep == BEp && line >= BSline && line <= BEline) ? ep->HGPen : ep->FGPen;
  33.     if (Comlinemode)
  34.         pen = ep->FGPen;
  35.     if (pen != rp->FgPen)
  36.         SetAPen(rp, pen);
  37.     bpen = (pen == ep->FGPen) ? ep->BGPen : ep->HGBGPen;
  38.     if (bpen != rp->BgPen)
  39.         SetBPen(rp, bpen);
  40. }
  41. */
  42.  
  43. int is_in_block(int line, int col)
  44. {
  45.    int ret = 0;
  46.  
  47.    if (Ep == BEp)
  48.    {
  49.       switch (Blocktype)
  50.       {
  51.          case BLOCK_CHARACTER:
  52.             if ((line > BSline) || ((line == BSline) && (col >= BSchar)))
  53.                if ((line < BEline) || ((line == BEline) && (col <= BEchar)))
  54.                   ret = 1;
  55.             break;
  56.          case BLOCK_LINE:
  57.             if (line >= BSline && line <= BEline)
  58.                ret = 1;
  59.          default:
  60.             break;
  61.       }
  62.    }
  63.    return ret;
  64. }
  65.  
  66.  
  67. void setpen(int line, int col)
  68. {
  69.     ED *ep = Ep;
  70.     RP *rp = ep->Win->RPort;
  71.     short bpen, pen;
  72.  
  73.     if (is_in_block(line, col))
  74.        pen = ep->HGPen;
  75.     else
  76.        pen = ep->FGPen;
  77.  
  78.     if (Comlinemode)
  79.         pen = ep->FGPen;
  80.     if (pen != rp->FgPen)
  81.         SetAPen(rp, pen);
  82.     bpen = (pen == ep->FGPen) ? ep->BGPen : ep->HGBGPen;
  83.     if (bpen != rp->BgPen)
  84.         SetBPen(rp, bpen);
  85. }
  86.  
  87.  
  88. int text_init(ED *oldep, WIN *win, struct NewWindow *nw)
  89. {
  90.     char buf[10];
  91.     ED *e;
  92.  
  93.     text_switch(NULL);
  94.     e = (ED *)allocb(sizeof(ED));
  95.     if (e == NULL)
  96.         return(0);
  97.     setmem(e, sizeof(ED), 0);
  98.     e->Win = win;
  99.     if (oldep) {
  100.         e->dirlock = (long)DupLock((BPTR)oldep->dirlock);
  101.  
  102.         movmem(&oldep->BeginConfig, &e->BeginConfig, (char *)&e->EndConfig - (char *)&e->BeginConfig);
  103.  
  104.         if (oldep->Font) {
  105.             e->Font = oldep->Font;
  106.             ++e->Font->tf_Accessors;
  107.             if (win)
  108.                 SetFont(win->RPort, e->Font);
  109.         }
  110.         e->IWiny = oldep->IWiny + 16;
  111.     } else {
  112.         PROC *proc = (PROC *)FindTask(NULL);
  113.         e->dirlock = (long)DupLock((BPTR)proc->pr_CurrentDir);
  114.  
  115.         e->Insertmode = 1;
  116.         e->Tabstop = 4;
  117.         e->WWCol = DefaultParcol;
  118.         e->Margin= DefaultMargin;
  119.         e->FGPen = 1;
  120.         e->BGPen = 0;
  121.         e->HGPen = 2;
  122.         e->HGBGPen = 3;
  123.         loadconfig(e);
  124.     }
  125.     e->Lines = 1;
  126.     e->Maxlines = 32;
  127.     e->List = (ubyte **)allocl(e->Maxlines);
  128.     e->List[0] = allocb(1);
  129.     e->List[0][0] = Current[0] = Clen = 0;
  130.     AddHead((LIST *)&DBase, (NODE *)e);
  131.     strcpy(e->Name, "unnamed");
  132.     Ep = e;
  133.  
  134.     if (nw) {
  135.         if (e->Winwidth && e->Winheight) {
  136.             nw->LeftEdge= e->Winx;
  137.             nw->TopEdge = e->Winy;
  138.             nw->Width   = e->Winwidth;
  139.             nw->Height  = e->Winheight;
  140.         } else {
  141.             nw->LeftEdge= 0;
  142.             nw->TopEdge = 0;
  143.             nw->Width   = 640;
  144.             nw->Height  = 200;
  145.         }
  146.         nw->DetailPen = e->BGPen;
  147.         nw->BlockPen  = e->FGPen;
  148.     }
  149.     return(1);
  150. }
  151.  
  152. int text_switch(WIN *win)
  153. {
  154.     ED *e;
  155.  
  156.     if (win)
  157.         text_sync();
  158.     if (win) {
  159.         for (e = (ED *)DBase.mlh_Head; e->Node.mln_Succ; e = (ED *)e->Node.mln_Succ) {
  160.             if (e->Win == win) {
  161.                 Ep = e;
  162.                 text_load();
  163.                 if (!Ep->iconmode) {
  164.                     set_window_params();
  165.                     window_title();
  166.                 }
  167.                 return(1);
  168.             }
  169.         }
  170.         return(0);
  171.     }
  172. }
  173.  
  174.  
  175. int text_sync(void)
  176. {
  177.     ED *ep = Ep;
  178.     char redraw = 0;
  179.     short len;
  180.     ubyte *ptr;
  181.  
  182.     for (len = strlen(Current) - 1; len >= 0 && Current[len] == ' '; --len)
  183.         Current[len] = '\0';
  184.     Clen = len + 1;
  185.     if (!Comlinemode) {
  186.         if (strlen(ep->List[ep->Line]) != Clen) {
  187.             if (ptr = allocb(Clen+1)) {
  188.                 ep->Modified = 1;
  189.                 Overide = 0;
  190.                 FreeMem(ep->List[ep->Line], strlen(ep->List[ep->Line])+1);
  191.                 ep->List[ep->Line] = ptr;
  192.             } else {
  193.                 nomemory();
  194.                 strcpy(Current, ep->List[ep->Line]);
  195.                 Clen = strlen(Current);
  196.             }
  197.         } else {
  198.             if (strcmp(ep->List[ep->Line], Current)) {
  199.                 ep->Modified = 1;
  200.                 Overide = 0;
  201.             }
  202.         }
  203.         strcpy(ep->List[ep->Line], Current);
  204.     }
  205.     if (Nsu == 0) {
  206.         if (ep->Column - ep->Topcolumn >= Columns || ep->Column < ep->Topcolumn) {
  207.             redraw = 1;
  208.  
  209.             ep->Topcolumn = ep->Column - (Columns>>1);
  210.  
  211.             if (ep->Topcolumn < 0)
  212.                 ep->Topcolumn = 0;
  213.         }
  214.         if (ep->Line - ep->Topline >= Rows || ep->Line < ep->Topline) {
  215.             redraw = 1;
  216.  
  217.             ep->Topline = ep->Line - (Rows>>1);
  218.  
  219.             if (ep->Topline < 0)
  220.                 ep->Topline = 0;
  221.         }
  222.     }
  223.     while (ep->Column > Clen)
  224.         Current[Clen++] = ' ';
  225.     Current[Clen] = '\0';
  226.     if (redraw)
  227.         text_redisplay();
  228.     return((int)redraw);
  229. }
  230.  
  231. int text_load(void)
  232. {
  233.     if (Comlinemode)
  234.         return(0);
  235.     strcpy(Current, Ep->List[Ep->Line]);
  236.     Clen = strlen(Current);
  237.     while (Ep->Column > Clen)
  238.         Current[Clen++] = ' ';
  239.     Current[Clen] = '\0';
  240. }
  241.  
  242. int text_colno(void)
  243. {
  244.     return(Ep->Column);
  245. }
  246.  
  247. int text_lineno(void)
  248. {
  249.     return(Ep->Line+1);
  250. }
  251.  
  252. int text_lines(void)
  253. {
  254.     return(Ep->Lines);
  255. }
  256.  
  257. int text_cols(void)
  258. {
  259.     return((int)Clen);
  260. }
  261.  
  262. int text_imode(void)
  263. {
  264.     return((int)Ep->Insertmode);
  265. }
  266.  
  267. int text_tabsize(void)
  268. {
  269.     return((int)Ep->Tabstop);
  270. }
  271.  
  272. unsigned char *text_name()
  273. {
  274.     return(Ep->Name);
  275. }
  276.  
  277. void text_uninit(void)
  278. {
  279.     ED *ep = Ep;
  280.  
  281.     PMKill(ep);
  282.     freelist((char **)ep->List, ep->Lines);
  283.     FreeMem(ep->List, ep->Maxlines * sizeof(char *));
  284.  
  285.     if (BEp == ep) {
  286.         BEp = NULL;
  287.         BSline = BEline = BSchar = BEchar = -1;
  288.     }
  289.     Remove((NODE *)ep);
  290.     if (ep->Font) {
  291.         SetFont(ep->Win->RPort, ep->Win->WScreen->RastPort.Font);
  292.         CloseFont(ep->Font);
  293.     }
  294.     UnLock((BPTR)ep->dirlock);
  295.     FreeMem(ep, sizeof(ED));
  296.     if (((ED *)DBase.mlh_Head)->Node.mln_Succ) {
  297.         Ep = (ED *)DBase.mlh_Head;
  298.         text_load();
  299.     } else {
  300.         Ep = NULL;
  301.     }
  302. }
  303.  
  304. void inversemode(int n)
  305. {
  306.     RP *rp = Ep->Win->RPort;
  307.  
  308.     if (n) {
  309.         SetAPen(rp, ~Ep->BGPen);
  310.         SetDrMd(rp, JAM2|INVERSVID);
  311.     } else {
  312.         setpen(Ep->Line, Ep->Column);
  313.         SetDrMd(rp, JAM2);
  314.     }
  315. }
  316.  
  317. void text_cursor(int n)
  318. {
  319.     ED *ep = Ep;
  320.     RP *rp = ep->Win->RPort;
  321.  
  322.     movetocursor();
  323.     inversemode(n);
  324.     if (Current[ep->Column])
  325.         Text(rp, Current+ep->Column, 1);
  326.     else
  327.         Text(rp, " ", 1);
  328.     inversemode(0);
  329. }
  330.  
  331. void text_position(int col, int row)
  332. {
  333.     ED *ep = Ep;
  334.     text_sync();
  335.     if (col == 0)
  336.         col = -1;
  337.     ep->Column = ep->Topcolumn + col;
  338.     if (ep->Column > 254)
  339.         ep->Column = 254;
  340.     if (ep->Column < 0)
  341.         ep->Column = 0;
  342.     ep->Line = ep->Topline + row;
  343.     if (ep->Line >= ep->Lines)
  344.         ep->Line = ep->Lines - 1;
  345.     if (ep->Line < 0)
  346.         ep->Line = 0;
  347.     text_load();
  348.     text_sync();
  349. }
  350.  
  351. void displayblock(int on)
  352. {
  353.     long start = Ep->Topline;
  354.     long lines = BEline - BSline + 1;
  355.  
  356.     if (start < BSline)
  357.         start = BSline;
  358.     if (!on) {
  359.         BSline = BEline = BSchar = BEchar = -1;
  360.         BEp = NULL;
  361.         Marking = 0;
  362.     }
  363.     /* if (Ep == BEp) removed by KL */
  364.         text_displayseg(start - Ep->Topline, lines);
  365. }
  366.  
  367. void text_redrawblock(int ok)
  368. {
  369.     WIN *savewin = NULL;
  370.  
  371.     if (BEp) {
  372.         if (BEp != Ep) {
  373.             savewin = Ep->Win;
  374.             text_switch(BEp->Win);
  375.         }
  376.         if (BSline <= BEline && BSline >= 0 && BEline < Ep->Lines) {
  377.             if (!ok) {
  378.                 BEp = NULL;
  379.                 BSline = BEline = BSchar = BEchar = -1;
  380.             }
  381.             text_displayseg(0, Rows);
  382.         }
  383.         if (savewin)
  384.             text_switch(savewin);
  385.     }
  386.     if (!ok) {
  387.         BEp = NULL;
  388.         BSline = BEline = BSchar = BEchar = -1;
  389.         Marking = 0;
  390.     }
  391. }
  392.  
  393. int highlight(int line)
  394. {
  395.    int col = Ep->Topcolumn;
  396.    int start, stop;
  397.    int linelength = strlen(Ep->List[line]);
  398. /*
  399.    if ((Ep == BEp) && (! Blockempty) && (!( BSchar == BEchar) && (BSline == BEline)))
  400. */
  401.    switch (Blocktype)
  402.    {
  403.       case BLOCK_CHARACTER:
  404.          if ((Ep == BEp) && (! Blockempty))
  405.          {
  406.             if (line < BSline || line > BEline)
  407.                return  0;  /* No highlighting */
  408.             else if(line > BSline && line < BEline)
  409.                return  2;  /* Highlight entire line */
  410.             else if ((BSline != BEline) && (line == BSline))
  411.             {
  412.                start = BSchar; stop = 256;
  413.             }
  414.             else if ((BSline != BEline) && (line == BEline))
  415.             {
  416.                start = 0; stop = BEchar;
  417.             }
  418.             else
  419.             {
  420.                start = BSchar; stop = BEchar;
  421.             }
  422.             {
  423.                if ((start <= col) && ((stop >= linelength) || (stop - col > Columns)))
  424.                   return 2;
  425.                else if ((start <= col) && (stop < linelength))
  426.                   return 1;
  427.                else if ((start > col) && ((stop >= linelength) || (stop - col > Columns)))
  428.                   return 3;
  429.                else if ((start > col) && (stop < linelength))
  430.                   return 4;
  431.             }
  432.             printf("Highlight: unknown situation\n");
  433.             return 0;
  434.          }
  435.          else
  436.             return 0;
  437.          break;
  438.       case BLOCK_LINE:
  439.          if (Ep == BEp && line >= BSline && line <= BEline)
  440.             return 2;
  441.          else
  442.             return 0;
  443.          break;
  444.       default:
  445.          break;
  446.    }
  447. }
  448.  
  449. /* Changed by Karl Lukas 06/94: Less flicker */
  450.  
  451. void text_displayseg(int start, int n)
  452. {
  453.     short i, c;
  454.     ubyte *ptr;
  455.     ED *ep = Ep;
  456.     RP *rp = ep->Win->RPort;
  457.     RP rp2 = *rp;
  458.     int len;
  459.  
  460.     int hgpen = ep->HGPen;
  461.     int fgpen = ep->FGPen;
  462.     int bgpen = ep->BGPen;
  463.     int hgbgpen = ep->HGBGPen;
  464.  
  465.     if (Nsu)
  466.         return;
  467.     for (i = start; i < start + n && i < Rows && ep->Topline + i < ep->Lines; ++i) {
  468.         if (Comlinemode)
  469.         {
  470.             if (ep->Topline + i != ep->Line)
  471.                 continue;
  472.             ptr = Current;
  473.         }
  474.         else
  475.             ptr = ep->List[ep->Topline + i];
  476.  
  477.         for (c = ep->Topcolumn; c && *ptr; ++ptr, --c);
  478.  
  479.         if (! Comlinemode)
  480.         {
  481.            switch (highlight(ep->Topline + i))
  482.            {
  483.               case 0:  /* No highlighting */
  484.                  if (rp->BgPen != bgpen)
  485.                     SetBPen(rp, bgpen);
  486.                  if (rp->FgPen != fgpen)
  487.                     SetAPen(rp, fgpen);
  488.                  if (rp2.FgPen != bgpen)
  489.                     SetAPen(&rp2, bgpen);
  490.                  c = strlen(ptr);
  491.                  RectFill(&rp2, COL(c), ROW(i), Xbase + Xpixs - 1, ROW(i+1)-1);
  492.                  if (c)
  493.                  {
  494.                     Move(rp, COLT(0), ROWT(i));
  495.                     Text(rp, ptr, (c > Columns) ? Columns : c);
  496.                  }
  497.                  break;
  498.               case 3:  /* highlight end of line */
  499.                  if (rp->BgPen != hgbgpen)
  500.                     SetBPen(rp, hgbgpen);
  501.                  if (rp->FgPen != hgpen)
  502.                     SetAPen(rp, hgpen);
  503.                  if (rp2.FgPen != hgbgpen)
  504.                     SetAPen(&rp2, hgbgpen);
  505.                  RectFill(&rp2, COL(0), ROW(i), Xbase + Xpixs - 1, ROW(i+1)-1);
  506.                  len = BSchar - ep->Topcolumn;
  507.                  c = strlen(ptr);
  508.                  if (c)
  509.                  {
  510.                     Move(rp, COLT(0), ROWT(i));
  511.                     Text(rp, ptr, (c > Columns) ? Columns : c);
  512.                  }
  513.                  if (len > 0 && c)
  514.                  {
  515.                     SetAPen(rp, fgpen);
  516.                     SetBPen(rp, bgpen);
  517.                     Move(rp, COLT(0), ROWT(i));
  518.                     Text(rp, ptr, (len > Columns) ? Columns : len);
  519.                  }
  520.                  break;
  521.               case 1:  /* highlight front of line */
  522.                  if (rp->BgPen != bgpen)
  523.                     SetBPen(rp, bgpen);
  524.                  if (rp->FgPen != fgpen)
  525.                     SetAPen(rp, fgpen);
  526.                  if (rp2.FgPen != bgpen)
  527.                     SetAPen(&rp2, bgpen);
  528.                  RectFill(&rp2, COL(0), ROW(i), Xbase + Xpixs - 1, ROW(i+1)-1);
  529.                  len = BEchar - ep->Topcolumn + 1;
  530.                  c = strlen(ptr);
  531.                  if (c)
  532.                  {
  533.                     Move(rp, COLT(0), ROWT(i));
  534.                     Text(rp, ptr, (c > Columns) ? Columns : c);
  535.                  }
  536.                  if (len > 0 && c)
  537.                  {
  538.                     SetAPen(rp, hgpen);
  539.                     SetBPen(rp, hgbgpen);
  540.                     Move(rp, COLT(0), ROWT(i));
  541.                     Text(rp, ptr, (len > Columns) ? Columns : len);
  542.                  }
  543.                  break;
  544.               case 4:
  545.                  if (rp->BgPen != bgpen)
  546.                     SetBPen(rp, bgpen);
  547.                  if (rp->FgPen != fgpen)
  548.                     SetAPen(rp, fgpen);
  549.                  if (rp2.FgPen != bgpen)
  550.                     SetAPen(&rp2, bgpen);
  551.                  RectFill(&rp2, COL(0), ROW(i), Xbase + Xpixs - 1, ROW(i+1)-1);
  552.                  c = strlen(ptr);
  553.                  if (c)
  554.                  {
  555.                     Move(rp, COLT(0), ROWT(i));
  556.                     Text(rp, ptr, (c > Columns) ? Columns : c);
  557.                  }
  558.                  c = BEchar - BSchar + 1;
  559.                  if (c > 0)
  560.                  {
  561.                     SetAPen(rp, hgpen);
  562.                     SetBPen(rp, hgbgpen);
  563.                     Move(rp, COLT(BSchar - ep->Topcolumn), ROWT(i));
  564.                     Text(rp, ptr + BSchar - ep->Topcolumn, c);
  565.                  }
  566.                  break;
  567.               case 2:  /* highlight whole line */
  568.                  if (rp->BgPen != hgbgpen)
  569.                     SetBPen(rp, hgbgpen);
  570.                  if (rp->FgPen != hgpen)
  571.                     SetAPen(rp, hgpen);
  572.                  if (rp2.FgPen != hgbgpen)
  573.                     SetAPen(&rp2, hgbgpen);
  574.                  RectFill(&rp2, COL(0), ROW(i), Xbase + Xpixs - 1, ROW(i+1)-1);
  575.                  c = strlen(ptr);
  576.                  if (c)
  577.                  {
  578.                     Move(rp, COLT(0), ROWT(i));
  579.                     Text(rp, ptr, (c > Columns) ? Columns : c);
  580.                  }
  581.                  break;
  582.            }
  583.         }
  584.         else
  585.         {
  586.            SetAPen(&rp2, ep->BGPen);
  587.            SetAPen(rp, ep->FGPen);
  588.            SetBPen(rp, ep->BGPen);
  589.            RectFill(&rp2, COL(0), ROW(i), Xbase + Xpixs - 1, ROW(i+1)-1);
  590.            c = strlen(ptr);
  591.            if (c)
  592.            {
  593.               Move(rp, COLT(0), ROWT(i));
  594.               Text(rp, ptr, (c > Columns) ? Columns : c);
  595.            }
  596.         }
  597.     }
  598.     if (UpdateTitle)
  599.        window_title();  /* Added by KL 2.sep.94 */
  600.     if(!Comlinemode)
  601.         prop_adj();
  602.     SetBPen(rp, ep->BGPen);
  603. }
  604.  
  605. void do_updatetitle(void)
  606. {
  607.    UpdateTitle = atoi(av[1]);
  608. }
  609.  
  610. /* Changed by Karl Lukas 06/94: less flicker in conjuction with text_displayseg() */
  611.  
  612. void text_redisplay(void)
  613. {
  614.     ED *ep = Ep;
  615.     RP *rp = ep->Win->RPort;
  616.     int lastrow;
  617.  
  618.     if (Nsu)
  619.         return;
  620.     SetAPen(rp, ep->BGPen);
  621.  
  622.     lastrow = ep->Lines - ep->Topline - 1;
  623.  
  624.     if (Comlinemode)
  625.         RectFill(rp, COL(0), ROW(Rows-1), Xbase + Xpixs - 1, Ybase + Ypixs - 1);
  626.     else
  627.     {
  628.        if (lastrow < Rows)
  629.           RectFill(rp, Xbase, ROW(lastrow), Xbase + Xpixs - 1, Ybase + Ypixs - 1);
  630.     }
  631.     text_displayseg(0,Rows);
  632. }
  633.  
  634. void text_redisplaycurrline(void)
  635. {
  636.     ED *ep = Ep;
  637.     RP *rp = ep->Win->RPort;
  638.  
  639.     int row = ep->Line - ep->Topline;
  640.  
  641.     if (Nsu)
  642.         return;
  643.     SetAPen(rp, ep->BGPen);
  644.     RectFill(rp, COL(0), ROW(row), Xbase + Xpixs - 1, ROW(row+1)-1);
  645.     text_displayseg(row, 1);
  646. }
  647.  
  648. void text_write(unsigned char *str)
  649. {
  650.     short len = strlen(str);
  651.     short i;
  652.     ED *ep = Ep;
  653.     RP *rp = ep->Win->RPort;
  654.  
  655.     if (Clen + len >= 255) {
  656.         text_sync();
  657.         text_load();
  658.     }
  659.     if (ep->Insertmode == 0) {
  660.         if (ep->Column + len >= 255)
  661.             goto fail;
  662.         movmem(str, Current + ep->Column, len);
  663.         if (ep->Column + len >= Clen)
  664.             Clen = ep->Column + len;
  665.         Current[Clen] = 0;
  666.     } else {
  667.         if (Clen + len >= 255)
  668.             goto fail;
  669.  
  670.         /* Adjust character block */
  671.         if ((Blocktype == BLOCK_CHARACTER) && (ep->Line == BSline) && (ep->Column <= BSchar))
  672.            BSchar += len;
  673.         if ((Blocktype == BLOCK_CHARACTER) && (ep->Line == BEline) && (ep->Column <= BEchar))
  674.            BEchar += len;
  675.  
  676.         movmem(Current + ep->Column, Current + ep->Column + len, Clen+1-ep->Column);
  677.         movmem(str, Current + ep->Column, len);
  678.         Clen += len;
  679.         if (len < Columns - (ep->Column - ep->Topcolumn)) {
  680.             ScrollRaster(rp, -len * Xsize, 0 ,
  681.                 COL(ep->Column - ep->Topcolumn),
  682.                 ROW(ep->Line - ep->Topline),
  683.                 Xbase + Xpixs - 1,
  684.                 ROW(ep->Line - ep->Topline + 1) - 1
  685.             );
  686.         }
  687.     }
  688.     i = (ep->Column - ep->Topcolumn + len > Columns) ? Columns - ep->Column + ep->Topcolumn : len;
  689.     setpen(ep->Line, ep->Column);
  690.     Move(rp, COLT(ep->Column - ep->Topcolumn), ROWT(ep->Line - ep->Topline));
  691.     Text(rp, str, i);
  692.     ep->Column += len;
  693.     if (ep->Column - ep->Topcolumn >= Columns)
  694.         text_sync();
  695. fail:
  696.     if (Comlinemode == 0 && ep->Wordwrap)
  697.         do_reformat(0);
  698. }
  699.  
  700. void do_up(void)
  701. {
  702.     ED *ep = Ep;
  703.     RP *rp = ep->Win->RPort;
  704.  
  705.     if (ep->Line) {
  706.         text_sync();
  707.         --ep->Line;
  708.         text_load();
  709.         if (Ep->Line < Ep->Topline) {
  710.             if (Nsu == 0) {
  711.                 ScrollRaster(rp,0,-Ysize,COL(0),ROW(0),Xbase + Xpixs - 1,ROW(Rows)-1);
  712.                 --ep->Topline;
  713.                 text_displayseg(0, 1);
  714.             }
  715.         }
  716.     } else {
  717.         Abortcommand = 1;
  718.     }
  719. }
  720.  
  721. void do_scrolldown(void)
  722. {
  723.     ED *ep = Ep;
  724.     RP *rp = ep->Win->RPort;
  725.  
  726.     if (ep->Topline + Rows < ep->Lines) {
  727.         if (Nsu == 0) {
  728.             text_sync();
  729.             ScrollRaster(rp,0,Ysize,COL(0),ROW(0),Xbase + Xpixs - 1,ROW(Rows)-1);
  730.             ++ep->Topline;
  731.             ++ep->Line;
  732.             text_load();
  733.             text_displayseg(Rows-1, 1);
  734.         }
  735.     } else {
  736.         Abortcommand = 1;
  737.     }
  738. }
  739.  
  740. void do_scrollup(void)
  741. {
  742.     ED *ep = Ep;
  743.     RP *rp = ep->Win->RPort;
  744.  
  745.     if (ep->Topline) {
  746.         if (Nsu == 0) {
  747.             text_sync();
  748.             ScrollRaster(rp,0,-Ysize,COL(0),ROW(0),Xbase + Xpixs - 1,ROW(Rows)-1);
  749.             --ep->Topline;
  750.             --ep->Line;
  751.             text_load();
  752.             text_displayseg(0, 1);
  753.         }
  754.     } else {
  755.         Abortcommand = 1;
  756.     }
  757. }
  758.  
  759. void do_down(void)
  760. {
  761.     ED *ep = Ep;
  762.     RP *rp = ep->Win->RPort;
  763.  
  764.     if (ep->Line + 1 < ep->Lines) {
  765.         text_sync();
  766.         ++ep->Line;
  767.         text_load();
  768.         if (ep->Line - ep->Topline >= Rows) {
  769.             if (Nsu == 0) {
  770.                 ScrollRaster(rp,0,Ysize,COL(0),ROW(0),Xbase + Xpixs - 1,ROW(Rows)-1);
  771.                 ++ep->Topline;
  772.                 text_displayseg(Rows-1, 1);
  773.             }
  774.         }
  775.     } else {
  776.         Abortcommand = 1;
  777.     }
  778. }
  779.  
  780.  
  781. void do_downfast(void)
  782. {
  783.     ED *ep = Ep;
  784.     RP *rp = ep->Win->RPort;
  785.  
  786.     if (ep->Line + 2 < ep->Lines) {
  787.         text_sync();
  788.         ep->Line += 2;
  789.         text_load();
  790.         if (ep->Line - ep->Topline >= Rows) {
  791.             if (Nsu == 0) {
  792.                 ScrollRaster(rp,0,2*Ysize,COL(0),ROW(0),Xbase + Xpixs - 1,ROW(Rows)-1);
  793.                 ep->Topline += 2;
  794.                 text_displayseg(Rows-2, 2);
  795.             }
  796.         }
  797.     } else {
  798.         do_down();
  799.     }
  800. }
  801.  
  802. void do_upfast(void)
  803. {
  804.     ED *ep = Ep;
  805.     RP *rp = ep->Win->RPort;
  806.     int diff;
  807.  
  808.     if (ep->Line > 1) {
  809.         text_sync();
  810.         ep->Line -= 2;
  811.         text_load();
  812.         if ((diff = Ep->Topline - Ep->Line) > 0)
  813.         {
  814.             if (Nsu == 0)
  815.             {
  816.                 ScrollRaster(rp,0,-diff*Ysize,COL(0),ROW(0),Xbase + Xpixs - 1,ROW(Rows)-1);
  817.                 ep->Topline -= diff;
  818.                 text_displayseg(0, diff);
  819.             }
  820.         }
  821.     } else {
  822.         do_up();
  823.     }
  824. }
  825.  
  826. /* Added by Karl Lukas 06/94 */
  827.  
  828. void scroll_jump(int newtop)
  829. {
  830.    ED *ep = Ep;
  831.    RP *rp = ep->Win->RPort;
  832.    int diff = abs(newtop - Ep->Topline);
  833.  
  834.    text_cursor(0);
  835.    if (diff >= Rows)
  836.    {
  837.       text_sync();
  838.       ep->Line += newtop - ep->Topline;
  839.       ep->Topline = newtop;
  840.       text_load();
  841.       if (!text_sync())
  842.          text_redisplay();
  843.    }
  844.    else if((newtop > Ep->Topline) && (Nsu == 0)) /* Scroll up */
  845.    {
  846.       /* Minterm 192: plain vanilla copy */
  847.       ClipBlit(rp, COL(0), ROW(diff), rp, COL(0), ROW(0), Xpixs, (Rows-diff)*Ysize, 192);
  848.       ep->Line += diff;
  849.       ep->Topline = newtop;
  850.       text_load();
  851.       text_displayseg(Rows - diff, diff);
  852.    }
  853.    else if((newtop < Ep->Topline) && (Nsu == 0)) /* Scroll down */
  854.    {
  855.       /* Minterm 192: plain vanilla copy */
  856.       ClipBlit(rp, COL(0), ROW(0), rp, COL(0), ROW(diff), Xpixs, (Rows-diff)*Ysize, 192);
  857.       ep->Line -= diff;
  858.       ep->Topline = newtop;
  859.       text_load();
  860.       text_displayseg(0, diff);
  861.    }
  862.    text_cursor(1);
  863. }
  864.  
  865.  
  866. /*
  867.  *  PAGEUP
  868.  *  PAGEDOWN
  869.  *  PAGESET n   (n = 0 to 100 for percentage of #rows to scroll, minimum 1)
  870.  *              can be > 100.
  871.  */
  872.  
  873. void do_page(void)
  874. {
  875.     int n, multiplier = 1;
  876.     ED *ep = Ep;
  877.  
  878.     switch(av[0][4]) {
  879.     case 'u':
  880.         multiplier = -1;
  881.         if (ep->Topline == 0 && ep->Line == 0)  /* Added by Karl Lukas 06/94 to avoid flicker */
  882.             return;                             /* to avoid flicker */
  883.         if (ep->Topline == 0)
  884.         {
  885.            ep->Line = 0;
  886.            text_load();
  887.            return;
  888.         }                                       /* KL end */
  889.     case 'd':
  890.         n = multiplier * Rows * Pagejump / 100;
  891.         if (!n)
  892.             n = multiplier;
  893.         if (n > 0 && ep->Topline >= ep->Lines - Rows)
  894.         {                                        /* Added by Karl Lukas 06/94      */
  895.            if (ep->Line < (ep->Lines - 1))       /* Now the cursor really jumps to */
  896.            {                                     /* the last line if file end is   */
  897.               ep->Line = ep->Lines - 1;          /* reached                        */
  898.               text_load();
  899.            }                                     /* KL end                         */
  900.            return;
  901.         }
  902.         text_sync();
  903.         ep->Line += n;
  904.         ep->Topline += n;
  905.         if (ep->Line >= ep->Lines)
  906.             ep->Line = ep->Lines - 1;
  907.         if (ep->Line < 0)
  908.             ep->Line = 0;
  909.         if (ep->Topline >= ep->Lines)
  910.             ep->Topline = ep->Lines - Rows - 1;
  911.         if (ep->Topline < 0)
  912.             ep->Topline = 0;
  913.         text_load();
  914.         if (!text_sync())
  915.             text_redisplay();
  916.         break;
  917.     case 's':
  918.         Pagejump = atoi(av[1]);
  919.         break;
  920.     }
  921. }
  922.  
  923. void do_downadd(void)
  924. {
  925.     ED *ep = Ep;
  926.     ubyte *ptr;
  927.  
  928.     if (ep->Line + 1 == ep->Lines) {
  929.         ep->Modified = 1;
  930.         if (makeroom(32) && (ptr = allocb(1))) {
  931.             ep->List[ep->Lines] = ptr;
  932.             *ptr = 0;
  933.             ++ep->Lines;
  934.         } else {
  935.             nomemory();
  936.         }
  937.     }
  938.     do_down();
  939. }
  940.  
  941. void do_left(void)
  942. {
  943.     ED *ep = Ep;
  944.  
  945.     if (ep->Column) {
  946.         --ep->Column;
  947.         if (ep->Column < ep->Topcolumn)
  948.             text_sync();
  949.     } else {
  950.         Abortcommand = 1;
  951.     }
  952. }
  953.  
  954. void do_right(void)
  955. {
  956.     ED *ep = Ep;
  957.  
  958.     if (ep->Column != 254) {
  959.         if (Current[ep->Column] == 0) {
  960.             Current[ep->Column] = ' ';
  961.             Current[ep->Column+1]= '\0';
  962.             ++Clen;
  963.         }
  964.         ++ep->Column;
  965.         if (ep->Column - ep->Topcolumn >= Columns)
  966.             text_sync();
  967.     } else {
  968.         Abortcommand = 1;
  969.     }
  970. }
  971.  
  972. void do_tab(void)
  973. {
  974.     short n;
  975.     ED *ep = Ep;
  976.  
  977.     for (n = ep->Tabstop-(ep->Column % ep->Tabstop); n > 0; --n)
  978.         do_right();
  979. }
  980.  
  981. void do_backtab(void)
  982. {
  983.     short n;
  984.     ED *ep = Ep;
  985.  
  986.     n = ep->Column % ep->Tabstop;
  987.     if (!n)
  988.         n = ep->Tabstop;
  989.     for (; n > 0; --n)
  990.         do_left();
  991. }
  992.  
  993. void do_return(void)
  994. {
  995.     ubyte buf[256];
  996.     char *partial;
  997.  
  998.     if (Comlinemode) {
  999.         strcpy(buf, Current);
  1000.         strcpy(RecallBuf, Current);
  1001.         partial = Partial;
  1002.         Partial = NULL;
  1003.         escapecomlinemode();
  1004.         if (partial) {
  1005.             if (do_command(buf))
  1006.                 do_command(partial);
  1007.             free(partial);
  1008.         } else {
  1009.             do_command(buf);
  1010.         }
  1011.     } else {
  1012.         Ep->Column = 0;
  1013.         text_sync();
  1014.         do_downadd();
  1015.     }
  1016. }
  1017.  
  1018. void do_bs(void)
  1019. {
  1020.     ED *ep = Ep;
  1021.     RP *rp = ep->Win->RPort;
  1022.  
  1023.     if (ep->Column)
  1024.     {
  1025.         if (Blocktype == BLOCK_CHARACTER)
  1026.         {
  1027.            if ((ep->Line == BSline) && (BSchar >= ep->Column))
  1028.               BSchar--;
  1029.            if ((ep->Line == BEline) && (BEchar + 1 >= ep->Column))
  1030.               BEchar--;
  1031.         }
  1032.         movmem(Current + ep->Column, Current + ep->Column - 1, Clen - ep->Column + 1);
  1033.         --ep->Column;
  1034.         --Clen;
  1035.         if (ep->Column < ep->Topcolumn) {
  1036.             text_sync();
  1037.         } else {
  1038.             setpen(ep->Line, ep->Topcolumn + Columns - 1);
  1039.             ScrollRaster(rp, Xsize, 0,
  1040.                 COL(ep->Column - ep->Topcolumn),
  1041.                 ROW(ep->Line   - ep->Topline),
  1042.                 Xbase + Xpixs - 1,
  1043.                 ROW(ep->Line - ep->Topline + 1)-1
  1044.             );
  1045.             if (Clen >= ep->Topcolumn + Columns) {
  1046.                 setpen(ep->Line, ep->Column);
  1047.                 Move(rp, COLT(Columns-1), ROWT(ep->Line - ep->Topline));
  1048.                 Text(rp, Current + ep->Topcolumn + Columns - 1, 1);
  1049.             }
  1050.         }
  1051.         if (Comlinemode == 0 && ep->Wordwrap)
  1052.             do_reformat(0);
  1053.     } else {
  1054.         Abortcommand = 1;
  1055.     }
  1056. }
  1057.  
  1058.  
  1059. /*
  1060.  * esc, escimm
  1061.  */
  1062.  
  1063. int Savetopline, Savecolumn, Savetopcolumn;
  1064.  
  1065. void do_recall(void)
  1066. {
  1067.     av[0] = (ubyte *)"escimm";
  1068.     av[1] = (ubyte *)RecallBuf;
  1069.     do_esc();
  1070. }
  1071.  
  1072. void do_esc(void)
  1073. {
  1074.     ED *ep = Ep;
  1075.     RP *rp = ep->Win->RPort;
  1076.  
  1077.     if (Comlinemode) {
  1078.         escapecomlinemode();
  1079.         return;
  1080.     }
  1081.     text_sync();
  1082.     if (av[0][3] == 'i')
  1083.         strcpy(Current, av[1]);
  1084.     else
  1085.         Current[0] = 0;
  1086.     Clen = strlen(Current);
  1087.     Comlinemode = 1;
  1088.     returnoveride(1);
  1089.     Savetopline = ep->Topline;
  1090.     Savecolumn  = ep->Column;
  1091.     Savetopcolumn = ep->Topcolumn;
  1092.     ep->Column    = Clen;
  1093.     ep->Topcolumn = 0;
  1094.     ep->Topline   = ep->Line - Rows + 1;
  1095.     SetAPen(rp, ep->BGPen);
  1096.     RectFill(rp, COL(0), ROW(Rows-1), Xbase + Xpixs - 1, Ybase + Ypixs - 1);
  1097.     SetAPen(rp, ep->FGPen);
  1098.     Move(rp, COL(0), ROW(Rows-1) - 1);
  1099.     Draw(rp, Xbase + Xpixs - 1, ROW(Rows - 1) - 1);
  1100.     text_displayseg(Rows - 1, 1);
  1101. }
  1102.  
  1103. void escapecomlinemode(void)
  1104. {
  1105.     ED *ep = Ep;
  1106.     RP *rp = ep->Win->RPort;
  1107.  
  1108.     if (Partial) {
  1109.         free(Partial);
  1110.         Partial = NULL;
  1111.     }
  1112.     if (Comlinemode) {
  1113.         strcpy(RecallBuf, Current);
  1114.         Comlinemode = 0;
  1115.         returnoveride(0);
  1116.         ep->Topline = Savetopline;
  1117.         ep->Column  = Savecolumn;
  1118.         ep->Topcolumn = Savetopcolumn;
  1119.         text_load();
  1120.         SetAPen(rp, ep->BGPen);
  1121.         RectFill(rp, COL(0), ROW(Rows-1)-1, Xbase + Xpixs - 1, Ybase + Ypixs - 1);
  1122.         SetAPen(rp, ep->FGPen);
  1123.         text_displayseg(Rows - 2, 2);
  1124.     }
  1125. }
  1126.  
  1127. void do_del(void)
  1128. {
  1129.     ED *ep = Ep;
  1130.     RP *rp = ep->Win->RPort;
  1131.  
  1132.     if (Current[ep->Column])
  1133.     {
  1134.         if (Blocktype == BLOCK_CHARACTER)
  1135.         {
  1136.            if ((ep->Line == BSline) && (BSchar > ep->Column))
  1137.               BSchar--;
  1138.            if ((ep->Line == BEline) && (BEchar >= ep->Column))
  1139.               BEchar--;
  1140.         }
  1141.         movmem(Current + ep->Column + 1, Current + ep->Column, Clen - ep->Column);
  1142.         --Clen;
  1143.         setpen(ep->Line, ep->Topcolumn + Columns - 1);
  1144.         ScrollRaster(rp, Xsize, 0,
  1145.             COL(ep->Column - ep->Topcolumn),
  1146.             ROW(ep->Line - ep->Topline),
  1147.             Xbase + Xpixs - 1,
  1148.             ROW(ep->Line - ep->Topline + 1) - 1
  1149.         );
  1150.         if (Clen >= ep->Topcolumn + Columns) {
  1151.             setpen(ep->Line, ep->Column);
  1152.             Move(rp, COLT(Columns-1), ROWT(ep->Line-ep->Topline));
  1153.             Text(rp, Current+ep->Topcolumn+Columns-1, 1);
  1154.         }
  1155.         if (Comlinemode == 0 && ep->Wordwrap)
  1156.             do_reformat(0);
  1157.     }
  1158. }
  1159.  
  1160. void do_top(void)
  1161. {
  1162.     text_sync();
  1163.     Ep->Line = 0;
  1164.     text_load();
  1165.     text_sync();
  1166. }
  1167.  
  1168. void do_bottom(void)
  1169. {
  1170.     text_sync();
  1171.     Ep->Line = Ep->Lines - 1;
  1172.     text_load();
  1173.     text_sync();
  1174. }
  1175.  
  1176. void do_firstcolumn(void)
  1177. {
  1178.     if (Ep->Column) {
  1179.         Ep->Column = 0;
  1180.         text_sync();
  1181.     }
  1182. }
  1183.  
  1184. void do_firstnb(void)
  1185. {
  1186.     for (Ep->Column = 0; Current[Ep->Column] == ' '; ++Ep->Column);
  1187.     if (Current[Ep->Column] == 0)
  1188.         Ep->Column = 0;
  1189.     text_sync();
  1190. }
  1191.  
  1192. void do_lastcolumn(void)
  1193. {
  1194.     short i;
  1195.  
  1196.     text_sync();
  1197.     i = (Comlinemode) ? Clen : strlen(Ep->List[Ep->Line]);
  1198.     if (i != Ep->Column) {
  1199.         Ep->Column = i;
  1200.         text_sync();
  1201.     }
  1202. }
  1203.  
  1204. /*
  1205.  * GOTO [+/-]N
  1206.  * GOTO BLOCK   start of block
  1207.  * GOTO START   start of block
  1208.  * GOTO END     end of block
  1209.  */
  1210.  
  1211. void do_goto(void)
  1212. {
  1213.     long n, i, col = -1;
  1214.     ubyte *ptr = av[1];
  1215.  
  1216.     i = 0;
  1217.     n = -1;
  1218.  
  1219.     switch(*ptr) {
  1220.     case 'b':
  1221.     case 's':
  1222.     case 'B':
  1223.     case 'S':
  1224.         n = -1;
  1225.         if (Ep == BEp)
  1226.         {
  1227.             n = BSline;
  1228.             col = BSchar;
  1229.         }
  1230.         break;
  1231.     case 'e':
  1232.     case 'E':
  1233.         n = -1;
  1234.         if (Ep == BEp)
  1235.         {
  1236.             n = BEline;
  1237.             col = BEchar;
  1238.         }
  1239.         break;
  1240.     case '+':
  1241.         i = 1;
  1242.     case '-':
  1243.         n = Ep->Line;
  1244.     default:
  1245.         n += atoi(ptr+i);
  1246.     }
  1247.     if (n >= Ep->Lines)
  1248.         n = Ep->Lines - 1;
  1249.     if (n < 0)
  1250.         n = 0;
  1251.     text_sync();
  1252.     Ep->Line = n;
  1253.     if ((Blocktype == BLOCK_CHARACTER) && (col >= 0))
  1254.        Ep->Column = col;
  1255.     else
  1256.        Ep->Column = 0;
  1257.     text_load();
  1258.     text_sync();
  1259. }
  1260.  
  1261. void do_screentop(void)
  1262. {
  1263.     text_sync();
  1264.     Ep->Line = Ep->Topline;
  1265.     text_load();
  1266.     text_sync();
  1267. }
  1268.  
  1269. void do_screenbottom(void)
  1270. {
  1271.     text_sync();
  1272.     Ep->Line = Ep->Topline + Rows - 1;
  1273.     if (Ep->Line < 0 || Ep->Line >= Ep->Lines)
  1274.         Ep->Line = Ep->Lines - 1;
  1275.     text_load();
  1276.     text_sync();
  1277. }
  1278.  
  1279. static ubyte Fstr[256];
  1280. static ubyte Rstr[256];
  1281. static short Srch_sign;
  1282. static char Doreplace;
  1283.  
  1284. /*
  1285.  * findstr, repstr
  1286.  */
  1287.  
  1288. void do_findstr(void)
  1289. {
  1290.     if (av[0][0] == 'f')
  1291.         strcpy(Fstr, av[1]);
  1292.     else
  1293.         strcpy(Rstr, av[1]);
  1294. }
  1295.  
  1296. /*
  1297.  * findr, nextr, prevr
  1298.  */
  1299.  
  1300. void do_findr(void)
  1301. {
  1302.     Doreplace = 1;
  1303.     Srch_sign = 1;
  1304.     switch(av[0][0]) {
  1305.     case 'f':
  1306.         strcpy(Fstr, av[1]);
  1307.         strcpy(Rstr, av[2]);
  1308.         break;
  1309.     case 'p':
  1310.         Srch_sign = -1;
  1311.         break;
  1312.     }
  1313.     search_operation();
  1314. }
  1315.  
  1316. /*
  1317.  * find, next, prev
  1318.  */
  1319.  
  1320. void do_find(void)
  1321. {
  1322.     Doreplace = 0;
  1323.     Srch_sign = 1;
  1324.     switch(av[0][0]) {
  1325.     case 'f':
  1326.         strcpy(Fstr, av[1]);
  1327.         break;
  1328.     case 'p':
  1329.         Srch_sign = -1;
  1330.         break;
  1331.     }
  1332.     search_operation();
  1333. }
  1334.  
  1335. void do_reqreplace(void)
  1336. {
  1337.    int len, i = 0, replace = 0;
  1338.  
  1339.    SearchPattern[0] = 0;
  1340.    ReplacePattern[0] = 0;
  1341.  
  1342.    len = GetClipText(SearchPattern, 255, 1);
  1343.  
  1344.    /* Read only to first linefeed, forget the rest */
  1345.    while ((i < len) && (SearchPattern[i] != '\n'))
  1346.       i++;
  1347.    if (SearchPattern[i] == '\n')
  1348.       SearchPattern[i] = 0;
  1349.  
  1350.    len = GetClipText(ReplacePattern, 255, 2);
  1351.  
  1352.    /* Read only to first linefeed, forget the rest */
  1353.    while ((i < len) && (ReplacePattern[i] != '\n'))
  1354.       i++;
  1355.    if (ReplacePattern[i] == '\n')
  1356.       ReplacePattern[i] = 0;
  1357.  
  1358.    if (! OpenReplaceWindow(Ep->Win->WScreen))
  1359.    {
  1360.       if (HandleReplaceIDCMP())
  1361.       {
  1362.          replace = 1;
  1363.       }
  1364.       else
  1365.          title("Operation cancelled");
  1366.       CloseReplaceWindow();
  1367.    }
  1368.    else
  1369.       title("Unable to open requester");
  1370.  
  1371.    if (replace)
  1372.    {
  1373.       PutClipText(SearchPattern, 1);
  1374.       PutClipText(ReplacePattern, 2);
  1375.  
  1376.       Doreplace = 1;
  1377.       Srch_sign = 1;
  1378.       ConfirmReplace = 1;
  1379.       strcpy(Fstr, SearchPattern);
  1380.       strcpy(Rstr, ReplacePattern);
  1381.  
  1382.       while (! Abortcommand)
  1383.          search_operation();
  1384.       ConfirmReplace = 0;
  1385.    }
  1386. }
  1387.  
  1388.  
  1389. void do_reqfind(void)
  1390. {
  1391.    char buf[256];
  1392.    int len, i = 0;
  1393.  
  1394.    if (ReqToolsBase)
  1395.    {
  1396.       struct TagItem taglist[] =
  1397.       {
  1398.          RT_Window, (ULONG)Ep->Win,
  1399.          TAG_DONE, 0L
  1400.       };
  1401.       buf[0] = 0;
  1402.  
  1403.       len = GetClipText(buf, 255, 1);
  1404.  
  1405.       while ((i < len) && (buf[i] != '\n')) /* Read only to first linefeed, forget the rest */
  1406.          i++;
  1407.       if (buf[i] == '\n')
  1408.          buf[i] = 0;
  1409.  
  1410.       if (rtGetStringA(buf, 255, "Enter search string", NULL, taglist))
  1411.       {
  1412.          PutClipText(buf, 1);
  1413.          av[0] = "f";
  1414.          av[1] = buf;
  1415.          do_find();
  1416.       }
  1417.    }
  1418.    else
  1419.       title("You need reqtools.library for this");
  1420. }
  1421.  
  1422. int GetClipText(char * buf, int buflen, int unit)
  1423. {
  1424.    struct IOClipReq *ior;
  1425.    struct cbbuf *clipbuf;
  1426.    int len = 0;
  1427.  
  1428.    if (ior = CBOpen(unit))
  1429.    {
  1430.       if (CBQueryFTXT(ior))
  1431.       {
  1432.          if (clipbuf = CBReadCHRS(ior))
  1433.          {
  1434.             len = clipbuf->count > buflen ? buflen : clipbuf->count;
  1435.             strncpy(buf, clipbuf->mem, len);
  1436.             buf[len] = 0;
  1437.             CBFreeBuf(clipbuf);
  1438.          }
  1439.          CBReadDone(ior);
  1440.       }
  1441.       CBClose(ior);
  1442.    }
  1443.    return len;
  1444. }
  1445.  
  1446. int PutClipText(char *buf, int unit)
  1447. {
  1448.    struct IOClipReq *ior;
  1449.    int ret = 0;
  1450.  
  1451.    if (ior = CBOpen(unit))
  1452.    {
  1453.       if (CBWriteFTXT(ior, buf))
  1454.          ret = 1;
  1455.       CBClose(ior);
  1456.    }
  1457.    return ret;
  1458. }
  1459.  
  1460.  
  1461. static char CaseIgnore;
  1462.  
  1463. void search_operation(void)
  1464. {
  1465.     int flen = strlen(Fstr);
  1466.     int rlen = strlen(Rstr);
  1467.     char senabled = 0;
  1468.     ubyte *ptr;
  1469.     int i, col;
  1470.     ED *ep = Ep;
  1471.  
  1472.     CaseIgnore = ep->IgnoreCase;
  1473.     text_sync();
  1474.     if (!flen) {
  1475.         title("No find pattern");
  1476.         Abortcommand = 1;
  1477.         return;
  1478.     }
  1479.  
  1480.     title("Searching..."); /* Added 1.sep.94 by KL */
  1481.  
  1482.     col = ep->Column;
  1483.     if (col >= strlen(ep->List[ep->Line]))
  1484.         col = strlen(ep->List[ep->Line]);
  1485.     for (i = ep->Line;;) {
  1486.         ptr = ep->List[i];
  1487.         if (Srch_sign > 0) {
  1488.             while (ptr[col]) {
  1489.                 if (senabled && case_strncmp(Fstr,ptr+col,flen) == 0)
  1490.                     goto found;
  1491.                 senabled = 1;
  1492.                 ++col;
  1493.             }
  1494.             senabled = 1;
  1495.             if (++i >= ep->Lines)
  1496.                 break;
  1497.             col = 0;
  1498.         } else {
  1499.             while (col >= 0) {
  1500.                 if (senabled && case_strncmp(Fstr,ptr+col,flen) == 0)
  1501.                     goto found;
  1502.                 senabled = 1;
  1503.                 --col;
  1504.             }
  1505.             senabled = 1;
  1506.             if (--i < 0)
  1507.                 break;
  1508.             col = strlen(ep->List[i]);
  1509.         }
  1510.     }
  1511.     title("Pattern Not Found");
  1512.     Abortcommand = 1;
  1513.     return;
  1514.  
  1515. found:
  1516.     if (! Doreplace)
  1517.        title("Found pattern"); /* Added 1.sep.94 by KL */
  1518.     ep->Line = i;
  1519.     ep->Column = col;
  1520.  
  1521.     text_load();
  1522.     text_sync();
  1523.     text_cursor(1);
  1524.     if (Doreplace && confirm_replace()) {
  1525.         if (rlen > flen && rlen-flen+strlen(ptr) > 254) {
  1526.             title("Replace: Line Too Long");
  1527.             Abortcommand = 1;
  1528.             return;
  1529.         }
  1530.         if (Clen-col-flen >= 0) {
  1531.             movmem(Current+col+flen, Current+col+rlen, Clen-col-flen+1);
  1532.             movmem(Rstr, Current+col, rlen);
  1533.             Clen += rlen-flen;
  1534.             ep->Column += rlen;
  1535.         }
  1536.         text_sync();
  1537.         text_redisplaycurrline();
  1538.     }
  1539.     text_cursor(0);
  1540. }
  1541.  
  1542. int confirm_replace(void)
  1543. {
  1544.    int ret;
  1545.    int done = 0;
  1546.    struct IntuiMessage *message;
  1547.    char buf[256];
  1548.  
  1549.    if (! ConfirmReplace)
  1550.       return 1;
  1551.  
  1552.    title("Replace? (Y)es (N)o (A)ll (Q)uit");
  1553.  
  1554.    while (! done)
  1555.    {
  1556.       Wait(1 << Ep->Win->UserPort->mp_SigBit);
  1557.  
  1558.       while (message = (struct IntuiMessage *)GetMsg(Ep->Win->UserPort))
  1559.       {
  1560.          switch (message->Class)
  1561.          {
  1562.             case RAWKEY:
  1563.                buf[0] = 0;
  1564.                DeadKeyConvert(message, buf, 255, NULL);
  1565.                switch(buf[0])
  1566.                {
  1567.                   case 'A':
  1568.                   case 'a':
  1569.                     ConfirmReplace = 0;
  1570.                   case 'Y':
  1571.                   case 'y':
  1572.                      ret = done = 1;
  1573.                      break;
  1574.                   case 'N':
  1575.                   case 'n':
  1576.                      ret = 0;
  1577.                      done = 1;
  1578.                      break;
  1579.                   case 'Q':
  1580.                   case 'q':
  1581.                      ret = 0;
  1582.                      done = 1;
  1583.                      Abortcommand = 1;
  1584.                      title("Aborted");
  1585.                      break;
  1586.                   default:
  1587.                      break;
  1588.                }
  1589.                break;
  1590.             case NEWSIZE:
  1591.                ret = 0;
  1592.                Abortcommand = 1;
  1593.                done = 1;
  1594.                set_window_params();
  1595.                if (!text_sync())
  1596.                   text_redisplay();
  1597.                title("Aborted");
  1598.                break;
  1599.             case INTUITICKS:
  1600.                break;
  1601.             default:
  1602.                break;
  1603.          }
  1604.          ReplyMsg((struct Message *)message);
  1605.       }
  1606.    }
  1607.    return ret;
  1608. }
  1609.  
  1610.  
  1611. int case_strncmp(char *s1, char *s2, int len)
  1612. {
  1613.     if (CaseIgnore == 0)
  1614.         return(strncmp(s1, s2, len));
  1615.     for (; len; --len, ++s1, ++s2) {
  1616.         if ((*s1|0x20) != (*s2|0x20))
  1617.             return(1);
  1618.         if ((!isalpha(*s1) || !isalpha(*s2)) && *s1 != *s2)
  1619.             return(1);
  1620.     }
  1621.     return(0);
  1622. }
  1623.  
  1624.  
  1625.  
  1626.  
  1627. static ubyte brackets[][2] = {
  1628.     '(',    ')',
  1629.     '{',    '}',
  1630.     '[',    ']',
  1631.     '<',    '>',
  1632.     '`',    '\'',
  1633.     0
  1634. };
  1635.  
  1636. void
  1637. do_findmatch()
  1638. {
  1639.     ubyte c, c2;
  1640.     ubyte *lineptr;
  1641.     short direction = 0, i;
  1642.     long cnt = 0;
  1643.     long line, column;
  1644.     long endline, endcol, col, len;
  1645.  
  1646.     line = Ep->Line;
  1647.     column = Ep->Column;
  1648.     c = Current[column];
  1649.  
  1650.     for (i = 0; brackets[i][0]; i++) {
  1651.         if (brackets[i][0] == c) {      /* forward  */
  1652.             c2 = brackets[i][1];
  1653.             direction = 1;
  1654.             endline = Ep->Lines - 1;
  1655.             break;
  1656.         }
  1657.         if (brackets[i][1] == c) {      /* backward */
  1658.             c2 = brackets[i][0];
  1659.             direction = -1;
  1660.             endline = 0;
  1661.             break;
  1662.         }
  1663.     }
  1664.  
  1665.     if (direction == 0) {
  1666.         title("not matchable character");
  1667.         return;
  1668.     }
  1669.  
  1670.     for ( ; line != endline + direction; line += direction) {
  1671.  
  1672.         if (cnt == 0) {
  1673.             lineptr = Current;      /* current line (we're just starting) */
  1674.             len = Clen;
  1675.             col = column;
  1676.         } else {
  1677.             lineptr = Ep->List[line];
  1678.             len = strlen(lineptr);
  1679.             col = (direction == 1) ? 0 : len - 1;
  1680.         }
  1681.         endcol = (direction == 1) ? len - 1 : 0;
  1682.  
  1683.         for ( ; col != endcol + direction; col += direction) {
  1684.             if (lineptr[col] == c)
  1685.                 cnt++;
  1686.             else if (lineptr[col] == c2) {
  1687.                 cnt--;
  1688.                 if (cnt == 0) {     /* found match!!          */
  1689.                     text_sync();    /* ok, now update buffers */
  1690.                     Ep->Line = line;
  1691.                     Ep->Column = col;
  1692.                     text_load();    /* and move to new place  */
  1693.                     text_sync();
  1694.                     return;
  1695.                 }
  1696.             }
  1697.         }
  1698.     }
  1699.     title("match not found");
  1700. }
  1701.  
  1702. /*
  1703.  *  Change to window by filepath, open new window and load new file
  1704.  *  if window cannot be found.
  1705.  */
  1706.  
  1707. void
  1708. do_window()
  1709. {
  1710.     ED *ed;
  1711.     char buf[128];
  1712.  
  1713.     if ((ed = finded(av[1], 0)) == NULL) {
  1714.         sprintf(buf, "newwindow newfile (%s)", av[1]);
  1715.         do_command(buf);
  1716.         ed = finded(av[1], 0);
  1717.     } else {
  1718.         WindowToFront(ed->Win);
  1719.         ActivateWindow(ed->Win);
  1720.     }
  1721.     if (ed == NULL) {
  1722.         title("unable to load file");
  1723.     } else {
  1724.         text_switch(ed->Win);
  1725.         if (Ep->iconmode)
  1726.             uniconify();
  1727.         else
  1728.             text_cursor(0);
  1729.     }
  1730. }
  1731.  
  1732.