home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Misc / YADME10.LHA / YADME10 / src / cmd1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-19  |  40.0 KB  |  1,747 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), ROWT(i));
  564.                     Text(rp, ptr + BSchar, 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.  
  599. /* dust---------------------------------------------------
  600.         if ((rp2.FgPen != rp->BgPen) && (! Comlinemode))
  601.            SetAPen(&rp2, rp->BgPen);
  602.         else if (Comlinemode)
  603.  
  604.         RectFill(&rp2, COL(0), ROW(i), Xbase + Xpixs - 1, ROW(i+1)-1);
  605.         c = strlen(ptr);
  606.         if (c) {
  607.             Move(rp, COLT(0), ROWT(i));
  608.             Text(rp, ptr, (c > Columns) ? Columns : c);
  609.         }
  610. -----------------------------------------------------------*/
  611.  
  612.     }
  613.     if (UpdateTitle)
  614.        window_title();  /* Added by KL 2.sep.94 */
  615.     if(!Comlinemode)
  616.         prop_adj();
  617.     SetBPen(rp, ep->BGPen);
  618. }
  619.  
  620. void do_updatetitle(void)
  621. {
  622.    UpdateTitle = atoi(av[1]);
  623. }
  624.  
  625. /* Changed by Karl Lukas 06/94: less flicker in conjuction with text_displayseg() */
  626.  
  627. void text_redisplay(void)
  628. {
  629.     ED *ep = Ep;
  630.     RP *rp = ep->Win->RPort;
  631.     int lastrow;
  632.  
  633.     if (Nsu)
  634.         return;
  635.     SetAPen(rp, ep->BGPen);
  636.  
  637.     lastrow = ep->Lines - ep->Topline - 1;
  638.  
  639.     if (Comlinemode)
  640.         RectFill(rp, COL(0), ROW(Rows-1), Xbase + Xpixs - 1, Ybase + Ypixs - 1);
  641.     else
  642.     {
  643.        if (lastrow < Rows)
  644.           RectFill(rp, Xbase, ROW(lastrow), Xbase + Xpixs - 1, Ybase + Ypixs - 1);
  645.     }
  646.     text_displayseg(0,Rows);
  647. }
  648.  
  649. void text_redisplaycurrline(void)
  650. {
  651.     ED *ep = Ep;
  652.     RP *rp = ep->Win->RPort;
  653.  
  654.     int row = ep->Line - ep->Topline;
  655.  
  656.     if (Nsu)
  657.         return;
  658.     SetAPen(rp, ep->BGPen);
  659.     RectFill(rp, COL(0), ROW(row), Xbase + Xpixs - 1, ROW(row+1)-1);
  660.     text_displayseg(row, 1);
  661. }
  662.  
  663. void text_write(unsigned char *str)
  664. {
  665.     short len = strlen(str);
  666.     short i;
  667.     ED *ep = Ep;
  668.     RP *rp = ep->Win->RPort;
  669.  
  670.     if (Clen + len >= 255) {
  671.         text_sync();
  672.         text_load();
  673.     }
  674.     if (ep->Insertmode == 0) {
  675.         if (ep->Column + len >= 255)
  676.             goto fail;
  677.         movmem(str, Current + ep->Column, len);
  678.         if (ep->Column + len >= Clen)
  679.             Clen = ep->Column + len;
  680.         Current[Clen] = 0;
  681.     } else {
  682.         if (Clen + len >= 255)
  683.             goto fail;
  684.  
  685.         /* Adjust character block */
  686.         if ((Blocktype == BLOCK_CHARACTER) && (ep->Line == BSline) && (ep->Column <= BSchar))
  687.            BSchar += len;
  688.         if ((Blocktype == BLOCK_CHARACTER) && (ep->Line == BEline) && (ep->Column <= BEchar))
  689.            BEchar += len;
  690.  
  691.         movmem(Current + ep->Column, Current + ep->Column + len, Clen+1-ep->Column);
  692.         movmem(str, Current + ep->Column, len);
  693.         Clen += len;
  694.         if (len < Columns - (ep->Column - ep->Topcolumn)) {
  695.             ScrollRaster(rp, -len * Xsize, 0 ,
  696.                 COL(ep->Column - ep->Topcolumn),
  697.                 ROW(ep->Line - ep->Topline),
  698.                 Xbase + Xpixs - 1,
  699.                 ROW(ep->Line - ep->Topline + 1) - 1
  700.             );
  701.         }
  702.     }
  703.     i = (ep->Column - ep->Topcolumn + len > Columns) ? Columns - ep->Column + ep->Topcolumn : len;
  704.     setpen(ep->Line, ep->Column);
  705.     Move(rp, COLT(ep->Column - ep->Topcolumn), ROWT(ep->Line - ep->Topline));
  706.     Text(rp, str, i);
  707.     ep->Column += len;
  708.     if (ep->Column - ep->Topcolumn >= Columns)
  709.         text_sync();
  710. fail:
  711.     if (Comlinemode == 0 && ep->Wordwrap)
  712.         do_reformat(0);
  713. }
  714.  
  715. void do_up(void)
  716. {
  717.     ED *ep = Ep;
  718.     RP *rp = ep->Win->RPort;
  719.  
  720.     if (ep->Line) {
  721.         text_sync();
  722.         --ep->Line;
  723.         text_load();
  724.         if (Ep->Line < Ep->Topline) {
  725.             if (Nsu == 0) {
  726.                 ScrollRaster(rp,0,-Ysize,COL(0),ROW(0),Xbase + Xpixs - 1,ROW(Rows)-1);
  727.                 --ep->Topline;
  728.                 text_displayseg(0, 1);
  729.             }
  730.         }
  731.     } else {
  732.         Abortcommand = 1;
  733.     }
  734. }
  735.  
  736. void do_scrolldown(void)
  737. {
  738.     ED *ep = Ep;
  739.     RP *rp = ep->Win->RPort;
  740.  
  741.     if (ep->Topline + Rows < ep->Lines) {
  742.         if (Nsu == 0) {
  743.             text_sync();
  744.             ScrollRaster(rp,0,Ysize,COL(0),ROW(0),Xbase + Xpixs - 1,ROW(Rows)-1);
  745.             ++ep->Topline;
  746.             ++ep->Line;
  747.             text_load();
  748.             text_displayseg(Rows-1, 1);
  749.         }
  750.     } else {
  751.         Abortcommand = 1;
  752.     }
  753. }
  754.  
  755. void do_scrollup(void)
  756. {
  757.     ED *ep = Ep;
  758.     RP *rp = ep->Win->RPort;
  759.  
  760.     if (ep->Topline) {
  761.         if (Nsu == 0) {
  762.             text_sync();
  763.             ScrollRaster(rp,0,-Ysize,COL(0),ROW(0),Xbase + Xpixs - 1,ROW(Rows)-1);
  764.             --ep->Topline;
  765.             --ep->Line;
  766.             text_load();
  767.             text_displayseg(0, 1);
  768.         }
  769.     } else {
  770.         Abortcommand = 1;
  771.     }
  772. }
  773.  
  774. void do_down(void)
  775. {
  776.     ED *ep = Ep;
  777.     RP *rp = ep->Win->RPort;
  778.  
  779.     if (ep->Line + 1 < ep->Lines) {
  780.         text_sync();
  781.         ++ep->Line;
  782.         text_load();
  783.         if (ep->Line - ep->Topline >= Rows) {
  784.             if (Nsu == 0) {
  785.                 ScrollRaster(rp,0,Ysize,COL(0),ROW(0),Xbase + Xpixs - 1,ROW(Rows)-1);
  786.                 ++ep->Topline;
  787.                 text_displayseg(Rows-1, 1);
  788.             }
  789.         }
  790.     } else {
  791.         Abortcommand = 1;
  792.     }
  793. }
  794.  
  795.  
  796. void do_downfast(void)
  797. {
  798.     ED *ep = Ep;
  799.     RP *rp = ep->Win->RPort;
  800.  
  801.     if (ep->Line + 2 < ep->Lines) {
  802.         text_sync();
  803.         ep->Line += 2;
  804.         text_load();
  805.         if (ep->Line - ep->Topline >= Rows) {
  806.             if (Nsu == 0) {
  807.                 ScrollRaster(rp,0,2*Ysize,COL(0),ROW(0),Xbase + Xpixs - 1,ROW(Rows)-1);
  808.                 ep->Topline += 2;
  809.                 text_displayseg(Rows-2, 2);
  810.             }
  811.         }
  812.     } else {
  813.         do_down();
  814.     }
  815. }
  816.  
  817. void do_upfast(void)
  818. {
  819.     ED *ep = Ep;
  820.     RP *rp = ep->Win->RPort;
  821.     int diff;
  822.  
  823.     if (ep->Line > 1) {
  824.         text_sync();
  825.         ep->Line -= 2;
  826.         text_load();
  827.         if ((diff = Ep->Topline - Ep->Line) > 0)
  828.         {
  829.             if (Nsu == 0)
  830.             {
  831.                 ScrollRaster(rp,0,-diff*Ysize,COL(0),ROW(0),Xbase + Xpixs - 1,ROW(Rows)-1);
  832.                 ep->Topline -= diff;
  833.                 text_displayseg(0, diff);
  834.             }
  835.         }
  836.     } else {
  837.         do_up();
  838.     }
  839. }
  840.  
  841. /* Added by Karl Lukas 06/94 */
  842.  
  843. void scroll_jump(int newtop)
  844. {
  845.    ED *ep = Ep;
  846.    RP *rp = ep->Win->RPort;
  847.    int diff = abs(newtop - Ep->Topline);
  848.  
  849.    text_cursor(0);
  850.    if (diff >= Rows)
  851.    {
  852.       text_sync();
  853.       ep->Line += newtop - ep->Topline;
  854.       ep->Topline = newtop;
  855.       text_load();
  856.       if (!text_sync())
  857.          text_redisplay();
  858.    }
  859.    else if((newtop > Ep->Topline) && (Nsu == 0)) /* Scroll up */
  860.    {
  861.       /* Minterm 192: plain vanilla copy */
  862.       ClipBlit(rp, COL(0), ROW(diff), rp, COL(0), ROW(0), Xpixs, (Rows-diff)*Ysize, 192);
  863.       ep->Line += diff;
  864.       ep->Topline = newtop;
  865.       text_load();
  866.       text_displayseg(Rows - diff, diff);
  867.    }
  868.    else if((newtop < Ep->Topline) && (Nsu == 0)) /* Scroll down */
  869.    {
  870.       /* Minterm 192: plain vanilla copy */
  871.       ClipBlit(rp, COL(0), ROW(0), rp, COL(0), ROW(diff), Xpixs, (Rows-diff)*Ysize, 192);
  872.       ep->Line -= diff;
  873.       ep->Topline = newtop;
  874.       text_load();
  875.       text_displayseg(0, diff);
  876.    }
  877.    text_cursor(1);
  878. }
  879.  
  880.  
  881. /*
  882.  *  PAGEUP
  883.  *  PAGEDOWN
  884.  *  PAGESET n   (n = 0 to 100 for percentage of #rows to scroll, minimum 1)
  885.  *              can be > 100.
  886.  */
  887.  
  888. void do_page(void)
  889. {
  890.     int n, multiplier = 1;
  891.     ED *ep = Ep;
  892.  
  893.     switch(av[0][4]) {
  894.     case 'u':
  895.         multiplier = -1;
  896.         if (ep->Topline == 0 && ep->Line == 0)  /* Added by Karl Lukas 06/94 to avoid flicker */
  897.             return;                             /* to avoid flicker */
  898.         if (ep->Topline == 0)
  899.         {
  900.            ep->Line = 0;
  901.            text_load();
  902.            return;
  903.         }                                       /* KL end */
  904.     case 'd':
  905.         n = multiplier * Rows * Pagejump / 100;
  906.         if (!n)
  907.             n = multiplier;
  908.         if (n > 0 && ep->Topline >= ep->Lines - Rows)
  909.         {                                        /* Added by Karl Lukas 06/94      */
  910.            if (ep->Line < (ep->Lines - 1))       /* Now the cursor really jumps to */
  911.            {                                     /* the last line if file end is   */
  912.               ep->Line = ep->Lines - 1;          /* reached                        */
  913.               text_load();
  914.            }                                     /* KL end                         */
  915.            return;
  916.         }
  917.         text_sync();
  918.         ep->Line += n;
  919.         ep->Topline += n;
  920.         if (ep->Line >= ep->Lines)
  921.             ep->Line = ep->Lines - 1;
  922.         if (ep->Line < 0)
  923.             ep->Line = 0;
  924.         if (ep->Topline >= ep->Lines)
  925.             ep->Topline = ep->Lines - Rows - 1;
  926.         if (ep->Topline < 0)
  927.             ep->Topline = 0;
  928.         text_load();
  929.         if (!text_sync())
  930.             text_redisplay();
  931.         break;
  932.     case 's':
  933.         Pagejump = atoi(av[1]);
  934.         break;
  935.     }
  936. }
  937.  
  938. void do_downadd(void)
  939. {
  940.     ED *ep = Ep;
  941.     ubyte *ptr;
  942.  
  943.     if (ep->Line + 1 == ep->Lines) {
  944.         ep->Modified = 1;
  945.         if (makeroom(32) && (ptr = allocb(1))) {
  946.             ep->List[ep->Lines] = ptr;
  947.             *ptr = 0;
  948.             ++ep->Lines;
  949.         } else {
  950.             nomemory();
  951.         }
  952.     }
  953.     do_down();
  954. }
  955.  
  956. void do_left(void)
  957. {
  958.     ED *ep = Ep;
  959.  
  960.     if (ep->Column) {
  961.         --ep->Column;
  962.         if (ep->Column < ep->Topcolumn)
  963.             text_sync();
  964.     } else {
  965.         Abortcommand = 1;
  966.     }
  967. }
  968.  
  969. void do_right(void)
  970. {
  971.     ED *ep = Ep;
  972.  
  973.     if (ep->Column != 254) {
  974.         if (Current[ep->Column] == 0) {
  975.             Current[ep->Column] = ' ';
  976.             Current[ep->Column+1]= '\0';
  977.             ++Clen;
  978.         }
  979.         ++ep->Column;
  980.         if (ep->Column - ep->Topcolumn >= Columns)
  981.             text_sync();
  982.     } else {
  983.         Abortcommand = 1;
  984.     }
  985. }
  986.  
  987. void do_tab(void)
  988. {
  989.     short n;
  990.     ED *ep = Ep;
  991.  
  992.     for (n = ep->Tabstop-(ep->Column % ep->Tabstop); n > 0; --n)
  993.         do_right();
  994. }
  995.  
  996. void do_backtab(void)
  997. {
  998.     short n;
  999.     ED *ep = Ep;
  1000.  
  1001.     n = ep->Column % ep->Tabstop;
  1002.     if (!n)
  1003.         n = ep->Tabstop;
  1004.     for (; n > 0; --n)
  1005.         do_left();
  1006. }
  1007.  
  1008. void do_return(void)
  1009. {
  1010.     ubyte buf[256];
  1011.     char *partial;
  1012.  
  1013.     if (Comlinemode) {
  1014.         strcpy(buf, Current);
  1015.         strcpy(RecallBuf, Current);
  1016.         partial = Partial;
  1017.         Partial = NULL;
  1018.         escapecomlinemode();
  1019.         if (partial) {
  1020.             if (do_command(buf))
  1021.                 do_command(partial);
  1022.             free(partial);
  1023.         } else {
  1024.             do_command(buf);
  1025.         }
  1026.     } else {
  1027.         Ep->Column = 0;
  1028.         text_sync();
  1029.         do_downadd();
  1030.     }
  1031. }
  1032.  
  1033. void do_bs(void)
  1034. {
  1035.     ED *ep = Ep;
  1036.     RP *rp = ep->Win->RPort;
  1037.  
  1038.     if (ep->Column)
  1039.     {
  1040.         if (Blocktype == BLOCK_CHARACTER)
  1041.         {
  1042.            if ((ep->Line == BSline) && (BSchar >= ep->Column))
  1043.               BSchar--;
  1044.            if ((ep->Line == BEline) && (BEchar + 1 >= ep->Column))
  1045.               BEchar--;
  1046.         }
  1047.         movmem(Current + ep->Column, Current + ep->Column - 1, Clen - ep->Column + 1);
  1048.         --ep->Column;
  1049.         --Clen;
  1050.         if (ep->Column < ep->Topcolumn) {
  1051.             text_sync();
  1052.         } else {
  1053.             setpen(ep->Line, ep->Topcolumn + Columns - 1);
  1054.             ScrollRaster(rp, Xsize, 0,
  1055.                 COL(ep->Column - ep->Topcolumn),
  1056.                 ROW(ep->Line   - ep->Topline),
  1057.                 Xbase + Xpixs - 1,
  1058.                 ROW(ep->Line - ep->Topline + 1)-1
  1059.             );
  1060.             if (Clen >= ep->Topcolumn + Columns) {
  1061.                 setpen(ep->Line, ep->Column);
  1062.                 Move(rp, COLT(Columns-1), ROWT(ep->Line - ep->Topline));
  1063.                 Text(rp, Current + ep->Topcolumn + Columns - 1, 1);
  1064.             }
  1065.         }
  1066.         if (Comlinemode == 0 && ep->Wordwrap)
  1067.             do_reformat(0);
  1068.     } else {
  1069.         Abortcommand = 1;
  1070.     }
  1071. }
  1072.  
  1073.  
  1074. /*
  1075.  * esc, escimm
  1076.  */
  1077.  
  1078. int Savetopline, Savecolumn, Savetopcolumn;
  1079.  
  1080. void do_recall(void)
  1081. {
  1082.     av[0] = (ubyte *)"escimm";
  1083.     av[1] = (ubyte *)RecallBuf;
  1084.     do_esc();
  1085. }
  1086.  
  1087. void do_esc(void)
  1088. {
  1089.     ED *ep = Ep;
  1090.     RP *rp = ep->Win->RPort;
  1091.  
  1092.     if (Comlinemode) {
  1093.         escapecomlinemode();
  1094.         return;
  1095.     }
  1096.     text_sync();
  1097.     if (av[0][3] == 'i')
  1098.         strcpy(Current, av[1]);
  1099.     else
  1100.         Current[0] = 0;
  1101.     Clen = strlen(Current);
  1102.     Comlinemode = 1;
  1103.     returnoveride(1);
  1104.     Savetopline = ep->Topline;
  1105.     Savecolumn  = ep->Column;
  1106.     Savetopcolumn = ep->Topcolumn;
  1107.     ep->Column    = Clen;
  1108.     ep->Topcolumn = 0;
  1109.     ep->Topline   = ep->Line - Rows + 1;
  1110.     SetAPen(rp, ep->BGPen);
  1111.     RectFill(rp, COL(0), ROW(Rows-1), Xbase + Xpixs - 1, Ybase + Ypixs - 1);
  1112.     SetAPen(rp, ep->FGPen);
  1113.     Move(rp, COL(0), ROW(Rows-1) - 1);
  1114.     Draw(rp, Xbase + Xpixs - 1, ROW(Rows - 1) - 1);
  1115.     text_displayseg(Rows - 1, 1);
  1116. }
  1117.  
  1118. void escapecomlinemode(void)
  1119. {
  1120.     ED *ep = Ep;
  1121.     RP *rp = ep->Win->RPort;
  1122.  
  1123.     if (Partial) {
  1124.         free(Partial);
  1125.         Partial = NULL;
  1126.     }
  1127.     if (Comlinemode) {
  1128.         strcpy(RecallBuf, Current);
  1129.         Comlinemode = 0;
  1130.         returnoveride(0);
  1131.         ep->Topline = Savetopline;
  1132.         ep->Column  = Savecolumn;
  1133.         ep->Topcolumn = Savetopcolumn;
  1134.         text_load();
  1135.         SetAPen(rp, ep->BGPen);
  1136.         RectFill(rp, COL(0), ROW(Rows-1)-1, Xbase + Xpixs - 1, Ybase + Ypixs - 1);
  1137.         SetAPen(rp, ep->FGPen);
  1138.         text_displayseg(Rows - 2, 2);
  1139.     }
  1140. }
  1141.  
  1142. void do_del(void)
  1143. {
  1144.     ED *ep = Ep;
  1145.     RP *rp = ep->Win->RPort;
  1146.  
  1147.     if (Current[ep->Column])
  1148.     {
  1149.         if (Blocktype == BLOCK_CHARACTER)
  1150.         {
  1151.            if ((ep->Line == BSline) && (BSchar > ep->Column))
  1152.               BSchar--;
  1153.            if ((ep->Line == BEline) && (BEchar >= ep->Column))
  1154.               BEchar--;
  1155.         }
  1156.         movmem(Current + ep->Column + 1, Current + ep->Column, Clen - ep->Column);
  1157.         --Clen;
  1158.         setpen(ep->Line, ep->Topcolumn + Columns - 1);
  1159.         ScrollRaster(rp, Xsize, 0,
  1160.             COL(ep->Column - ep->Topcolumn),
  1161.             ROW(ep->Line - ep->Topline),
  1162.             Xbase + Xpixs - 1,
  1163.             ROW(ep->Line - ep->Topline + 1) - 1
  1164.         );
  1165.         if (Clen >= ep->Topcolumn + Columns) {
  1166.             setpen(ep->Line, ep->Column);
  1167.             Move(rp, COLT(Columns-1), ROWT(ep->Line-ep->Topline));
  1168.             Text(rp, Current+ep->Topcolumn+Columns-1, 1);
  1169.         }
  1170.         if (Comlinemode == 0 && ep->Wordwrap)
  1171.             do_reformat(0);
  1172.     }
  1173. }
  1174.  
  1175. void do_top(void)
  1176. {
  1177.     text_sync();
  1178.     Ep->Line = 0;
  1179.     text_load();
  1180.     text_sync();
  1181. }
  1182.  
  1183. void do_bottom(void)
  1184. {
  1185.     text_sync();
  1186.     Ep->Line = Ep->Lines - 1;
  1187.     text_load();
  1188.     text_sync();
  1189. }
  1190.  
  1191. void do_firstcolumn(void)
  1192. {
  1193.     if (Ep->Column) {
  1194.         Ep->Column = 0;
  1195.         text_sync();
  1196.     }
  1197. }
  1198.  
  1199. void do_firstnb(void)
  1200. {
  1201.     for (Ep->Column = 0; Current[Ep->Column] == ' '; ++Ep->Column);
  1202.     if (Current[Ep->Column] == 0)
  1203.         Ep->Column = 0;
  1204.     text_sync();
  1205. }
  1206.  
  1207. void do_lastcolumn(void)
  1208. {
  1209.     short i;
  1210.  
  1211.     text_sync();
  1212.     i = (Comlinemode) ? Clen : strlen(Ep->List[Ep->Line]);
  1213.     if (i != Ep->Column) {
  1214.         Ep->Column = i;
  1215.         text_sync();
  1216.     }
  1217. }
  1218.  
  1219. /*
  1220.  * GOTO [+/-]N
  1221.  * GOTO BLOCK   start of block
  1222.  * GOTO START   start of block
  1223.  * GOTO END     end of block
  1224.  */
  1225.  
  1226. void do_goto(void)
  1227. {
  1228.     long n, i, col = -1;
  1229.     ubyte *ptr = av[1];
  1230.  
  1231.     i = 0;
  1232.     n = -1;
  1233.  
  1234.     switch(*ptr) {
  1235.     case 'b':
  1236.     case 's':
  1237.     case 'B':
  1238.     case 'S':
  1239.         n = -1;
  1240.         if (Ep == BEp)
  1241.         {
  1242.             n = BSline;
  1243.             col = BSchar;
  1244.         }
  1245.         break;
  1246.     case 'e':
  1247.     case 'E':
  1248.         n = -1;
  1249.         if (Ep == BEp)
  1250.         {
  1251.             n = BEline;
  1252.             col = BEchar;
  1253.         }
  1254.         break;
  1255.     case '+':
  1256.         i = 1;
  1257.     case '-':
  1258.         n = Ep->Line;
  1259.     default:
  1260.         n += atoi(ptr+i);
  1261.     }
  1262.     if (n >= Ep->Lines)
  1263.         n = Ep->Lines - 1;
  1264.     if (n < 0)
  1265.         n = 0;
  1266.     text_sync();
  1267.     Ep->Line = n;
  1268.     if ((Blocktype == BLOCK_CHARACTER) && (col >= 0))
  1269.        Ep->Column = col;
  1270.     else
  1271.        Ep->Column = 0;
  1272.     text_load();
  1273.     text_sync();
  1274. }
  1275.  
  1276. void do_screentop(void)
  1277. {
  1278.     text_sync();
  1279.     Ep->Line = Ep->Topline;
  1280.     text_load();
  1281.     text_sync();
  1282. }
  1283.  
  1284. void do_screenbottom(void)
  1285. {
  1286.     text_sync();
  1287.     Ep->Line = Ep->Topline + Rows - 1;
  1288.     if (Ep->Line < 0 || Ep->Line >= Ep->Lines)
  1289.         Ep->Line = Ep->Lines - 1;
  1290.     text_load();
  1291.     text_sync();
  1292. }
  1293.  
  1294. static ubyte Fstr[256];
  1295. static ubyte Rstr[256];
  1296. static short Srch_sign;
  1297. static char Doreplace;
  1298.  
  1299. /*
  1300.  * findstr, repstr
  1301.  */
  1302.  
  1303. void do_findstr(void)
  1304. {
  1305.     if (av[0][0] == 'f')
  1306.         strcpy(Fstr, av[1]);
  1307.     else
  1308.         strcpy(Rstr, av[1]);
  1309. }
  1310.  
  1311. /*
  1312.  * findr, nextr, prevr
  1313.  */
  1314.  
  1315. void do_findr(void)
  1316. {
  1317.     Doreplace = 1;
  1318.     Srch_sign = 1;
  1319.     switch(av[0][0]) {
  1320.     case 'f':
  1321.         strcpy(Fstr, av[1]);
  1322.         strcpy(Rstr, av[2]);
  1323.         break;
  1324.     case 'p':
  1325.         Srch_sign = -1;
  1326.         break;
  1327.     }
  1328.     search_operation();
  1329. }
  1330.  
  1331. /*
  1332.  * find, next, prev
  1333.  */
  1334.  
  1335. void do_find(void)
  1336. {
  1337.     Doreplace = 0;
  1338.     Srch_sign = 1;
  1339.     switch(av[0][0]) {
  1340.     case 'f':
  1341.         strcpy(Fstr, av[1]);
  1342.         break;
  1343.     case 'p':
  1344.         Srch_sign = -1;
  1345.         break;
  1346.     }
  1347.     search_operation();
  1348. }
  1349.  
  1350. void do_reqreplace(void)
  1351. {
  1352.    int len, i = 0, replace = 0;
  1353.  
  1354.    SearchPattern[0] = 0;
  1355.    ReplacePattern[0] = 0;
  1356.  
  1357.    len = GetClipText(SearchPattern, 255, 1);
  1358.  
  1359.    /* Read only to first linefeed, forget the rest */
  1360.    while ((i < len) && (SearchPattern[i] != '\n'))
  1361.       i++;
  1362.    if (SearchPattern[i] == '\n')
  1363.       SearchPattern[i] = 0;
  1364.  
  1365.    len = GetClipText(ReplacePattern, 255, 2);
  1366.  
  1367.    /* Read only to first linefeed, forget the rest */
  1368.    while ((i < len) && (ReplacePattern[i] != '\n'))
  1369.       i++;
  1370.    if (ReplacePattern[i] == '\n')
  1371.       ReplacePattern[i] = 0;
  1372.  
  1373.    if (! OpenReplaceWindow(Ep->Win->WScreen))
  1374.    {
  1375.       if (HandleReplaceIDCMP())
  1376.       {
  1377.          replace = 1;
  1378.       }
  1379.       else
  1380.          title("Operation cancelled");
  1381.       CloseReplaceWindow();
  1382.    }
  1383.    else
  1384.       title("Unable to open requester");
  1385.  
  1386.    if (replace)
  1387.    {
  1388.       PutClipText(SearchPattern, 1);
  1389.       PutClipText(ReplacePattern, 2);
  1390.  
  1391.       Doreplace = 1;
  1392.       Srch_sign = 1;
  1393.       ConfirmReplace = 1;
  1394.       strcpy(Fstr, SearchPattern);
  1395.       strcpy(Rstr, ReplacePattern);
  1396.  
  1397.       while (! Abortcommand)
  1398.          search_operation();
  1399.       ConfirmReplace = 0;
  1400.    }
  1401. }
  1402.  
  1403.  
  1404. void do_reqfind(void)
  1405. {
  1406.    char buf[256];
  1407.    int len, i = 0;
  1408.  
  1409.    if (ReqToolsBase)
  1410.    {
  1411.       struct TagItem taglist[] =
  1412.       {
  1413.          RT_Window, (ULONG)Ep->Win,
  1414.          TAG_DONE, 0L
  1415.       };
  1416.       buf[0] = 0;
  1417.  
  1418.       len = GetClipText(buf, 255, 1);
  1419.  
  1420.       while ((i < len) && (buf[i] != '\n')) /* Read only to first linefeed, forget the rest */
  1421.          i++;
  1422.       if (buf[i] == '\n')
  1423.          buf[i] = 0;
  1424.  
  1425.       if (rtGetStringA(buf, 255, "Enter search string", NULL, taglist))
  1426.       {
  1427.          PutClipText(buf, 1);
  1428.          av[0] = "f";
  1429.          av[1] = buf;
  1430.          do_find();
  1431.       }
  1432.    }
  1433.    else
  1434.       title("You need reqtools.library for this");
  1435. }
  1436.  
  1437. int GetClipText(char * buf, int buflen, int unit)
  1438. {
  1439.    struct IOClipReq *ior;
  1440.    struct cbbuf *clipbuf;
  1441.    int len = 0;
  1442.  
  1443.    if (ior = CBOpen(unit))
  1444.    {
  1445.       if (CBQueryFTXT(ior))
  1446.       {
  1447.          if (clipbuf = CBReadCHRS(ior))
  1448.          {
  1449.             len = clipbuf->count > buflen ? buflen : clipbuf->count;
  1450.             strncpy(buf, clipbuf->mem, len);
  1451.             buf[len] = 0;
  1452.             CBFreeBuf(clipbuf);
  1453.          }
  1454.          CBReadDone(ior);
  1455.       }
  1456.       CBClose(ior);
  1457.    }
  1458.    return len;
  1459. }
  1460.  
  1461. int PutClipText(char *buf, int unit)
  1462. {
  1463.    struct IOClipReq *ior;
  1464.    int ret = 0;
  1465.  
  1466.    if (ior = CBOpen(unit))
  1467.    {
  1468.       if (CBWriteFTXT(ior, buf))
  1469.          ret = 1;
  1470.       CBClose(ior);
  1471.    }
  1472.    return ret;
  1473. }
  1474.  
  1475.  
  1476. static char CaseIgnore;
  1477.  
  1478. void search_operation(void)
  1479. {
  1480.     int flen = strlen(Fstr);
  1481.     int rlen = strlen(Rstr);
  1482.     char senabled = 0;
  1483.     ubyte *ptr;
  1484.     int i, col;
  1485.     ED *ep = Ep;
  1486.  
  1487.     CaseIgnore = ep->IgnoreCase;
  1488.     text_sync();
  1489.     if (!flen) {
  1490.         title("No find pattern");
  1491.         Abortcommand = 1;
  1492.         return;
  1493.     }
  1494.  
  1495.     title("Searching..."); /* Added 1.sep.94 by KL */
  1496.  
  1497.     col = ep->Column;
  1498.     if (col >= strlen(ep->List[ep->Line]))
  1499.         col = strlen(ep->List[ep->Line]);
  1500.     for (i = ep->Line;;) {
  1501.         ptr = ep->List[i];
  1502.         if (Srch_sign > 0) {
  1503.             while (ptr[col]) {
  1504.                 if (senabled && case_strncmp(Fstr,ptr+col,flen) == 0)
  1505.                     goto found;
  1506.                 senabled = 1;
  1507.                 ++col;
  1508.             }
  1509.             senabled = 1;
  1510.             if (++i >= ep->Lines)
  1511.                 break;
  1512.             col = 0;
  1513.         } else {
  1514.             while (col >= 0) {
  1515.                 if (senabled && case_strncmp(Fstr,ptr+col,flen) == 0)
  1516.                     goto found;
  1517.                 senabled = 1;
  1518.                 --col;
  1519.             }
  1520.             senabled = 1;
  1521.             if (--i < 0)
  1522.                 break;
  1523.             col = strlen(ep->List[i]);
  1524.         }
  1525.     }
  1526.     title("Pattern Not Found");
  1527.     Abortcommand = 1;
  1528.     return;
  1529.  
  1530. found:
  1531.     if (! Doreplace)
  1532.        title("Found pattern"); /* Added 1.sep.94 by KL */
  1533.     ep->Line = i;
  1534.     ep->Column = col;
  1535.  
  1536.     text_load();
  1537.     text_sync();
  1538.     text_cursor(1);
  1539.     if (Doreplace && confirm_replace()) {
  1540.         if (rlen > flen && rlen-flen+strlen(ptr) > 254) {
  1541.             title("Replace: Line Too Long");
  1542.             Abortcommand = 1;
  1543.             return;
  1544.         }
  1545.         if (Clen-col-flen >= 0) {
  1546.             movmem(Current+col+flen, Current+col+rlen, Clen-col-flen+1);
  1547.             movmem(Rstr, Current+col, rlen);
  1548.             Clen += rlen-flen;
  1549.             ep->Column += rlen;
  1550.         }
  1551.         text_sync();
  1552.         text_redisplaycurrline();
  1553.     }
  1554.     text_cursor(0);
  1555. }
  1556.  
  1557. int confirm_replace(void)
  1558. {
  1559.    int ret;
  1560.    int done = 0;
  1561.    struct IntuiMessage *message;
  1562.    char buf[256];
  1563.  
  1564.    if (! ConfirmReplace)
  1565.       return 1;
  1566.  
  1567.    title("Replace? (Y)es (N)o (A)ll (Q)uit");
  1568.  
  1569.    while (! done)
  1570.    {
  1571.       Wait(1 << Ep->Win->UserPort->mp_SigBit);
  1572.  
  1573.       while (message = (struct IntuiMessage *)GetMsg(Ep->Win->UserPort))
  1574.       {
  1575.          switch (message->Class)
  1576.          {
  1577.             case RAWKEY:
  1578.                buf[0] = 0;
  1579.                DeadKeyConvert(message, buf, 255, NULL);
  1580.                switch(buf[0])
  1581.                {
  1582.                   case 'A':
  1583.                   case 'a':
  1584.                     ConfirmReplace = 0;
  1585.                   case 'Y':
  1586.                   case 'y':
  1587.                      ret = done = 1;
  1588.                      break;
  1589.                   case 'N':
  1590.                   case 'n':
  1591.                      ret = 0;
  1592.                      done = 1;
  1593.                      break;
  1594.                   case 'Q':
  1595.                   case 'q':
  1596.                      ret = 0;
  1597.                      done = 1;
  1598.                      Abortcommand = 1;
  1599.                      title("Aborted");
  1600.                      break;
  1601.                   default:
  1602.                      break;
  1603.                }
  1604.                break;
  1605.             case NEWSIZE:
  1606.                ret = 0;
  1607.                Abortcommand = 1;
  1608.                done = 1;
  1609.                set_window_params();
  1610.                if (!text_sync())
  1611.                   text_redisplay();
  1612.                title("Aborted");
  1613.                break;
  1614.             case INTUITICKS:
  1615.                break;
  1616.             default:
  1617.                break;
  1618.          }
  1619.          ReplyMsg((struct Message *)message);
  1620.       }
  1621.    }
  1622.    return ret;
  1623. }
  1624.  
  1625.  
  1626. int case_strncmp(char *s1, char *s2, int len)
  1627. {
  1628.     if (CaseIgnore == 0)
  1629.         return(strncmp(s1, s2, len));
  1630.     for (; len; --len, ++s1, ++s2) {
  1631.         if ((*s1|0x20) != (*s2|0x20))
  1632.             return(1);
  1633.         if ((!isalpha(*s1) || !isalpha(*s2)) && *s1 != *s2)
  1634.             return(1);
  1635.     }
  1636.     return(0);
  1637. }
  1638.  
  1639.  
  1640.  
  1641.  
  1642. static ubyte brackets[][2] = {
  1643.     '(',    ')',
  1644.     '{',    '}',
  1645.     '[',    ']',
  1646.     '<',    '>',
  1647.     '`',    '\'',
  1648.     0
  1649. };
  1650.  
  1651. void
  1652. do_findmatch()
  1653. {
  1654.     ubyte c, c2;
  1655.     ubyte *lineptr;
  1656.     short direction = 0, i;
  1657.     long cnt = 0;
  1658.     long line, column;
  1659.     long endline, endcol, col, len;
  1660.  
  1661.     line = Ep->Line;
  1662.     column = Ep->Column;
  1663.     c = Current[column];
  1664.  
  1665.     for (i = 0; brackets[i][0]; i++) {
  1666.         if (brackets[i][0] == c) {      /* forward  */
  1667.             c2 = brackets[i][1];
  1668.             direction = 1;
  1669.             endline = Ep->Lines - 1;
  1670.             break;
  1671.         }
  1672.         if (brackets[i][1] == c) {      /* backward */
  1673.             c2 = brackets[i][0];
  1674.             direction = -1;
  1675.             endline = 0;
  1676.             break;
  1677.         }
  1678.     }
  1679.  
  1680.     if (direction == 0) {
  1681.         title("not matchable character");
  1682.         return;
  1683.     }
  1684.  
  1685.     for ( ; line != endline + direction; line += direction) {
  1686.  
  1687.         if (cnt == 0) {
  1688.             lineptr = Current;      /* current line (we're just starting) */
  1689.             len = Clen;
  1690.             col = column;
  1691.         } else {
  1692.             lineptr = Ep->List[line];
  1693.             len = strlen(lineptr);
  1694.             col = (direction == 1) ? 0 : len - 1;
  1695.         }
  1696.         endcol = (direction == 1) ? len - 1 : 0;
  1697.  
  1698.         for ( ; col != endcol + direction; col += direction) {
  1699.             if (lineptr[col] == c)
  1700.                 cnt++;
  1701.             else if (lineptr[col] == c2) {
  1702.                 cnt--;
  1703.                 if (cnt == 0) {     /* found match!!          */
  1704.                     text_sync();    /* ok, now update buffers */
  1705.                     Ep->Line = line;
  1706.                     Ep->Column = col;
  1707.                     text_load();    /* and move to new place  */
  1708.                     text_sync();
  1709.                     return;
  1710.                 }
  1711.             }
  1712.         }
  1713.     }
  1714.     title("match not found");
  1715. }
  1716.  
  1717. /*
  1718.  *  Change to window by filepath, open new window and load new file
  1719.  *  if window cannot be found.
  1720.  */
  1721.  
  1722. void
  1723. do_window()
  1724. {
  1725.     ED *ed;
  1726.     char buf[128];
  1727.  
  1728.     if ((ed = finded(av[1], 0)) == NULL) {
  1729.         sprintf(buf, "newwindow newfile (%s)", av[1]);
  1730.         do_command(buf);
  1731.         ed = finded(av[1], 0);
  1732.     } else {
  1733.         WindowToFront(ed->Win);
  1734.         ActivateWindow(ed->Win);
  1735.     }
  1736.     if (ed == NULL) {
  1737.         title("unable to load file");
  1738.     } else {
  1739.         text_switch(ed->Win);
  1740.         if (Ep->iconmode)
  1741.             uniconify();
  1742.         else
  1743.             text_cursor(0);
  1744.     }
  1745. }
  1746.  
  1747.